I have been stuck on this issue for a long time. I'm a newer in Swift and I couldn't find a way to solve this problem.
I got the receipt data from my App, the code is,
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL, FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
do {
let receiptData = try Foundation.Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
print(receiptData)
// Read ReceiptData
print("receipt: \(receiptData.base64EncodedString(options: []))")
}
catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
}
which is copied from sample code from Apple Developer Document.
And this is one of the receipt data got from sandbox environment,
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
But when I use it to verify in sandbox environment, I always got 21002 error.
Then I found some receipt data from stackoverflow Apple receipt_data sample .
I use them to test my python code, it works. Here is the python code,
receipt = "xxxxxx"
url = 'https://sandbox.itunes.apple.com/verifyReceipt'
headers = {"Content-type": "application/json"}
data = json.dumps({"receipt-data": receipt})
res = requests.post(url=url,
data=data,
headers=headers,
verify=False).text
print(res)
So, it seems that it's the receipt data I got from Apple wrong.
I don't know why the receipt data is wrong. Is there anyway to find out the problem?
I'm using XCode (Version 14.1 beta 2 (14B5024i)) and a iphone SE to make a test. It purchased and verified according to StoreKit 2.
According to the issue I post on Apple Developer Forum, my problem lies in the environment. I used the product configuration file in run schema in XCode. So, the receipt data I got was signed by XCode instead of Apple Store. Below is the link of my issue, you can get more details from this issue.
https://developer.apple.com/forums/thread/729543
I changed the configuration and run the App in sandbox environment. Now, it works on both ways. I hope this case could help you.