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

Posted

技术标签:

【中文标题】iOS 7 本地(设备上)收据验证和应用内购买检查【英文标题】:iOS 7 Local (on device) Receipt Validation and In-App Purchases Check 【发布时间】:2014-06-13 10:20:33 【问题描述】:

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

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

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

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

【问题讨论】:

这没有意义。为什么 Apple 会抱怨您提交审核的应用程序正在使用生产服务器?为什么他们会说将沙盒服务器用于生产应用程序? 我不认为我被允许在外部发布 Apple 的解决中心消息,否则我会在这里发布。 只是好奇:在调用刷新之后,我假设它失败了,之后你在你的应用程序中做了什么?通读devforums,似乎只有在验证失败时阻止审阅者继续使用例如进行 IAP 购买。 如果失败,例如用户在 iTunes 登录提示上按下取消,只需加载应用程序的基本免费版本。没有阻塞或任何东西。 Anuj,你和 Apple 解决了这个问题了吗? 【参考方案1】:

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

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

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

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

希望这会有所帮助。

【讨论】:

如果你提到原因,那些一直拒绝投票的人会很有帮助。 这是事实。如果收据无效或不存在,则会显示输入用户密码的对话框。因此,然后在开始时要求 psw (因为用户很困惑,因为他只是启动应用程序并且它无缘无故地询问)提供恢复 btn,您必须提供 ANYWAY 和 w8 直到用户按下它。【参考方案2】:

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

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

根据http://asciiwwdc.com/2013/sessions/308,调用什么服务器取决于应用程序是如何签名的,显然需要在提交时签名才能生产。

【讨论】:

【参考方案3】:

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

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

    确保从 Apple 配置门户创建正确的配置证书。了解 Ad-Hoc 与 Distribution 之间的区别。 当您使用从 iTunes Connect 创建的测试 iTunes 用户帐户进行购买时,您必须在 沙盒服务器 下对其进行测试。在代码签名身份Release下,您应该选择Ad-Hoc provisioning而不是distribution provisioning。 但是当您想发布到应用商店时,您必须选择分发配置以及生产服务器 (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。

【讨论】:

不,这不是问题所在,当您使用 Apple 的服务器进行收据验证和应用购买解析时,这些内容适用。在本地,完全在设备上进行操作时,无法判断您是在沙盒环境中还是在生产环境中。 你能给我看看验证收据的代码吗?据我所知,有两种方法可以验证收据。 1. 在设备上本地验证,是的,我们使用设备调用收据验证 URL,如上所述。 2. 在服务器上验证。服务器将验证收据并将参数传递回设备。这两种方法我都做过。如果你想在本地验证,你可以按照这个很好的教程:raywenderlich.com/21081/…我以前在第一次学习在移动端(本地)验证收据时有时使用过。 学完第一个教程,学这个raywenderlich.com/23266/… 找到一个可能有帮助的链接:developer.apple.com/library/ios/documentation/StoreKit/… properties 在测试环境中,新收据应该具有的属性。有关密钥,请参阅“收据属性”(第 4 页)。在生产环境中,将此参数设置为nil。 @voyage11,当我们谈论在本地验证收据时,没有我们可以调用的 URL。我们只使用 SKReceiptRefreshRequest。因此,您对如何进行本地收据验证的理解与提问者不同。【参考方案4】:

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

所以相当如果收据不存在,则在开始时要求 psw (因为用户感到困惑,因为他只是启动应用程序并且它无缘无故地询问) 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];

【讨论】:

【参考方案5】:

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

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

【讨论】:

以上是关于iOS 7 本地(设备上)收据验证和应用内购买检查的主要内容,如果未能解决你的问题,请参考以下文章

iOS 7:应用内购买收据验证和验证

验证应用商店收据:本地与服务器

iOS:React Native:应用内购买:收据验证

iOS8 In App Purchase收据验证

从 iOS 应用内购买收据中检索订单 ID/文件编号

IOS应用内购买验证或数据检索