in iOS with in-app purchases, it is necessary to verify receipts with subscriptions. is it necessary to verify receipts for consumables also?
2 Answers
No you don't need to verify receipts for consumables.
You don't need to verify receipts for subscriptions either. What's important here is that you can restore running subscriptions; but for that you can use purchase ID.
As always make 100% sure you've given the user what was paid for before telling iOS that the purchase was successful!
(There are all kinds of other considerations why you would like to keep purchase related information on a server, but that's not what you ask about.)

- 21,929
- 10
- 82
- 142
Necessary, no. Recommended, yes.
All purchases; consumables, un-consumables and subscriptions are susceptible to fraudulent attacks. Often though iap crackers or network spoofing. Validating the receipt can mitigate this problem.
You can validate the receipt locally in the app (see Validating Receipts Locally), though it is still susceptible to cracking.
The safest way to prevent fraud is to perform server-side validation by sending the receipt to your server then sending it on to Apple (see Validating Receipts With the App Store).
However, do not validate the receipt with the app store in the app itself. It's really easy to spoof the network request and return a positive (valid) result.
If you notice a large discrepancy between the actual purchases in your reports from Apple and your in-app purchase analytics (assuming you have that), you may want to invest in server-side validation, otherwise, if it's not a problem, don't worry about it.

- 13,440
- 11
- 59
- 90

- 11,278
- 4
- 30
- 54
-
1In case of server-side validation with consumable products, what happens if a network operation fails while verifying the receipt? For example, suppose the product is purchased and the receipt is sent to the iPhone. Then, the receipt is in turn sent from the iPhone to the trusted server. If this latter network operation fails, should the receipt be saved in order to retry validation in a second moment? (receipts for consumable product compare only at the time of the purchase). I think this way is not correct since in this case the user pays for a product which can't be immediately used. – Andrea Gorrieri Jun 19 '18 at 10:03
-
2@AndreaGorrieri handing upstream failures such as network outages depends on how you want to handle fraud. You can either treat purchases as fraudulent until proven valid or valid until proven fraudulent. In the former case, send the receipt to your server, keep retrying exponentially if it fails (e.g. no network, 500, etc.). In the latter, send the receipt, unlock the content anyway if it fails and keep retrying. Revoke access if the receipt is fraudulent. – Marc Greenstock Jun 20 '18 at 10:52
-
2Thanks @Mark, what I'm concerning about is: since receipts for consumable product compare only at the time of the purchase, how should the validation retry be managed? Should i save the receipt locally in order to retransmit it in the future? Can i simply does not mark the transaction as "finished"? From what i understand in documentation, in this latter case StoreKit should call the transaction queue observer again (passing the receipt) until the transaction is marked as "finished", is it correct? – Andrea Gorrieri Jun 20 '18 at 12:21
-
2@AndreaGorrieri Once you finish a transaction on a consumable purchase, the transaction will be removed from the receipt. I.e. if you were to finish the purchase queue before validating, there will be no transaction in which to validate. However, if you validate before finishing and you encounter an error on your server you will need to decided what to do. You could save the receipt locally (before finishing), call finish, then exponentially reattempt to validate. If the receipt is fraudulent you could punish the user somehow, e.g. if your selling in-game currency, take some away. – Marc Greenstock Jun 21 '18 at 14:03
-
Thanks @Mark for your help, suppose I finish the transaction only AFTER receipt validation so that in case of receipt validation error (network outages) the transaction is not finished. In this case will the paymentQueue(_:updatedTransactions:) method be called again? Can I retrieve in that moment the receipt for the consumable product and retry the validation procedure? Is the credit card of the user charged if a transaction is not finished? – Andrea Gorrieri Jun 22 '18 at 10:39