In-app purchase receipt data invalid after interrupting purchase

I have a case where I am getting an invalid transaction receipt from the app store while doing purchases in sandbox. I'm doing server-side receipt validation.


Steps:

1. Go to make a purchase.

2. Get the Apple "Cancel" or "Buy" confirmation dialog; click "Buy".

3. Get the Apple "Thank You" OK dialog; do NOT click OK.

4. Sometimes the "purchased" transaction update message has arrived from the app store at this point, but sometimes it hasn't and the transaction is still in a pending state until the OK dialog is dismissed, but problems can occur if it is not dismissed.

5. While the Thank You dialog is still showing, minimize the app, turn off wifi, and return to the app.

6. The "Thank You" dialog has disappeared. If the transaction was in the pending state in step 4, I now get into the purchased state, but the transaction I get has a receipt that looks as if it has garbage data in it, and when the wifi is turned back on, and the receipt is sent to my server for validation, Apple rejects the receipt as having invalid data.

7. If the transaction was in the purchased state in step 4, the receipt is valid and everything works fine. But repeating the above steps will eventually reproduce the issue.

Once I get a bad receipt, if I leave the transaction open and restart the app, the purchase goes through again, this time with a valid receipt.

For clarity in your edge case:

1) In step 6 - When you write "Apple rejects the receipt as having invalid data" does that mean the receipt is invalid with a 21002 error or is the receipt valid but it does not indicate the IAP has been purchased?

2) At the bottome - When you write "if I leave the transaction open" does that mean "if I don't call finishTransaction on this transaction"?

3) In step 6 - Where you write "I now get into the purchased state" - do you mean "I get a call to updatedTransactions and the state is 'purchased' "


Have you tried the following:

1) refresh the receipt in the immediate call to updatedTransactions that occurs in step 6. Does that get you a better receipt? Not useful but reassuring.

2) (my favorite solution to this edge case) in step 5 remove the transaction observer when the app closes. - although Apple says it is not best practice, I always remove the transaction observer when done with it. Then allow the user to select an option like 'look for approved purchases' - if they select that, call addTransactionObserver and give StoreKit about 5 seconds to respond before telling the user that there are no transactions and removing the transaction observer. I think this procedure will handle your edge case (even though it is not Apple's choice for best practice - it may be 'better than best practice') as it will cause StoreKit to resend the waiting transaction with an 'unbroken' receipt rather than presenting the one stuck in your edge-case queue. The problem is that your transaction observer will accept the transaction with the bad receipt and when you finishTransaction you are lost, especially with a consumable.

In-app purchase receipt data invalid after interrupting purchase
 
 
Q