I am working on a client/server application which uses Apples IAP and StoreKit framework to purchase a subscription.
What we would like is for the client (iPhone or iPad) to make the initial subscription purchase with apple through their iTunes account using StoreKit framework and then pass of the receipt to our server, which will validate it and then update the users account status. We'd also like the server to be responsible for managing the status of the subscription (check for auto-renew, cancellation etc..) This is all using iOS 7 style appleReceipts, rather than iOS 6 style transaction receipts which are deprecated currently.
Apple's docs say to POST to the following URL to validate a receipt in the sandbox along with the receipt and the secret code
https://sandbox.itunes.apple.com/verifyReceipt
Up to this point .. everything works as it should.
Where things get confusing to me is in the response. Apple's docs say that the response should have up to 4 fields. If you are validating an iOS 7 style app receipt then you should only expect the first 2. If it's an iOS 6 style subscription transaction receipt then you should expect to see all 4.
1) status (0 for valid, some error code otherwise)
2) receipt (a JSON representation of the receipt that was sent)
3) latest_receipt (Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions. The base-64 encoded transaction receipt for the most recent renewal.)
4) latest_receipt_info (same as above in JSON format)
Problem 1: I am seeing all 4 even though I am validating an iOS 7 style app receipt. The docs say that shouldn't be happening.
Problem 2:
We'd like to have the server handle maintaining the user subscription status by polling this API with the original app receipt that the client passed after its initial purchase. The latest_receipt_info
field does seem to contain a continually updated list of transactions, while the receipt
field is a copy of the original with no updated transaction information.
My Question:
It seems then that the only way the server can get information about updated transaction is by looking at the latest_receipt_info
or latest_receipt
fields, but those fields are not supposed to be present in the response according to the documentation.
Is this an error in the Apple documentation? Or is the only way to get the latest set of transaction is to have the client send updated AppReceipts when it gets notified by the SKPayementTransactionObserver
?
EDIT -- adding steps taken and some code as per comment below.
1) Making a purchase of a autoRenewSubscription product using SKPaymentQueue:
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
payment.applicationUsername = [self hashedValueForAccountName:[UserAccount sharedInstance].subscriberKey];
[[SKPaymentQueue defaultQueue] addPayment:payment];
2) When the payment is completed I get a call back through my SKPaymentTransactionObserver and send the file at the following URL:
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
to my remote server.
3) I'm using the following python code to validate the receipt
import itunesiap
import base64
file = "/path/to/receipt/sandboxReceipt"
f = open(file)
encoded = base64.b64encode(f.read())
with itunesiap.env.current().clone(use_sandbox=True): # additional change for current environment.
response = itunesiap.verify(encoded,"mysecretkey")
The response contains a dictionary. The dictionary has the following fields
"latest_receipt" = base64 encoded receipt here
"latest_receipt_info" = a JSON representation of the latest receipt
"receipt" = a JSON representation fo the receipt I sent for verification
The Docs say that the first 2 fields are
"Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions."
- Why are they showing up here, since I was validating an iOS 7 style app receipt?
- If these fields aren't supposed to be present, how do I get the latest transaction information?
The wording in Apple's docs is ambiguous. Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions. This means the field is always present for iOS 7 receipts using appStoreReceiptURL
but only present for deprecated transaction style receipts that are for an auto-renewing subscription. i.e. they do not show up on iOS 6 transaction receipts if the purchase isn't a subscription.
You need to include "password" key in your JSON along with "receipt-data" when hit to validate the reciept and its value will be "shared secret key" that you can generate from itunes account. Refer third heading in this link for more detail. https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html
来源:https://stackoverflow.com/questions/35905357/iap-receipt-validation-for-ios