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.
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.
If you’re testing a receipt for the sandbox, the endpoint URL to check with is
https://sandbox.itunes.apple.com/verifyReceipt. The endpoint URL for real transactions is
As such, we can set the URL based on the value of
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
$postData variables we have defined.
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
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
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,
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.
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.
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.