Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices in Server side validation of In app purchase in iOS

We are using server side validation of the payment like so -

  1. User makes payment.
  2. Store kit API sends transaction receipt to App.
  3. App sends base64 encoded transaction receipt to our server.
  4. Our server calls https://buy.itunes.apple.com/verifyReceipt and validates the transaction recept.
  5. User is marked as paid.

For a particular user, we didn't get the transaction receipt at the server, due to which the receipt couldn't be verified. We are guessing something went wrong in steps 2 and 3. If there were connection problems at the time of sending receipt to server, the app retries again on subsequent app resume.

Now we have one missing transaction receipt and an angry user. How do you suggest we go forward? How can we prevent this in future? Are there any guidelines or best practices that we can follow to prevent such situation?

Thank you.

like image 880
8suhas Avatar asked Feb 11 '13 08:02

8suhas


People also ask

How do I validate purchases on my server?

To validate purchases, you need to verify receipts on your server or the device. If you work with auto-renewable subscriptions, the App Store can also notify your server of key subscription events. To retrieve the receipt data ( appStoreReceiptURL) from the app on the device, use the appStoreReceiptURL = Bundle.main.appStoreReceiptURL

What is receipt validation ( verifyreceipt)?

To provide access to your content, you need to pass a receipt through the receipt validation ( verifyReceipt) endpoint. Receipt is an encrypted file signed with an Apple certificate. To validate purchases, you need to verify receipts on your server or the device.

What should I know about in-app purchases and storekit?

You should be familiar with in-App Purchases and StoreKit. Get access to the iOS Developer Center and App Store Connect. Consumable – are used once and are depleted. For example, coins. Non-Consumable – are used once, but do not expire. For example, a movie in a video app. Auto-Renewable Subscriptions – access to services with periodic payment.


1 Answers

Based on my experience, the likely issues are

  • The base64 data got url-encoded along the way and so + and / got messed up - replace these with safer characters before transfer
  • The whole transaction is bogus.

The way to check for the second case is to look at your account and see if there is a matching purchase record. Unfortunately, the web site can be a bit difficult to review unless you have a low purchase volume.

The are two things you need in your code to correctly handle errors on your server or on, if it happens, Apple's end.

  1. Do not call finishTransaction: until you have successfully communicated with your server (it wouldn't help in this case but worth noting)
  2. Have a "Reload Purchases" button or action that calls restoreCompletedTransactions: on the SKPaymentQueue defaultQueue. For non-consumable/entitlement objects, this will resend all transactions with receipts that can be re-verified on your server.

If the problem you are facing is with non-consumables/entitlements, then the second item is the way out.

like image 171
DrC Avatar answered Sep 23 '22 08:09

DrC