How to verify ios In-App Purchase on your server

29,992

Solution 1

Fetch the app's receipt (from the file at [[NSBundle mainBundle] appStoreReceiptURL]) and send it to your server. Then either…

  • Parse the receipt and check its signature against Apple's certificate as described here (on your server, not in the app). Or,

  • Send the receipt (again, from your server) to the app store for validation as described here.

Solution 2

I just released a simple Python/Django web app (In-App Purchase Receipt Verifier) that automatically handles the annoying part of this process (i.e., verifying the receipt on your server while maintaining cryptographic integrity). The code itself is relatively simple, but I figured others would appreciate not having to do the grunt-work here.

To use it, just make sure you have your app-specific shared secret ready to go, then go here and click "Deploy to Heroku". Your app will be up and running within a minute.

I've also included some sample code for how to use this web app to validate your receipts within your app. Using Swift 4:

guard let receiptURL = Bundle.main.appStoreReceiptURL,
    let data = try? Data(contentsOf: receiptURL) else {
      return
}

let encodedData = data.base64EncodedData(options: [])
let url = URL(string: "https://your-app.herokuapp.com/verify")!

var request = URLRequest(url: url)
request.httpBody = encodedData
request.httpMethod = "POST"

let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
    guard let data = data,
        let object = try? JSONSerialization.jsonObject(with: data, options: []),
        let json = object as? [String: Any] else {
            return
    }

    // Your application logic here.
}
task.resume()

Note: There are other solutions floating around on StackOverflow that suggest to do the validation completely within the app itself, but I'd highly recommend against that. From Apple's documentation in Receipt Validation Programming Guide:

Use a trusted server to communicate with the App Store. Using your own server lets you design your app to recognize and trust only your server, and lets you ensure that your server connects with the App Store server. It is not possible to build a trusted connection between a user’s device and the App Store directly because you don’t control either end of that connection.

Further improvements could probably be made to add some sort of cryptographic signature within the response header so that your app can check whether the response is safe, but I'll probably add that in a future release. Done :)

Solution 3

Server can verify receipt with App Store by Http Post. Please refer to https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html

Share:
29,992
Marko Zadravec
Author by

Marko Zadravec

Updated on November 12, 2020

Comments

  • Marko Zadravec
    Marko Zadravec over 3 years

    I am up to build my first in-app purchase app. I would like to know whether there is a way to verify purchase on your server.

    I have to build the whole user management, and I would like to know for all registered user what they already bought on their iOS devices, so that they get web app for free, or something like that. So, is there a way for me to check on Apple store side, if this user has already buy some product?

    EDIT:

    Scenario is like this:

    User A buy app B on mobile device. After this I would like to check on my server (on my web page,...) if user A is bought app B, or (similar) which app was bought by user A.

    I don't want to send message from mobile device to my server that user A buy app B, because users can reproduce this call on server even if they didn't buy app B.

    I would check on server side whit app Store if user A bought app B.