1
votes

I would like to implement In-App purchase of consumable products for an iOS app I'm developing. I want to validate the receipt on the server side as indicated in the documentation:

  1. App start transaction asking to the Apple Store
  2. Apple Store return receipt to the app
  3. The app send the receipt to a trusted server
  4. Trusted server sends receipt (in base 64 format) to the Apple Store through an HTTP POST
  5. Apple Store replies to the HTTP POST with the validation
  6. If the validation response is ok, the purchase can be enabled

I'm concerning about the following situation: a user buys a product and the Apple Store sends back the receipt to the App (steps 1,2). Then, when the app tries to send the receipt to the trusted server (step 3) the connection goes down. In this case receipt validation has to be retried in a second moment, however, I have the following questions:

a) in this case, has the user already paid for the product?
b) Since receipts for consumable products compare only at the time of the purchase, how should the validation retry be managed? Should I save the receipt locally in order to retransmit it in the future? Can I simply does not mark the transaction as "finished"? From what I understand reading the documentation, in this case StoreKit should call the transaction queue observer again (passing again the receipt?) until the transaction is marked as "finished", is it correct?

Thank you in advance

1

1 Answers

3
votes

a) in this case, has the user already paid for the product?

The PaymentTransaction observer will tell you what state the user's purchase is .Purchased, .Purchasing, .Failed . e.t.c.

So we can assume from your question that the user's state is .Purchased and You would have received a payment. Now since they have a receipt and it’s hopefully from a real purchase they will be waiting for you to validate on your server and unlock the purchase because they have received a receipt containing data about their purchase.

b) Since receipts for consumable products compare only at the time of the purchase, how should the validation retry be managed? Should I save the receipt locally in order to retransmit it in the future? Can I simply does not mark the transaction as "finished"? From what I understand reading the documentation, in this case StoreKit should call the transaction queue observer again (passing again the receipt?) until the transaction is marked as "finished", is it correct?

You don’t need to store it locally, with the information stored about the purchase in the receipt. This is kept until your paymentObserver finishes the transaction or the receipt is refreshed/ updated again. Your app will keep trying to validate with your server until it receives a response about the receipt usually when the user launches the app again, At that point if we assume it's valid, you enable your product and then after this finish the transaction on the SKPaymentQueue.

In the documentation it says’s

“The in-app purchase receipt for a consumable product is added to the receipt when the purchase is made. It is kept in the receipt until your app finishes that transaction. After that point, it is removed from the receipt the next time the receipt is updated “

https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW1

Also: “For example, consider the case of a user buying something in your app right before going into a tunnel. Your app isn’t able to deliver the purchased content because there’s no network connection. The next time your app is launched, StoreKit calls your transaction queue observer again and delivers the purchased content at that time. Similarly, if your app fails to mark a transaction as finished, StoreKit calls the observer every time your app is launched until the transaction is properly finished.”

I hope this helps and I hope it answered your questions.