App Store Receipt Validation on iOS 7

In October 2010, Apple introduced the Mac App Store, and with it a unified receipt stored in the application bundle. Three years later, iOS gets the same treatment with the release of iOS 7.

Unfortunately, validating and parsing the receipt on the device in neither easy, nor well documented. As I discussed this subject on the Apple developer forums, I saw many developers getting stuck at various stages of the process, and some throwing the towel in.

This article contains a few gotchas I had while implementing receipt validation in Tap Tap Chinese. I hope it will save some time (and hair) to my fellow developers.

Where is my receipt?

I used NSBundle’s appStoreReceiptURL to locate my receipt, but there is no file at this URL!

This is normal in a development environment. In order to get a valid receipt from the App Store, you need to start a SKReceiptRefreshRequest and wait for its delegate’s requestDidFinish: method to be called.

When you start the refresh request, iOS will prompt you to enter your App Store credentials. You need to enter a test user’s credentials, otherwise you will get an error. Additionally, this test user must have made a test purchase before.

This can only be done on a device, as StoreKit is not available in the iOS simulator.

Here’s for the lazy ones

Why doesn’t Apple just provide a method to validate and parse the receipt in one line?

The reasoning behind this is that if Apple did, everybody would use the exact same code to validate the receipt, and it would make it easier for pirates to crack your applications.

Instead, they chose to use standard cryptography and encoding techniques (PKCS7 and ASN1) and give hints for implementing the validation and parsing.