Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Apple-Provided Vulnerable Approach</strong></p> <p>The server can authenticate a purchase by <a href="http://developer.apple.com/iPhone/library/documentation/NetworkingInternet/Conceptual/StoreKitGuide/VerifyingStoreReceipts/VerifyingStoreReceipts.html#//apple_ref/doc/uid/TP40008267-CH104-SW1" rel="noreferrer">doing the following</a>:</p> <ol> <li><p>The iPhone application receives a <a href="http://developer.apple.com/iPhone/library/documentation/StoreKit/Reference/SKPaymentTransaction_Class/Reference/Reference.html#//apple_ref/occ/instp/SKPaymentTransaction/transactionReceipt" rel="noreferrer"><code>transactionReceipt</code></a> after the purchase. Have the iPhone <a href="http://en.wikipedia.org/wiki/Base64" rel="noreferrer">base64</a> encode it <em>(You can use this open-source <a href="http://www.cocoadev.com/index.pl?BaseSixtyFour" rel="noreferrer">addition to NSData</a>)</em> and send it to your server. <em>(You could even send it as-is and have the server base64 encode it before validation.)</em></p></li> <li><p>Have your server send a JSON request with the single key <code>receipt-data</code> with the base64 encoded <a href="http://developer.apple.com/iPhone/library/documentation/StoreKit/Reference/SKPaymentTransaction_Class/Reference/Reference.html#//apple_ref/occ/instp/SKPaymentTransaction/transactionReceipt" rel="noreferrer"><code>transactionReceipt</code></a> to <code>https://buy.itunes.apple.com/verifyReceipt</code> using an HTTP POST. (For directions on how to do this in various server-side languages <a href="http://www.json.org/" rel="noreferrer">see this site</a>)</p></li> <li><p>The server will respond with a JSON object with two keys: <code>status</code> which is an integer and <code>receipt</code> which is the receipt repeated.</p></li> </ol> <p>If status is zero, the receipt is valid should be accepted, a non-zero value means the receipt isn't valid.</p> <p><strong>Secure Additions to Apple's Approach</strong></p> <p>However, there are a few security implications. A user could use another user's receipt since devices aren't tied to receipts, or a user could use another product's receipt since the server doesn't verify the product id of the receipt. To ensure this doesn't happen you should also do the following:</p> <ol> <li><p>When you first get the receipt in the application, immediately send it to your server along with the <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIDevice_Class/Reference/UIDevice.html#//apple_ref/occ/instp/UIDevice/uniqueIdentifier" rel="noreferrer">device's UUID</a> over a secure channel such as HTTPS or an SSL socket. <em>Do not store it anywhere, leave it in memory.</em></p></li> <li><p>On your server, store the UUID and receipt pair in a database.</p></li> <li><p>When a device sends a UUID and receipt pair, verify with your database that the receipt has not already been used, <em>and</em> make sure the receipt is actually for your product by checking the <a href="http://developer.apple.com/iPhone/library/documentation/NetworkingInternet/Conceptual/StoreKitGuide/VerifyingStoreReceipts/VerifyingStoreReceipts.html#//apple_ref/doc/uid/TP40008267-CH104-SW4" rel="noreferrer">receipt's product id</a>. <em>The receipt is just a JSON object, so your server can read the contents by decoding the receipt from base64.</em></p></li> <li><p>Return a response to the device over the secure channel telling it whether the purchase is: </p> <ul> <li>Authenticated as new (wasn't in DB and was valid)</li> <li>Authenticated in the past (Same UUID and receipt pair was already in DB)</li> <li>Denied due to wrong product id</li> <li>Denied due to having already used the receipt with another UUID.</li> </ul></li> </ol> <p>Since the receipt is only ever in memory on the device, and your application uses the device's UUID (<strong>can be <a href="http://www.theiphonespot.net/2009/09/18/udid-faker/" rel="noreferrer">spoofed by jailbroken devices</a></strong>, see comments), and all purchases of your product are logged with the device's UUID on your server in a secure manner; a user could not use another user's receipt to verify the purchase, nor could they use a receipt from another product, since you check for that.</p> <p>You can also validate other fields from the receipt if you want to verify other details of the transaction. For example, if your product is a subscription, you'll like want to look at the transaction date as well.</p> <p>Also, users cannot pretend to be your server by having the device on a private network with a host of the same name as yours, since they won't have your SSL certificate.</p> <p><strong>Failure Considerations</strong></p> <p>Since failure might occur between when the user's device gets the receipt and verifying it with your server (for example if the user looses connectivity, or your server is down for maintenance), you should also let the user "re-authorize". Re-authorizing should get the receipt from the store <em>(using a <a href="http://developer.apple.com/iPhone/library/documentation/NetworkingInternet/Conceptual/StoreKitGuide/MakingaPurchase/MakingaPurchase.html#//apple_ref/doc/uid/TP40008267-CH3-SW2" rel="noreferrer">Restored Transaction</a>)</em> and re-send it to the server just as though this was a new purchase. This should rarely need to be used, but should be available to save the user having to re-buy the product in the case of network failure.</p> <p><strong>Multiple Devices Consideration</strong></p> <p>This means that if a user wants to use an application on more than one device, they will have to purchase the product multiple times. This might be the desired effect, but you should likely inform your users before they purchase since they might expect to be able to use the content across devices they have associated with their account.</p> <p>If the receipt also contains the iTunes account information, authentication could use that to allow users to share content between all their devices (but not their friends').</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload