这个问题涉及自动可再生IAP以及如何恢复它们 . 这些链接:this和this不幸地帮助了我 .
在我的应用程序中,我有用户订阅 Auto-Renewable In-App Purchases . 他们可以订阅1个月,6个月或12个月 .
订阅时,交易收据将发送到我的服务器以进行 later 验证 . 我 do not 立即验证收据,因为它会减慢用户体验(苹果服务器的收据验证查询对我来说需要大约1-2秒) . 相反,我使用 naive approach 并提供用户订阅的内容,而不进行任何直接收据验证 . 我安排了一个cron作业,每天验证每个用户的收据,并撤销过期收据的权限 .
既然苹果指南明确指出具有自动续订订阅的应用程序需要恢复功能,我选择实现它 .
当我尝试在沙盒模式下恢复购买时,使用:
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
我不仅获得当前订阅,还获得回调中所有先前订阅(包括过时订阅):
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
目前我已经尝试了大约30次IAP,这意味着上面的方法发送了30个不同的事务(过时和活动) . 对于这些交易中的每一个,我都将交易收据上传到我的Web服务以供以后验证 .
现在 . 如果最后一个事务具有过时的收据(但倒数第二个事务实际上是有效的),它将覆盖当前用户的当前(有效)收据,从而错误地撤销用户的权限 .
基本上我的问题是,当调用 restoreCompletedTransactions
时,我获得了过时和活动事务的列表 . 在服务器端,它们可能会互相失效 . 最理想的情况是,我只想检索一个事务(最相关)并将该收据发送到我的服务器以供以后验证 .
总而言之,我想我的主要问题是:
如何确保只恢复活动(即最新)的事务?
3 回答
我的解决方案:检索收据并根据您的productIdentifiers对其进行验证 . 使用
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
进行自动续订订阅没有意义,因为:需要太长时间,因为它会导致收据验证被调用太多次(过去每次交易一次)
可能导致后续失败的事务覆盖有效的事务验证
例如,如果您的自动续订订阅有三个持续时间,则只需针对与三个订阅持续时间关联的三个productIdentifier验证收据 .
我相信您必须处理收据并查看收据中每次购买的"Original Purchase Date and Subscription Expiration Date"(https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Subscriptions.html),以查看特定购买是否仍然有效 . 您可以使用服务器处理收据,并使用Apple进行验证以获取收据的JSON . 或者,如果您使用的是iOS7,则可以验证设备上的收据,并获取JSON(例如,请参阅A complete solution to LOCALLY validate an in-app receipts and bundle receipts on iOS 7) . 如果您使用的是iOS7,您将获得一张收据,其中包含所有购买内容:
[[NSBundle mainBundle] appStoreReceiptURL]
通过使用 KeyChains 使用 uniqueID ,我们可以存储
receipt
.通过验证
receipt
购买product
.