iOS 7本地(在设备上)收据验证和应用内购买检查

时间:2014-04-28 02:09:17

标签: ios objective-c receipt receipt-validation

我已经在Apple的本地收据验证编程指南的帮助下使用OpenSSL和asn1c编译器在设备上本地实现了收据验证。我的应用程序仅支持iOS 7及更高版本。

根据Apple的建议,我致电[[NSBundle mainBundle] appStoreReceiptURL]以获取应用商店收据。当应用程序“第一个”时,我也会这样做。在显示任何UI之前启动。首次启动呼叫是必需的,因为如果第一次尝试不在那里,Apple建议刷新收据。作为此次通话的结果(SKReceiptRefreshRequest),该应用会要求用户输入其iTunes登录信息。

现在的问题是Apple一直拒绝该应用说我正在调用他们的生产服务器而不是沙箱服务器。但根据我对“收据验证编程指南”的理解,只有使用第二种验证方法并通过您自己的安全服务器向Apple发送数据时才有效。然而,我在本地做所有事情,并且对于如何区分生产环境和沙盒环境非常困惑,以便我的应用程序可以通过审核。

任何指针或建议都会非常有用。

5 个答案:

答案 0 :(得分:13)

好的,所以这就是对我有用的东西,苹果公司在经过多轮评审上诉和重新提交一整个月后,昨晚批准了该应用程序。

在应用启动时不要尝试刷新收据,也不要阻止用户界面。我所做的是在发现收据之前没有显示任何UI,所以当在启动时提示输入iTunes密码时,取消将显示应用程序的限制版本,输入正确的密码将尝试下载新收据并采取行动根据是否找到了一个。

所以在发布时如果你发现收据很好,如果没有,请不要尝试刷新它。

当用户按下Restore Purchases选项时,请刷新它。

希望这会有所帮助。

答案 1 :(得分:5)

我删除了之前的回复,我误解了这个问题。

我相信你做的一切都是正确的,老实说,Apple对自己的指导方针感到困惑。毕竟,在“收据验证编程指南”中,他们明确指出:"如果在iOS中验证失败,请使用SKReceiptRefreshRequest类刷新收据"并且没有办法影响这个调用的服务器(SKReceiptRefreshRequest reference

根据http://asciiwwdc.com/2013/sessions/308,调用哪个服务器取决于应用程序的签名方式,显然需要在提交时签名生产。

答案 2 :(得分:4)

生产环境和沙箱环境之间的区别取决于您调用的链接。

#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是沙盒服务器。

  1. 确保从Apple配置门户创建正确的配置证书。了解Ad-Hoc与分布之间的区别。
  2. 当您使用从iTunes Connect创建的Test iTunes用户帐户购买时,您必须在沙盒服务器下进行测试。在代码签名身份发布下,您应选择 Ad-Hoc配置,而不是分配配置
  3. 但是,当您要发布到应用商店时,您必须选择分发配置以及生产服务器(ITMS_PROD_VERIFY_RECEIPT_URL)。您无法在此服务器上使用测试用户帐户。您将不得不使用真实的iTune用户帐户购买它(在Apple批准之后)进行真正的购买。
  4. 要了解如何在本地实施IAP并在本地验证收据,请了解: - 1。http://www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios-6-tutorial

    2。http://www.raywenderlich.com/23266/in-app-purchases-in-ios-6-tutorial-consumables-and-receipt-validation

    您可以在此处下载已完成的示例项目: - 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。

答案 3 :(得分:1)

如果收据无效或不存在,则会显示输入用户psw的对话框。

所以 RATHER 然后在开头询问psw如果收据不存在(因为用户混淆了bcs他只是启动应用程序并且它没有理由请求) < strong> PROVIDE 恢复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];
}

答案 4 :(得分:0)

我想分享一下我的经验。删除应用程序后,我一直在使用Sandbox和应用程序收据丢失。 (然后重新命令-R-ing)我不知道这是否在生产中发生,但听起来好像它确实如此。在第一次应用程序启动时要求刷新,并提示用户输入密码令人吃惊。当然,这是一个问题。

似乎[[SKPaymentQueue defaultQueue] restoreCompletedTransactions]也会在没有弹出对话框的情况下静默刷新应用收据。意思是,在事务恢复后,要求appReceiptURL + Data返回一个非零值。这只是我的短期测试。请自己进行测试。