1

Schema

Could anybody help me to understand the following schema? I have an iOS app and an app server. A connection between app and server (1A, 1B) is already working.

Let's say a user of the app has 10 gems, which controlled by the server due to security reasons. I have a consumable IAP type in the AppStore: 100 gems pack and the user wants to buy it. Of course, I want to make a record in my Mongo database to increase the number of gems for the user.

How does this flow work? Should I use StoreKit in the app first and then communicate to the server? Or can make an endpoint on the server like "/buyPack/100gems" and do everything on the server side? As far as I understand I need to validate a receipt from the AppStore, but where to get it and what does it contain?

If you could use my arrows (1A, 2A, 3B and so on) I will really appreciate this.

Evgeny
  • 631
  • 6
  • 17

1 Answers1

3

The purchase must happen on the iOS device using StoreKit.

When you get a transaction with a .purchased state you should retrieve the receipt and send it to your server for validation. Once you your server has validated the receipt with Apple and updated the user's balance in MongoDB it should return a success status to the app. At that point the app should complete the transaction with StoreKit.

Be aware that it is conceivable that the app is terminated by the user or loses network connectivity after you have updated your database but before it received the response and completed the transaction. In this case the app will receive the transaction again when it is next launched. Your server should be prepared for this by checking the transaction identifier. If you have previously processed the transaction, return success to your app so that it can complete the transaction but don't increase the user's balance again.

See this answer for some more advice on receipt validation.

The flow is something like:

  • 3B - purchase is made with StoreKit
  • 3A - updated transaction is delivered to App once payment is confirmed
  • 1A - App sends receipt and transaction details to your server
  • 2A - Your server validates the receipt with Apple
  • 2B - Your server updates the user's balance based on the validated receipt
  • 1B - Your server returns a success status to the app
  • 3B - Your app completes the transaction with StoreKit
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • I implemented almost everything, and happy scenario works as should. Just one scenario I don't know how to solve: – Evgeny Aug 15 '18 at 19:53
  • 1. I start a purchase with StoreKit 2. Put my server offline 3. Next time I start the app (or become online) I see some purchased but not finished transactions 4. I mark finish them without updating a server. Should I send a receipt from MainBundle to my server again and finish them after the successful response? – Evgeny Aug 15 '18 at 19:59
  • Yes, you should always follow the same flow. If you cannot contact your server then do not complete the transaction. You should probably provide some feedback to the user that the purchase is still in progress – Paulw11 Aug 15 '18 at 20:41
  • I'm still missing one thing. Example: I open the app and see 4 transactions in a queue: 1 is failed (which I finish immediately, there is no problem) and 3 are purchased. I iterate over the 3 purchased transactions and try to send info about it to my server and finish after success response. But I need to send receipt also, I take this from MainBundle.AppStoreReceiptUrl and attach to each call. In this case, AppStore says I some products are not valid in the receipt. Am I doing something wrong? – Evgeny Aug 16 '18 at 05:52
  • I solved the problem. I just send a receipt and extract transaction and product ids from it. It's more secure and correct. – Evgeny Aug 17 '18 at 06:16