Understanding receipt validation and receipt refreshing in iOS
Asked Answered
P

4

19

We have issues fully understanding the receipt validation flow in iOS.

Here is what we currently do (in development):

In applicationDidFinishLaunching and in applicationWillEnterForeground we validate the receipt on the server side, if there is no receipt or the receipt is invalid, we try to refresh the receipt and revalidate it.

Here are some issues/questions:

  1. What are the cases where there is no receipt available on the device ?

  2. Should we always issue a receipt refresh request when there is no receipt ?

  3. Why is this alert box sometimes shown on startup ? I understand this is shown on a receipt refresh request ?

Sign in required?

  1. When should a receipt verification happen ? We currently do it whenever a purchase is made to verify the purchase, is this correct usage ?
Parthia answered 3/12, 2015 at 19:38 Comment(0)
S
13
  1. In production a receipt is always available on device. In test after the first install there is not. So if you want to do a correct test, you must restore a purchase even if it doesn't exist a purchase on that user in the test environment. Why is that? App downloaded from the appstore always comes with a receipt even if they are free.
  2. Depends on the business logic you want to apply. If you are validating the receipt against a server each time the use launch the app, of course you need the receipt. If it is not present (but in production is always) or not valid, you can ask for a refresh or restore, but as far as I remember you should always ask the user first if he/she want to do that (can be a reason for reject). Restore and Refresh are not the same thing.
  3. This usually appear in purchase/restor/refresh. But also If the account has some pending requests because the app has crashed or you interrupted the debugging before the request end somehow, you will be bored by a lot of that. There is no way to flush them programmatically, just login until they stop. Of course it will not be a valid test.
  4. It's up to you and about the kind of purchase. If it is an autorenewable subscription, you can validate the receipt against a server, then store the the "end date" on the client and make another check after the date is expired. Pay attention that receipts can be quite big, because the have also all history values.
Selectivity answered 8/12, 2015 at 16:53 Comment(5)
I think that's a pretty solid answer, thank you. So, if we are not as strict as to verify the receipt on startup, would after each purchase be a good point to do it ? We also don't want to run into point 2.) you mentioned. So the flow would be: 1) User purchases subscription. 2) Verify receipt 3) Verificaion Succeeded: Schedule a local notification for expiration date (Is this a safe method ?). 4) Receipt expiration notification fired -> Revalidate or Lock premium features. Does that seem like a good way of handling this ?Parthia
I really depends on the kind of purchase. If is not a subscription a validation right after the purchase sounds ok for me. If it is a subscription you must know the end of it, thus the flow you presented its fine except for the local notification. Let's suppose that you are buying a monthly auto renewable subscription, each month if the user doesn't stop the auto renew mechanism, the subscription is automatically renewed. I've tried to understand when this happen without success, probably few days before the real expire date.Selectivity
Automatically means that you do not need to do nothing. I would save locally (keychain) the expire day, when I'm around that date I would send the receipt again for validation, until is expired or updated. If the validation sees a new month I update the date, if the receipt is expired I would present an alert like "your subscription seems to be expired $end date$ would you like to try a refresh"? You can send the receipt to your validation server all the times you want without asking the user, but you can't refresh or restore without asking the user.Selectivity
Can you please give me suggestion about this? #47712725Whatsoever
Very good answer. I have one question, If I have an auto-renewal in-app purchase is my receipt will be going to change every time whenever the renewal happens? Or is there any chance my receipt will be changed or it will be always the same even if I reinstall the app?Tutelary
H
2
  1. As Zhang mentioned, if there is no purchase or restore took place, there will be no receipt in the store
  2. Locate the receipt. If no receipt is found, then the validation fails and you should not request receipt refresh again. Only when you will restore process by yourself, you should request for the receipt again.
  3. This will be shown always when you will try to refresh the receipt (or you will pick from settings that you want not to ask for a password for 15 minutes).
  4. Yes.

For more information, look here: https://www.objc.io/issues/17-security/receipt-validation/#about-validation

Henryk answered 8/12, 2015 at 16:36 Comment(0)
P
1

If a user downloaded the app from the App Store – yes, receipt always exists.

However, in sandbox if your app was installed via Xcode or Testflight, then there won’t be a receipt until you make a purchase or restore.

Take a look at this complete FAQ about receipt validation in our blog:

https://blog.apphud.com/receipt-validation/

Pileum answered 20/10, 2019 at 9:30 Comment(0)
M
0

1.No purchase/Restore took place.
2.Nope.See 1
4.Sure.For consumable products,remember to save hash on your server,in order to defeat replay attack.

Moralist answered 8/12, 2015 at 16:26 Comment(1)
I don't really understand here. The validation receipt is to check this is a valid transaction or not, right? So after the transaction state is .Purchased, i call to validate receipt to verify the order. And if the receipt is invalid, mark that trasaction is fraud, right?Shipboard

© 2022 - 2024 — McMap. All rights reserved.