I've read Apple's documentaion a few times now and I didn't really get much smarter from it. So I hope somebody here knows how to deal with receipt validation:
I know there was a problem pre iOS 6. But is Receipt Validation needed nowadays on iOS 7? Does it really add extra security? It seems like it can cause problems if Apple changes the format of their receipts (parsing them on device).
In what I've seen, iOS7 doesn't change the need for whether or not you should do receipt validation, just how receipt validation is possible. iOS7 has enabled receipt validation on the device (e.g., see link from https://stackoverflow.com/users/1226963/rmaddy above, and see A complete solution to LOCALLY validate an in-app receipts and bundle receipts on iOS 7).
Does on-device receipt validation add extra security? It seems to me that it does. It gives you one more tool with which to secure your purchases. In my app (yet to be released), I want to support iOS6 and iOS7 so I decided to have a back-end server to do receipt validation for the iOS6 case. And since I have that server in place, for iOS7 receipts, I do on-device validation first and if that succeeds, I do server validation as a second check.
Whether or not you do receipt validation (in iOS5, iOS6, iOS7 etc) really depends on how much your security means to you. If you don't have much in the way of security needs, then why spend much time on security. If you do, then do more.
What if Apple changes the format of the receipts? Well, of course, this can and likely will happen. Given that the iOS6 to iOS7 change restructured receipts and in-app purchases considerably, it seems we should expect iOS8 to do so again. That's the future. Deal with what we have now.
Receipt validation is not required, but needed in these cases:
In case of auto-renewable subscriptions when a purchase has just been made – to get an expiration date.
When restoring in-app purchases. If user has reinstalled the app or launched it from a new device, you must provide a mechanism to restore his purchases and give access to features he already paid for.
A couple of years ago, when jailbreak was commonly used, developers used to validate receipts to verify that payment wasn’t hacked – I believe those days are gone now, and it’s not so necessary anymore.
Here is a complete FAQ about App Store receipt validation from our blog:
https://blog.apphud.com/receipt-validation/
Related
We have a successful app on the iOS app store with in-app purchases. Every time a purchase is completed we send the receipt to our server, our server than checks the receipt with Apple's servers and logs apple's response(including whether the purchase was valid and that they come from our app in that same time and date).
We have quite a few users who use iap cracks that send us receipts that apple says are invalid. However we started now to see cheaters that have receipts that apple replies that are VALID. What is strange in these cheats, that when such a cheater user purchases in our app, he usually purchases all of the purchases with the exact same receipt.
Have you heard of such a way to 'fool' apple receipt validation?(to generate receipts that apple will say they are from our app in the time of the 'purchase')
Is there something we can do to find those cheaters in their 1st purchase (for the next purchases we can simply check times of the next receipts or make sure that our receipts are unique)
Thanks!
Is there something we can do to find those cheaters in their 1st purchase
Actually, if this is the same hack I've seen discussed as a proof of concept recently, the first purchase is legitimate. The "innovation" is in decoding that legitimate receipt and rejigging its IAP ID with a different one while the receipt overall still appears valid. So simply avoiding the duplicates is enough. Didn't think that one was anywhere near production-ready though, so this might be something different.
We also faced similar issue while developing a game of iOS app store where business model was based on In App Purchase only.
Initially we used to check with Apple Servers for the receipts directly from the device. But some hacker has created a hack for the users where they can install the DNS server certificate on their device which spoofs the response from Apple.
The way to do this is let web server check for the receipts from Apple directly with some kind of hashing or md5 check to make sure the response if from Apple.
here is a link which have a detailed information on this https://www.objc.io/issues/17-security/receipt-validation/
Hope this helps.
I am trying to find the dates when apple will no longer accept the old style IAP receipt validation previous to iOS7 ? I looked at the apple doc's but I could not find it.
Thanks in advance
Do you mean "when will the transactionReceipt property disappear from SKPaymentTransaction"? That's happened in the Swift SDK.
Or do you mean "when will iOS 6 style receipts stop being accepted by Apple's web services?" That is unlikely to ever happen without a compelling reason to disrupt functioning code and purchase histories, so I wouldn't be overly concerned about that possibility. But Validating Receipts With the App Store would be a good place to go visit and upgrade to current best practices. Just in case.
OK I'm working on a app where the user purchases the app from the App Store, gets access to the app for a year, and then after the year has passed they are sent to an In-App Purchase screen where they can purchase a subscription for continued access.
(this is not the subscription model I'd implement if it were up to me, but the client insists that it follow this model)
In order for it to work, though, I need a reliable way to check when the app was purchased, in order to calculate when the first year of access ends. Following the suggestions in one of the answers in...
iOS App Purchase Date
...I've gotten the app receipt and I can find all the data fields that the documentation says there are, but there are also a few others including "original_purchase_date" (not the one in the IAP receipt array; the one for the app receipt itself). This would appear to be what I want. However this field is undocumented.
As far as I can tell, Apple security operates via a form of "Security Through Obscurity/Diversity", so it's been difficult to find further information about these undocumented data fields. My concern is that I might use the data from this field, and then discover that it was only there in sandbox mode and actual receipts don't have it. Worse, what if I reference that field and then Apple releases a new iOS update that completely discards that field from its implementation? Undocumented features are even less reliable than deprecated features, after all.
My question is this: is there a reliable source of information somewhere where I can find out what Apples intends regarding this field? Or better yet, is there another, safer way of achieving the system my client wants?
You have to implement it as a free app that requires a subscription IAP. Paying for an app cannot be its subscription cost.
Check rule 11.12 here: https://developer.apple.com/app-store/review/guidelines/#purchasing-currencies
Apps offering subscriptions must do so using IAP, Apple will share the
same 70/30 revenue split with developers for these purchases, as set
forth in the Program License Agreement
Implementing it the way your client wants will result in rejection.
Confused by several aspects of in-app purchase "restoration". Quick summary of my situation: have a paid app in store now, supports ios6 and ios7. Want to move to freemium model, with in-app purchase for "pro upgrade". So will need two bits of receipt functionality--check original install version, and restore in-app purchase. Found the promising looking RMStore, but have a couple of questions still:
I see many examples online (non-RMStore examples) that say to call restoreCompletedTransactions to restore in-app purchases, but in RMStore there is the RMAppReceipt method containsInAppPurchaseOfProductIdentifier. If I'm using RMStore, do I need to call restoreCompletedTransactions, or can I just use the RMAppReceipt method above to verify prior in-app purchase?
Can I use the above RMStore methods in ios6? Or is it ios7 only? I see info online that suggests "unified receipts" only available in ios7 or somesuch.
Non-RMStore specific question: Is receipt validation required, or just recommended? I.e., will the above work if I skip validating the receipt, or will app store reject w/o validation code?
If I'm using RMStore, do I need to call restoreCompletedTransactions, or can I just use the RMAppReceipt method above to verify prior in-app purchase?
In iOS 7, you can use on the app receipt. If you don't want to rely on the receipt, you can use your own transaction persistence. In RMStore, this is a simple as setting a default or custom transaction persistor and should work in all supported iOS versions.
In general, it's best to avoid restoring purchases frequently as it forces users to enter their password. Only do it if the user requests it, or if you have no other option.
Can I use the above RMStore methods in ios6? Or is it ios7 only? I see info online that suggests "unified receipts" only available in ios7 or somesuch.
iOS 7, as the receipt does not work in iOS 6 or lower.
Non-RMStore specific question: Is receipt validation required, or just recommended? I.e., will the above work if I skip validating the receipt, or will app store reject w/o validation code?
Recommended.
Back last year, that russian hacker created a way to validate in-app purchases without payment and this guy created a class to verify each purchase.
As far as I know, this technique exposed by the hacker does not work on iOS 6 anymore, but I am not sure about that.
I am creating a new app for iOS 6 and trying to minimize the code to a minimum and even better than that, my in-apps involved hosted content with Apple, so I wonder if this added validation is really necessary for my case.
Remember that
I am developing for iOS 6 and up;
my in-apps have hosted content with apple, so even if the hacking technique works the person will never get the content hosted with apple.
any thoughts?
thanks.
The vulnerability should be addressed in iOS6, but that does not mean you should deviate from Receipt Validation best practices in general. See Verifying Store Receipts and
In-App Purchase Receipt Validation on iOS for more information.
As mentioned in the links above, Apple recommend you follow their best practices for receipt validation, be it on iOS 5 or iOS 6. "Simplicity of code" is not a good enough excuse to deviate from these guidelines. If you structure your code into well defined classes, you can abstract away all the receipt validation logic to its own class, making the code that uses it a lot cleaner anyway.
If you connect to the App Store directly from the App for validation, the measures they explicitly state (see "My app performs validation by connecting to the App Store server directly. How am I affected?") should help. If you implement them in an abstracted way (in a category or class), then it should still keep your code clean.
Even if your content is hosted by Apple, you're still giving yourself an extra safeguard against fraud. Apple are not perfect; they could slip up themselves leaving your app open.
Ultimately, when you're dealing with your own revenue, you better play it safe than be sorry afterwards.