There is a lot of example about how to test in-app purchase receipt validation by using a sandbox tester account.
But how is the Receipt for the paid App itself? How can we get the App Receipt in development environment?
There is two thing I want to do:
To prevent illegal copy of our app running by the user who didn't purchase the app. As I have seen app that detected the iTune Account was connected doesn't owned the app (it shows warning to the user they didn't own the app, but they fail to stop the user to continue to use the app)
Send the app purchase receipt to our server. We want to know when do they buy our app, what version of app they brought.
Most parts of the answer can be found here in Apple's documentation. But there are gaps and the objective-c code is using deprecated methods.
This Swift 3 code shows how to get the App Receipt and send it to the app store for validation. You should definitely validate the App Receipt with the app store before saving the data you want. The advantage of asking the app store to validate is that it responds with data that you can easily serialize to JSON and from there pull out the values for the keys you want. No cryptography required.
As Apple describes in that documentation the preferred flow is like this...
When the app store returns to your server, assuming success, that's where you'll serialize and pull out the data you require and save it as you wish. See the JSON below. And you can send the result and whatever else you want back to the app.
In
validateAppReceipt()
below, to make it a working example, it simply uses this flow...To make this work with your server just change
validationURLString
to point to your server and add whatever else your require torequestDictionary
.To test this in development you need to:
Here's the code. The happy path flows just fine. Errors and failure points just print or are commented. Deal with those as you require.
This part grabs the app receipt. If it's not there (which will happen when you are testing) it asks the app store to refresh.
This part validates the app receipt. This is not local validation. Refer to Note 1 and Note 2 in the comments.
You should end up with something like this. In your case this is what you would be working with on your server.
if you want to test in-app go in the sandbox environment for receipt validation and please take into consideration that in sandbox renewal intervals are
1 week 3 minutes 1 month 5 minutes 2 months 10 minutes 3 months 15 minutes 6 months 30 minutes 1 year 1 hour
The best way is to validate receipt is to communicate your server with the apple server for validation.
I am assuming that you know how to perform InApp purchase.
We are required to validate a receipt, after a transaction is finished.
Once the product has been purchased successfully, it needs to be validated. Server does this for us, we just need to pass Receipt data returned by Apple server.
The response’s payload is a JSON object that contains the following keys and values:
status:
Either 0 if the receipt is valid, or one of the error codes mentioned below:
For iOS 6 style transaction receipts, the status code reflects the status of the specific transaction’s receipt.
For iOS 7 style app receipts, the status code is reflects the status of the app receipt as a whole. For example, if you send a valid app receipt that contains an expired subscription, the response is 0 because the receipt as a whole is valid.
receipt:
A JSON representation of the receipt that was sent for verification.
We will get staus code 21007 for successful receipt valication, in Sandbox environment.
In the test environment, use https://sandbox.itunes.apple.com/verifyReceipt as the URL. In production, use https://buy.itunes.apple.com/verifyReceipt as the URL.
transactionReceipt
is deprecated: first deprecated in iOS 7.0