[英]iOS 7 Local (on device) Receipt Validation and In-App Purchases Check
我已经在Apple的Receipt Validation Programming Guide的帮助下使用OpenSSL和asn1c编译器在设备上本地实现了收据验证。 我的应用程序仅支持iOS 7及更高版本。
根据Apple的推荐,我打电话给[[NSBundle mainBundle] appStoreReceiptURL]
获取应用商店收据。 当应用程序在显示任何UI之前“首次”启动时,我也会执行此操作。 首次启动呼叫是必需的,因为如果第一次尝试不在那里,Apple建议刷新收据。 作为此调用的结果( SKReceiptRefreshRequest
),应用程序要求用户输入其iTunes登录信息。
现在问题是Apple一直拒绝该应用程序说我正在调用他们的生产服务器而不是沙盒服务器。 但根据我对“收据验证编程指南”的理解,只有使用第二种验证方法并通过您自己的安全服务器向Apple发送数据时才有效。 然而,我在本地做所有事情,并且对于如何区分生产环境和沙盒环境非常困惑,以便我的应用程序可以通过审核。
任何指针或建议都会非常有用。
好的,这就是对我有用的东西,苹果公司在经过多轮审查上诉和重新提交的申请后,昨晚批准了该应用程序,这个申请已经持续了近一个月。
在应用启动时不要尝试刷新收据,也不要阻止用户界面。 我所做的是在发现收据之前没有显示任何UI,所以当在启动时提示输入iTunes密码时,取消将显示应用程序的限制版本,输入正确的密码将尝试下载新收据并采取行动根据是否找到一个。
所以在发布时如果您发现收据很好,如果没有,请不要尝试刷新它。
但是,当用户按下Restore Purchases选项时,请刷新它。
希望这可以帮助。
我删除了之前的回复,我误解了这个问题。
老实说,我相信你做的一切都是正确的,而苹果对自己的指导方针感到困惑。 毕竟,在“收据验证编程指南”中,他们清楚地建议:“如果在iOS中验证失败,请使用SKReceiptRefreshRequest类刷新收据”,并且无法影响此调用的服务器( SKReceiptRefreshRequest参考 )
根据http://asciiwwdc.com/2013/sessions/308 ,调用什么服务器取决于应用程序的签名方式,显然需要在提交时签名生产。
生产环境和沙箱环境之间的区别取决于您调用的链接。
#define ITMS_PROD_VERIFY_RECEIPT_URL @"https://buy.itunes.apple.com/verifyReceipt"
#define ITMS_SANDBOX_VERIFY_RECEIPT_URL @"https://sandbox.itunes.apple.com/verifyReceipt";
ITMS_PROD_VERIFY_RECEIPT_URL是生产服务器。 ITMS_SANDBOX_VERIFY_RECEIPT_URL是沙盒服务器。
要了解如何在本地实施IAP并在本地验证收据,请学习: - 1. http://www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios-6-tutorial
您可以在此处下载完成的示例项目: - 3. http://cdn1.raywenderlich.com/downloads/InAppRagePart2Finished.zip
注意:可能有另一种方法来验证我不知道的收据。
我找到了一些可能有用的东西: - 1. https://developer.apple.com/library/ios/documentation/StoreKit/Reference/SKReceiptRefreshRequest_ClassRef/SKReceiptRefreshRequest_ClassRef.pdf
- (id)initWithReceiptProperties:(NSDictionary *)properties
它说“在生产环境中,将此参数设置为nil。” 属性在测试环境中,新收据应具有的属性。 有关键,请参阅“收据属性”(第4页)。 在生产环境中,将此参数设置为nil。
如果收据无效或不存在,则显示输入用户psw的对话框。
因此, 而不是在一开始索要PSW如果收到不存在(用户是混乱的BCS他刚刚推出的应用程序,它要求毫无理由地) 提供恢复BTN你必须ANYWAY提供和W8,直到你得到收据,你可以合理地变化。
所以将刷新代码放入if语句中:
if([[NSFileManager defaultManager] fileExistsAtPath:[[[NSBundle mainBundle] appStoreReceiptURL] path]] == YES) {
self.receiptRefreshRequest = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];
self.receiptRefreshRequest.delegate = self;
[self.receiptRefreshRequest start];
}
我想分享一下我的经历。 删除应用程序后,我一直在使用Sandbox和应用程序收据丢失。 (然后重新命令-R-ing)我不知道这是否在生产中发生,但听起来好像它确实如此。 在第一次应用程序启动时要求刷新,并提示用户输入密码令人吃惊。 当然,这是一个问题。
似乎[[SKPaymentQueue defaultQueue] restoreCompletedTransactions]
也会在不弹出对话框的情况下静默刷新应用收据。 意思是,在事务恢复后,要求appReceiptURL + Data返回一个非零值。 这只是我的短期测试。 请自己做测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.