21

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

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

现在的问题是苹果一直拒绝该应用程序,说我正在调用他们的生产服务器而不是沙盒服务器。但是根据我从 Receipt Validation Programming Guide 中了解的内容,只有在您使用第二种验证方法并通过您自己的安全服务器将数据发送到 Apple 时才有效。但是,我在本地做所有事情,并且对如何区分生产环境和沙盒环境以使我的应用程序可以通过审核感到非常困惑。

任何指示或建议都会非常有帮助。

4

5 回答 5

13

好吧,这对我有用,经过近一个月的多轮审查上诉和重新提交,Apple 昨晚批准了该应用程序。

请勿在应用启动时尝试刷新收据,也不要阻止 UI。我所做的是在找到收据之前在启动时不显示任何 UI,因此当在启动时提示输入 iTunes 密码时,按取消将显示应用程序的受限版本,输入正确的密码将尝试下载新的收据并采取行动根据是否找到一个。

因此,在启动时,如果您发现收据很好,如果没有,请不要尝试刷新它。

但是,当用户按下恢复购买选项时,请刷新它。

希望这可以帮助。

于 2014-05-06T08:55:00.270 回答
5

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

我相信你做的一切都是正确的,老实说,Apple 对自己的指导方针感到困惑。毕竟,在 Receipt Validation Programming Guide 中,他们明确建议:“如果 iOS 中的验证失败,请使用 SKReceiptRefreshRequest 类来刷新收据”并且无法影响此调用的服务器(SKReceiptRefreshRequest 参考

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

于 2014-05-02T13:34:13.767 回答
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 与 Distribution 之间的区别。
  2. 当您使用从 iTunes Connect 创建的测试 iTunes 用户帐户进行购买时,您必须在沙箱服务器下对其进行测试。在代码签名身份的发布下,您应该选择Ad-Hoc provisioning而不是分发配置
  3. 但是,当您想发布到应用商店时,您必须选择分发配置以及生产服务器(ITMS_PROD_VERIFY_RECEIPT_URL)。您不能在此服务器上使用测试用户帐户。您必须使用真实的 iTune 用户帐户购买(在 Apple 批准后)才能进行真正的购买。

要了解如何在本地实施 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。

于 2014-05-05T05:47:20.907 回答
1

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

因此,如果收据不存在,则不如在开始时要求 psw 因为用户混淆了 bcs,他只是启动应用程序并且它无缘无故地询问)提供恢复 btn,您必须提供任何方式和w8,直到您收到收据,您可以合理地改变。

因此,将您的刷新代码放入 if 语句中:

if([[NSFileManager defaultManager] fileExistsAtPath:[[[NSBundle mainBundle] appStoreReceiptURL] path]] == YES) {

        self.receiptRefreshRequest = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];
        self.receiptRefreshRequest.delegate = self;
        [self.receiptRefreshRequest start];
}
于 2015-03-21T20:57:35.970 回答
0

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

似乎[[SKPaymentQueue defaultQueue] restoreCompletedTransactions]也默默地刷新了应用程序收据而不弹出对话框。意思是,在事务恢复后,请求 appReceiptURL + Data 返回一个非零值。这只是来自我的少量测试。请做你自己的测试。

于 2015-01-14T21:12:11.900 回答