2

I am a little confused about the process involved in the validation of receipts from users who have subscribed to my app.

At the minute a user joins and then purchases the subscription, the receipt is then base64 encoded and sent to my server. At midnight each night the server sends off the receipt stored in my db to Apple to be validated and the expiry date updated.

Now i'm a bit confused about how a receipt is updated each month. Please take a look at the following flow and let me know if this is correct.

  1. The user registers and subscribes to my app.( Lets say January).
  2. The original receipt is sent to my server and then validated with Apple, the expiry date is returned and set on my server.
  3. A month later in February on the expiry date I send the original (January) receipt to Apple again to see if the subscription has been renewed and then I can set the new expiry date.

Is this flow correct? Because I am sending the original (January) receipt each month will it still contain the latest renewal information or do I somehow have to refresh the receipt each month when the user logs in or opens the app?

jscs
  • 63,694
  • 13
  • 151
  • 195
ORStudios
  • 3,157
  • 9
  • 41
  • 69

1 Answers1

3

Yes, your understanding is more or less correct. When a user's first renewal occurs a couple of things will happen:

  1. The next time the user launches the app, your SKPaymentQueue delegate will receive a new SKPaymentTransaction for the new transaction. You need to be ready to observe this transaction with your delegate and finish it. If you don't, transactions will just continue to pile up over the months.

  2. The verifyReceipt response received from Apple for the first receipt will update the latest_receipt_info key to include the most update version of the receipt data. latest_receipt_info will originally just be a copy of the receipt.in_app field, but after the first renewal it will contain the most up to date transactions. You should use these latest_receipt_info transactions to update the expiration date.

My suggested behavior is that when you receive the new SKPaymentTransaction you send it to your server anyway (although you technically don't need to) and you use it to verify and update the expiration date before finishing the transaction. You can overwrite the old receipt with the new one.

You can have a look at the RevenueCat iOS framework source code to see how I handle it. (You should also make sure you trigger a fetch receipt request if the receipt data is missing, which I do in the code.)

If you are interested in an out of the box solution, RevenueCat is a service I started to handle all these and many more edge cases automatically.

Jacob Eiting
  • 1,004
  • 6
  • 9
  • Thanks for the response, I am currently developing using the latest_receipt_info field. To be honest it was this that was confusing me because I've read that you need to send the latest receipt which will have the new renewal info on it. From what I can gather you are saying I don't technically need to do this because Apple can use the original/first receipt for all future renewals? – ORStudios Nov 10 '17 at 17:59
  • Yes, technically you don't need to keep sending the updated receipt. In order to support one iTunes account being used by different app users, I allow receipts to be transferred, so I send them on every transaction. But if you don't support this you don't need to, no. – Jacob Eiting Nov 10 '17 at 18:07
  • Just had an additional thought, is the same true if the user cancels a subscription and the re-subscribes or would that be a completely new receipt with purchase history? – ORStudios Nov 10 '17 at 23:06
  • If it is the same iTunes account when the user re-subscribes, it will be accessible with the original receipt, there will just be a gap in the transactions. However, the transactions will no long be linked by `original_transaction_id`. – Jacob Eiting Nov 11 '17 at 01:43