When a user buys an IAP, they are issued with a receipt, which is stored locally on the device. In this video you'll learn how to use validation of these receipts to keep track of which IAPs the user has purchased.
Hi. I am surprised you don’t mention receigen, which is available on the App Store. It makes the hard stuff for you, but varies the code each time and makes the obfuscation. Thus we don’t have to write any code in C to make it work.
Hi @samdavies , in video you have used RMStore to validate receipt, which in turn uses openssl. I am planning to use SwiftyStorekit for IAP, do u think receipt validation in SwiftyStorekit is as powerful as openssl? and is it in accordance with Apple’s recommendation of implementing receipt validation?
I’ve not used SwiftyStoreKit, but it looks like it has a nice API. However, a brief perusal of the code around receipt validation suggests that it uses a technique that Apple specifically recommends against using.
There are 2 ways of doing receipt validation - 1 is to confirm the receipts cryptographic signature. This can be done independently, and hence on device. The second is to contact the App Store servers and request them to confirm a receipt is valid. This second way is significantly easier to implement, but is not appropriate for use on device.
This is because as a developer you cannot guarantee the security of either end of the connection. Apple specifically recommends against this in their docs:
It’s therefore recommended to only use this approach for server-App Store communications - where you can guarantee the authenticity of one end of the communication.
SwiftStoreKit uses this approach to validate receipts. As I said, it’s significantly easier to implement, but much less difficult to spoof. Therefore, in the video I used RMStore and openssl to perform the receipt validation procedure. This is appropriate for use on device.
As with everything, it becomes a risk-reward problem. It’s up to you to decide the risk of people spoofing your IAP receipt validation against the cost to you. It’s still not trivial to spoof receipt validation with the remote approach, but it is significantly easier than with the cryptographic signing.
Hope that helps - sorry it became a overly long braindump
I find this all quite overwhelming.
My last two apps have been freemium with in-app purchases. It is working well for me. I have a couple of older apps that I want to convert from paid to freemium with in-app purchases. I am having real difficulty figuring out how to locally validate the receipt for date of purchase and version purchased so that I can give those previous owners credit for the in-app purchase.
There is lots of information out there, but nothing that is detail enough and step-by-step for me with Swift 3.
Getting and compiling OpenSSL as well as adding this to my Xcode project is beyond my current ability so if anyone has a step-by-step tutorial available, or in the works I am sure I, and others would very much appreciate this.
Hi,
I see that you distribute openssl as a pre-compiled binary in the project (libssl_IOS.a). Did you build this binary yourself? Is it safe to use this in a production app? I ask because it is recommended that you build the binaries yourself.
It’s a while since I made this video, but I’m pretty sure I mentioned that you should not include this pre-built binary in your app. This is especially true now that the binary that’s part of this sample app is over 2 years old.
I distributed it as a binary here because I wanted to concentrate on the mechanics of receipt authentication, without having to go into detail about how to compile libSSL yourself. Sadly, you’ll have to do this as part of distributing your own production app.
I am witnessing the following (in sandbox):
• User A purchases my auto-renewing subscription
• User A logs out of iTunes & App Store
• User B logs in, receipt is still there on next app launch and exactly the same, so he still uses User A’s subscription.
Will the receipt be ever updated to show User B’s subscription state? How do we handle this case? Thanks in advance.