[Solved] Unity IAP not validating multiple transactions if passed in a receipt (iOS)

If for whatever reason a purchase doesn’t complete, and the user makes another, in the iOS receipt, you’ll have multiple transactions in the inApp field. Something like this:

{
environment: Sandbox,
receipt: {

in_app: {
{
is_trial_period: false,
original_purchase_date: 2016-05-1814: 19: 12Etc/GMT,
original_purchase_date_ms: 1463581152000,
original_purchase_date_pst: 2016-05-1807: 19: 12America/Los_Angeles,
original_transaction_id: 1000000212147818,
product_id: product_1,
purchase_date: 2016-05-1814: 19: 12Etc/GMT,
purchase_date_ms: 1463581152000,
purchase_date_pst: 2016-05-1807: 19: 12America/Los_Angeles,
quantity: 1,
transaction_id: 1000000212147818
},
{
is_trial_period: false,
original_purchase_date: 2016-05-1814: 17: 38Etc/GMT,
original_purchase_date_ms: 1463581058000,
original_purchase_date_pst: 2016-05-1807: 17: 38America/Los_Angeles,
original_transaction_id: 1000000212147465,
product_id: product_2,
purchase_date: 2016-05-1814: 17: 38Etc/GMT,
purchase_date_ms: 1463581058000,
purchase_date_pst: 2016-05-1807: 17: 38America/Los_Angeles,
quantity: 1,
transaction_id: 1000000212147465
}
},

},
status: 0
}

where “product_1” is the purchase that’s currently going on, and “product_2” is the purchase that hasn’t been validated.

Now, I can validate and give both on the server, however, when I get the return, and call Complete on the purchase, only “product_1” is cleared. Even explicitly calling RefreshAppReceipt won’t clear “product_2” even though technically it’s been treated.

I can’t call Complete on that one, as the ConfirmPendingPurchase() method only takes a Product, not a transactionID, and the Product in question won’t have that data.

If I call ConfirmPendingPurchase() on “product_2”, I get an error, as it doesn’t have the transactionID/receipt set on it.

I can’t set that data on it (transactionID and receipt) as the fields are internal/private.

I can’t create a new Product with the right data for the same reason.

So every purchase after this will include the transaction for “product_2” even though it’s been treated (I can check for this on the server however).

How can I clear this product specifically? UnityIAP’s not notifying me of it (see [Solved] Unity IAPs ProcessPurchase not calling after purchase, only after app restart - Unity Services - Unity Discussions and [Closed] RestorePurchase on iOS not return ProcessPurchase callback - Unity Services - Unity Discussions)

Thanks

I believe this is answered here which links to apple’s documentation.

Hi Banderous,

Thanks for the response, but this isn’t a case where a successfully treated product stays in the receipt until a new purchase/refresh, but rather one that that hasn’t been marked as complete, and is so sent along with other transactions in the receipt.

E.g. in the case of iOS where I make a purchase (P1), and before it’s verified by the server, I kill the game for whatever reason. On relaunch, I’m not notified of the pending purchase, so when I make another one (P2), the transaction is sent along (so I have 2 transactions in the receipt). When calling ConfirmPendingPurchase() on P2, only P2 is cleared from the receipt, as P1 hasn’t been marked as Complete behind the scenes (I guess, in UnityIAP?). So P1 stays in the receipt, even after a refresh. Both purchases are consumables.

Thanks

Hey Nicolas,

Have you ever found a solution to this issue? I can seem to find an anwser anywere

Thanks Niels

Hi @ -Paladin,

We handled it on the server side. Basically we take all the products in the receipt and return and array of “validated” products, then give that.

It eventually seems to trigger a purchase callback on its own though. For example, I have one player that made a purchase that was validated, but for what ever reason ConfirmPendingPurchase() was never called on it.

2 days later, I have 3 other purchase calls for them.

In the first two, the already verified but not completed purchase is sent along (so there’s two iaps in the receipt). As it’s already been given on the server, nothing happens (we verify and give the other iap, so for the user, nothing is out of norm).

Then, around 12 hours later, the third purchase call happens, this time with only one iap in the receipt - the already verified one. Then, on the client, this allows us to call ConfirmPendingPurchase().

It can happen, but it’s not super common for us (an average of 1 or 2 “already verified” calls a day)