17

The Apple docs on receipt validation say to perform receipt validation immediately after launch. This amounts to checking for data at the path returned by [[NSBundle mainBundle] appStoreRecieptURL], refreshing via SKReceiptRefreshRequest if it's not there, and validating it. The aforelinked docs reference both iOS and macOS.

Is it actually necessary on iOS? If so, why? Is it to prevent users from using my app on a jailbroken device, or without having bought it from the app store (in which case I probably don't care if my app is free)? Or does it have implications for other operations like restoring or validating in-app purchases? For example, does the receipt data have to be there already in order to validate a transaction for an in-app purchase?

Note: I am not using in-app subscriptions. I have in-app purchases, but I don't use the receipts from them after verifying them and recording the purchase server-side.

Tom Hamming
  • 10,577
  • 11
  • 71
  • 145
  • you don't _need_ to do so, that is optional only and could be done on iOS7+; implementing the validation is purely a financial decision, and even if you validate it, you are recommended _not_ to disable the content in case of failure as the validation could fail in standard environment as well anytime (e.g. in case of no connection) which may ruin your consumers experience; altogether, doing the validation'd rather make sense on OSX in practice. – holex Oct 17 '16 at 20:46
  • @holex can you make this an answer? – Tom Hamming Oct 24 '16 at 20:01
  • no prob, I just did it as you requested. – holex Oct 25 '16 at 08:12
  • https://stackoverflow.com/questions/12738061/receipt-validation-issue-in-app-purchases-mac-store-receipt-validation-should-b – pkamb Nov 06 '19 at 22:00

5 Answers5

14

you don't need to do so, that is optional only and could be done on iOS7+, if you interested in doing that.

briefly, implementing the validation is purely a financial decision, and even if you validate recipes you are recommended not to disable the content in case of failure as the validation could fail in standard environment as well anytime (e.g. in case of no connection), and such overreaction may ruin your consumers' experience.


altogether, doing the validation'd rather make sense on OSX in practice when you are allowed to disable the content in case of failure, regardless the reason; but if you feel you have more consumers than your income suggests or the amount of the stolen content is way beyond your margin, it may be worth to do it on iOS as well.


NOTE: in general you can read more about the technical details of receipt validation in Apple's Documentation.

holex
  • 23,961
  • 7
  • 62
  • 76
  • Can you please give me suggestion about this? https://stackoverflow.com/questions/47712225/auto-renewable-subscription-wrong-time-response-sandbox-mode – Siddharth Dec 09 '17 at 09:12
4

The simple answer to your question is NO, It is not necessary.

Here is the detailed explanation for you.

  1. According to Apple Documentation here, apple has given two methods of validating the receipts, they are given it as guidance only to prevent unauthorized copies of your application from running. For more guidance apple has pointed towards the apple review guidelines.
  2. In the review guidelines here, Apple does not mention anything related to the verification of receipts as mandatory.

If at all the receipt validation is mandatory, Apple would have provided a simple API to validate it.

Titbit: You can see a lot of rejections when it comes to app store receipt validations. But all those issues are because the receipt validation is not done properly.

But my personal recommendations will differ from the above answer. First thing for you to consider is "Never underestimate hackers". Validate the receipts several times apart from the start of the app. Read this article for more information.

Praveen Kumar
  • 1,338
  • 3
  • 20
  • 31
  • 1
    `Apple would have provided a simple API` - can't. Receipt validation call of this `simple api` can be patched and thus bypassed. There is no fool proof validation code for receipts but a good protection can be obtained by obfuscating the logic and this should be different from app to app and not known publicly. Thus can't have an Apple API. – Vikram Rao May 13 '17 at 23:03
3

You would generally only validate the receipt to prevent piracy by users who haven't bought your app or if you are using auto renewing subscriptions.

Whilst you can interrogate the receipt for IAP information, its actually easier (and required by app review) to give a button somewhere to "restore previous purchases" and call

[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];

It is also a better UX for the user to possibly be prompted for their Apple ID and password having pressed a "restore purchases" button rather than unexplained at app startup.

Daniel Broad
  • 2,512
  • 18
  • 14
2

The reasons I would give are:

  1. The user can change their product if you are using subscription groups from outside of your app.
  2. An auto-renewing subscription can renew outside of your app.
  3. The app does not receive transactions initiated outside of the app until the app restarts.
  4. The user can make purchases on another device using the same appleID whilst outside of your app on the current device.

Within our appDelegate:application didFinishLaunchingWithOptions we initialise a class that calls [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; to monitor for purchases initiated from within the app.

iCyberPaul
  • 650
  • 4
  • 15
0

It's not necessary, but beneficial for the following reasons:

  1. You'll always get the definite set of purchased products and not require the user to manually restore the products.

  2. You have (limited) fraud protection, especially if you combine local and remote validation.

  3. It's way more simple to compute the expiration date for automatically renewing subscriptions using the recipe.

DrMickeyLauer
  • 4,455
  • 3
  • 31
  • 67