Understanding receipt validation and receipt refreshing in iOS

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/


  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


  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.