IAP receipt validation for iOS

痞子三分冷 提交于 2019-12-07 14:49:25

问题


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.

https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW1

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."

  1. Why are they showing up here, since I was validating an iOS 7 style app receipt?
  2. If these fields aren't supposed to be present, how do I get the latest transaction information?

回答1:


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.




回答2:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!