如何使用单个 appStoreReceiptURL 验证多个 StoreKit 交易?

How to use a single appStoreReceiptURL to verify multiple StoreKit transactions?

我们正在使用服务器端验证来验证我们的 iTunes 应用程序购买。当交易发送到 SKPaymentTransactionObserver 时,我们从 appStoreReceiptURL 获取收据以验证它。

if let receiptPath = NSBundle.mainBundle().appStoreReceiptURL?.path where
    NSFileManager.defaultManager().fileExistsAtPath(receiptPath),
    let receiptData = NSData(contentsOfURL:NSBundle.mainBundle().appStoreReceiptURL!) {
    return receiptData
}

但在某些情况下,比如我们在恢复购买时,会收到多个交易到方法:

public func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction])

使用相同的收据数据来验证每笔交易似乎很奇怪。单张收据是否包含每笔交易的数据?

Does the single receipt contain data about each transaction?

是的。从 appStoreReceiptURL 访问的收据是用户和应用程序所有持久交易的单一收据。

Docs on In-app purchase receipt

The in-app purchase receipt for a consumable product is added to the receipt when the purchase is made. It is kept in the receipt until your app finishes that transaction. After that point, it is removed from the receipt the next time the receipt is updated—for example, when the user makes another purchase or if your app explicitly refreshes the receipt.

The in-app purchase receipt for a non-consumable product, auto-renewable subscription, non-renewing subscription, or free subscription remains in the receipt indefinitely.

即所有 in-app 次购买,包括订阅续订和恢复的购买,不包括已消费的购买,都会创建一个新交易并存储在收据中。

Docs on Working with Subscriptions:

After a subscription is successfully renewed, Store Kit adds a transaction for the renewal to the transaction queue. Your app checks the transaction queue on launch and handles the renewal the same way as any other transaction.

Docs on Restoring Purchased Products:

Restoring completed transactions creates a new transaction for every completed transaction the user made.

请注意,original transaction id 对于恢复的购买和续订是相同的。

收据本质上是一个存储在设备上的文件,每当添加新交易时应用都会更新该文件。