Verifying Apple App Store Receipts For In App Purchases With PHP and cURL

One of the features available to iOS developers when creating iPhone or iPad applications is the ability to sell items within their application (called In App Purchases).

In many cases, the In App Purchase will be fulfilled by downloading data from a third-party server. Before the iOS application can download the purchased item, the third-party server must check with Apple to ensure the item has been successfully purchased.

The following diagram demonstrates how this works in principle.

In this PhpRiot snippet I will show you how to verify a purchase receipt that was submitted by the iOS application with the Apple receipt verification service. We will achieve this using PHP and cURL. Referring to the above diagram, the code in this article will deal with steps 3, 4 and 5.

Note: This article assumes your iOS application already has the ability to submit the StoreKit receipt data in Base-64 encoding to your PHP web site.

To verify a receipt, we will define a function called getReceiptData(). This function will return information about the transaction being verified if the receipt is valid, and it will throw an exception if the receipt is invalid or if the receipt cannot be verified.

The following listing demonstrates the basic skeleton for this script. The first argument ($receipt) is the base-64 encoded receipt data exactly as supplied from the iOS application.

The second argument ($isSandbox) is a boolean indicating whether the receipt being verified is from a real transaction or a transaction from a test user.

Note: This code assumes your iOS application performs a POST request which includes data in receipt and sandbox.

If you’re testing a receipt for the sandbox, the endpoint URL to check with is The endpoint URL for real transactions is

As such, we can set the URL based on the value of $isSandbox.

The verifyReceipt web service requires a post request consisting only of a JSON-encoded string. This string should correspond to a JavaScript object with a single key called receipt-data. This can be defined in PHP using array('receipt-data' => $receipt).

Once this array has been defined, json_encode() can be used to build the JSON string.

Next we build the cURL request using the $endpoint and $postData variables we have defined.

Note: Your cURL installation must support SSL in order to communicate with the Apple web service.

In addition to setting the request post data (including setting the request to use POST instead of GET), we must also instruct cURL to return the response. This is achieved by setting the CURLOPT_RETURNTRANSFER to true. If you don’t do this, the response from the HTTP request will be output directly and you will be unable to parse it.

The listing below shows how we build the cURL request. Additionally, this code also performs the request (and assigns the response data to $response), retrieves any error codes or messages and finally closes the connection. We will make use of this data shortly.

Finally, we must check the response data. If the request failed for some reason, the $errno value will be non-zero. In this case, we throw an exception that includes the error number and message. This will be handled by the code that calls getReceiptData().

Note: You can see a list of cURL error codes at

At this point in the code we know we know the HTTP request was successful, so we must parse the response and ensure the submitted receipt was successful. This web service returns a JSON object with two keys, status and receipt.

We can turn the JSON string into a PHP object using json_decode(). This function will return null if the string wasn’t a valid JSON string.

If the status value is 0, the receipt was valid, otherwise it was not valid. As such, we throw an exception for non-zero values. If the receipt was valid, we build an array of data to return.

Note: There are other values returned by the web service. See the link below to Apple’s guide.

The following listing shows the entire code. You may want to move getReceiptData() into its own class or file so it can easily be reused.

Now that you can verify the receipt data, you can fulfill the user’s request. If you deem the receipt to be valid you can send back the requested data, otherwise you can send back an error message so your iOS application can communicate the problem back to the user.

Further Reading

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedIn

Leave a Reply

Your email address will not be published. Required fields are marked *