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

我已经在设备上使用OpenSSL和asn1c编译器在本地实现了接收validation,并且使用了“Apple收据validation编程指南”的帮助。 我的应用程序只支持iOS 7及以上。

正如苹果推荐的,我打电话给[[NSBundle mainBundle] appStoreReceiptURL]来获取app store收据。 在显示任何用户界面之前,应用程序“首次”启动时,我也会这样做。 如果苹果公司build议在第一次尝试的时候不需要刷新收据,则需要首次启动电话。 由于这个调用( SKReceiptRefreshRequest ),应用程序要求用户input他们的iTuneslogin信息。

现在的问题是苹果不断拒绝的应用程序说,我打电话给他们的生产服务器,而不是沙箱服务器。 但根据“收据validation编程指南”中的理解,只有在使用第二种validation方法并通过您自己的安全服务器将数据发送给Apple时,才是有效的。 然而,我在本地做所有事情,对于如何区分生产环境和沙箱环境非常困惑,所以我的应用程序可能会通过审查。

任何指针或build议将是非常有益的。

好的,这里是我的工作,经过多个审查上诉和重新提交跨越了近一个月,苹果昨晚批准了应用程序。

当应用程序启动时不要尝试刷新收据,也不要阻止用户界面。 我正在做的是没有显示任何用户界面启动,直到find一个收据,所以当启动时提示iTunes密码按取消将显示应用程序的有限版本,input一个正确的密码将尝试下载一个新的收据和行为根据是否被find。

所以,如果您发现收据很好,那么请不要尝试刷新它。

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

希望这可以帮助。

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

我相信你做的一切都是对的,说实话,苹果对自己的指导方针感到困惑。 毕竟,在“收据validation编程指南”中,他们明确地build议:“如果iOS中的validation失败,则使用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是沙箱服务器。

  1. 确保您从Appleconfiguration门户创build了正确的configuration证书。 了解Ad-Hoc与分布之间的区别。
  2. 当您使用从iTunes Connect创build的testingiTunes用户帐户购买时,您必须在沙箱服务器下进行testing。 在“ 代码签名标识发布之后,您应该select即席configuration,而不是分配configuration
  3. 但是,当您想要发布到app store时,您必须select分发configuration以及生产服务器 (ITMS_PROD_VERIFY_RECEIPT_URL)。 您不能在此服务器上使用testing用户帐户。 您将不得不使用一个真正的iTune用户帐户来购买(在苹果批准之后)才能真正购买。

要了解如何在本地实施IAP并在本地validation收据,请参阅: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

注意:可能有另一种validation收据的方式,我不知道。

我发现了一些可能有用的东西: – 1. https://developer.apple.com/library/ios/documentation/StoreKit/Reference/SKReceiptRefreshRequest_ClassRef/SKReceiptRefreshRequest_ClassRef.pdf

 - (id)initWithReceiptProperties:(NSDictionary *)properties 

它说:“在生产环境中,将此参数设置为零。” 属性在testing环境中,新收据应具有的属性。 有关按键,请参阅“收据属性”(第4页)。 在生产环境中,将此参数设置为nil。

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

因此,如果收据不存在,那么RATHER会在开始时询问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]; } 

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

看起来好像[[SKPaymentQueue defaultQueue] restoreCompletedTransactions]也默默地刷新应用程序收据而不popup对话框。 意思是,在事务恢复后,请求appReceiptURL + Data返回一个非零值。 这只是我的短期testing。 请做你自己的testing。