如何测试 SKPaymentTransactionStateDeferred?

Posted

技术标签:

【中文标题】如何测试 SKPaymentTransactionStateDeferred?【英文标题】:How to test SKPaymentTransactionStateDeferred? 【发布时间】:2014-08-26 16:23:25 【问题描述】:

ios 8 即将推出。我们有 Xcode beta 6 atm,但仍然找不到任何关于如何正确测试家庭共享的文档(或者我错过了什么?)。我的问题是如何正确设置沙盒与父/子?我试图让它在 beta 1 中顺利运行。

有什么提示吗?

更新:

Apple 开发者论坛上的两个相关故事:

    如何在 iTunes Connect 上创建儿童沙盒帐户?(https://devforums.apple.com/message/1030357#1030357) 在沙盒 (https://devforums.apple.com/message/1005569#1005569) 中测试“Ask to Buy”

【问题讨论】:

我做了一些研究,不幸的是我没有找到任何文档或方法来测试这个。 【参考方案1】:

我在这个话题上取得了一些进展,所以我想报告一下。另外,我发现了一个明显的错误,我已经向 Apple 报告了。

我所做的如下:

1) 在 iTunes Connect 中创建父测试(沙盒)帐户,并创建子测试帐户。这些实际上只是 iTunes Connect 中的两个测试帐户。称它们为 P 和 C 表示父母和孩子。

2) 使用这两个帐户,转到https://appleid.apple.com 并根据他们的年龄更改他们的年份。 iTunes Connect 不允许您这样做。出于某种原因,除非年龄确实有一年,否则家庭共享的过程不起作用。我发现您必须在https://appleid.apple.com 的年度列表中进行两次选择。奇怪的。我将我的 P 设置为大一点(一些成年人的年龄),我的 C 设置为年轻。

3) 在一台苹果设备(我的 iPhone,运行 iOS8)上,我在设置 > iCloud 下为 P 帐户设置家庭共享。我已使用我的真实 iTunes Apple ID(其中包含我的付款信息)在此设备上登录 iTunes。

4) 然后我邀请我的 C apple id 加入我的家庭,在设置 > iCloud 下。

5) 我接受了来自 P 的邀请(在我的 iPad 上,也运行 iOS8),这涉及在另一台设备上以 C 身份登录 iCloud。

6) 在我的 iPhone 上,我为 C 家庭成员打开了“Ask To Buy”。

现在,我已准备好在我的沙盒应用上尝试以 C 身份进行测试购买。在我的应用商店中完成常规流程后,我收到以下警报:

当我点击“询问”时,我会收到下一个提醒:

现在,我尝试了两种选择,分别购买。我尝试了“确定”选项,它应该向 P 帐户发送通知。我还没有在我的 P 帐户上收到这样的通知(仍然像在我的 iPad 上一样登录到 iCloud)。

我还在“孩子”的 iPad 上尝试了“亲自批准”选项。我使用 P 帐户,如果在下一个警报中输入:

在那之后我没有收到任何错误,所以看起来“亲自批准”有效,但我还没有将该购买转换为 SKPaymentTransactionStatePurchased 状态。所有延期购买仍在应用的支付队列中,每个都带有状态 SKPaymentTransactionStateDeferred。当我重新启动应用程序时,每次购买的状态(仍在队列中)都会延迟。

接下来,我想知道 C 的特定测试 iTunes 帐户是否有问题,所以我创建了第二个子帐户,将其命名为 C2,并尝试在我的 iPhone 上将其设置为 P 下的子帐户。但是,我在那里遇到了另一个问题。当我尝试接受邀请成为 P for C2 下的家庭成员时,我收到了警报(在 iPad 上):

对我来说,对 iCloud 帐户的这种限制不应该适用于测试帐户。这是我向 Apple 报告的明显错误。

因此,总而言之,我还没有 100% 确信我的 SKPaymentTransactionStateDeferred 实现正在运行。我们将看看 Apple 是否会回复我。

【讨论】:

您知道如果用户使用 Ask To Buy 多次购买产品会发生什么吗? iOS 会处理此案并报告购买已在等待批准吗?还是我必须检查产品批准是否已被延迟并禁用购买按钮? 我的另一个问题是:你应该在延迟状态进入时完成交易吗?我假设不是,但我找不到任何关于它的文档。 第一个问题,是的。您不需要禁用购买按钮。但我的采购观察员代表必须聪明。如果 所有 事务都被延迟,我推断委托方法不是由我的 UI 直接引起的。对于你的第二个问题。看来您永远不会完成这些交易。请参阅 WWDC 演讲 303。 不,没有更多的进展。我仍然不确定我的实现是否有效。我需要在生产版本中尝试它。 Apple 尚未就该错误报告作出任何回复。 当延期购买被拒绝时,你知道观察者收到的是哪个SKError吗?【参考方案2】:

从 iOS 8.3 开始,SKPayment 可以使用一个新标志:simulatesAskToBuyInSandbox

所以如果你需要测试你初始化的 SKPaymentTransactionStateDeferred 状态 新建SKMutablePayment 并设置simulatesAskToBuyInSandbox = YES

https://developer.apple.com/library/prerelease/ios/releasenotes/General/iOS83APIDiffs/frameworks/StoreKit.html

附言。警告:人们抱怨这个 API 不能正常工作(见 cmets)

【讨论】:

太棒了!过几天试试看:)! 我很高兴听到这个消息,直到看到 Apple 没有为这个新标志提供预期的行为!!您是否向 Apple 提交了有关此问题的错误报告?即,缺乏关于这个新属性的文档? 不幸的是,在 iOS 9.1 SDK 下对我不起作用。这是对question at Apple Dev Forum 的引用(还没有答案)。【参考方案3】:

iOS 9.2.1、Xcode 7.2.1、ARC 已启用

确认! simulatesAskToBuyInSandbox 属性不会导致支付队列观察者注册SKPaymentTransactionStateDeferred 状态。相反,它只处理付款,观察者注册SKPaymentTransactionStatePurchased 状态。

SKMutablePayment *payment = [SKMutablePayment
   paymentWithProduct:productUserRequested];

payment.simulatesAskToBuyInSandbox = true;
[[SKPaymentQueue defaultQueue] addPayment:payment];

我能够执行的唯一测试是在观察者注册SKPaymentTransactionStatePurchased 状态而不是我通常的方法并且不调用时调用我的延迟付款方法:

[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

这会将事务保留在应用程序上。终止,并使您能够测试未完成购买的用户(例如,在购买的最后阶段失去接收)和延迟购买。这是假设您的购买方法传递了一个延迟参数,如In App Purchasing Guide: Delivering Products 中的清单 4-2 响应交易状态所述。下面是这个方法的样子:

模拟挂起购买:

[self showTransactionAsInProgress:transaction deferred:NO];

模拟延迟:

[self showTransactionAsInProgress:transaction deferred:YES];

注意:在应用程序上。重启,Apple in app。如果您没有为凭证处理任何其他付款、卸载应用程序或在“设置”中退出“iTunes 和 App Store”,购买机制将要求您提供凭证。此外,如果您在此处点击“取消”,则交易不会失败,因为支付队列观察者将继续注册SKPaymentTransactionStatePurchased 状态。

2016 年 3 月 4 日更新:

我发现 Apple 提出的这个建议可能会很有帮助,这是一种执行我建议的好方法:

测试中断的事务

在您的事务队列观察器中设置断点 paymentQueue:updatedTransactions: 方法所以你可以控制它是否 交付产品。然后在测试中照常购买 环境,并使用断点暂时忽略 事务——例如,通过立即从方法返回 使用 LLDB 中的线程返回命令。

终止并重新启动您的应用。 Store Kit 调用 paymentQueue:updatedTransactions: 在启动后不久再次使用该方法; 这一次,让你的应用正常响应。验证您的应用 正确交付产品并完成交易。

希望这会有所帮助!干杯。

【讨论】:

【参考方案4】:

根据Chris Prince's answer创建子账号时,请确保将其“年龄”设置在13到18岁之间。如果将其设置为小于 13 岁,则无法验证其年龄(即使您将信用卡添加到您的 P 帐户)。如果它高于 18 - 启用“询问购买”的选项就消失了。花了几个小时试图找出我做错了什么。

另外,您需要通过 iTunes Connect 创建 C 帐户,而不是通过家庭共享屏幕中的“创建孩子的帐户”选项。

希望我能发表评论,但由于我没有 50 点声望点,我必须创建一个单独的答案。

【讨论】:

给予+1,因为当您使用沙盒帐户登录“iTunes”时,沙盒帐户几乎可以用于将来的测试。在 IAP 中使用它是可行的,因为 IAP 会“回退”到沙箱中,因此您在登录重试时会获得沙箱。【参考方案5】:

事实证明,沙盒环境似乎不支持父子关系,因此当@ChrisPrince 的回答中提到设置相关帐户时,不会发送消息。

我挖出来的文章可以在这里找到:https://forums.developer.apple.com/thread/38561#117143

从苹果工作人员的回答来看,sn-p的重要性是

关于 Ask-To-Buy 支持,沙盒中不支持此功能。 “Ask to Buy”不是 API 实现,而是由 iTunesConnect 实现的支持流程,需要 StoreKit 与特定 iTunes 帐户进行交互。这种支持只存在于生产环境中。要使此流程在沙盒环境中运行,ITC 需要为测试账户实施以引用其他账户来批准购买。

本文的其余部分重点介绍了“购买前询问”支持的指南和流程,但必须在子/父帐户关系处于活动状态的生产环境中进行测试。

【讨论】:

主要是因为这是一个较新的回复,并且与我最初的调查相吻合,添加了 +1,这也与@Raimundas 的答案相吻合【参考方案6】:

从 Xcode 12 开始,有一种模拟应用内购买的方法可以让您获得更多控制权。您可以在 Xcode 中完全设置 IAP,而无需访问 App Store Connect。而且您可以管理它们,而不是创建多个沙盒帐户并一遍又一遍地重新开始。这对于测试延迟事务状态非常有帮助。

创建模拟应用内购买

    通过转到文件 > 新文件 > StoreKit 配置文件添加一个新的 .storekit 文件 单击添加按钮并选择您需要的应​​用内购买类型 为您的 IAP 提供名称、产品 ID、价格等。

将您的应用指向新的模拟应用内购买

    选择您应用的方案并单击编辑方案 在运行下,选择选项选项卡。在 StoreKit Configuration 下,选择您刚刚创建的 .storekit 文件。这会将您的应用程序指向您的 .storekit 文件而不是 Apple 服务器

查看/管理您的交易

    运行您的应用程序并在 Xcode 中导航到 Debug > StoreKit > Manage Transactions 在您的应用中完成您的交易 观察您的事务现在在 Xcode 的 StoreKit 调试窗口中可见

测试延迟交易

    选择您的 .storekit 文件,然后单击编辑器 > 启用询问购买

    您的代码中可能有这样的内容:

    SKPaymentQueue.default().add(SKPayment(product: skProduct))
    

注释掉并添加它:

let mutablePayment = SKMutablePayment(product: skProduct)
mutablePayment.simulatesAskToBuyInSandbox = true
SKPaymentQueue.default().add(mutablePayment)

    构建应用并再次完成交易。您现在应该看到“询问权限”提示

    请求许可后,您可以通过选择该交易并单击“批准”或“拒绝”按钮来批准或拒绝该交易

【讨论】:

以上是关于如何测试 SKPaymentTransactionStateDeferred?的主要内容,如果未能解决你的问题,请参考以下文章

从 SKPaymentTransaction 获取订阅价格

我是不是必须验证每个 SKPaymentTransaction 订阅的收据?

SKPaymentTransaction(Swift 3)中的交易错误转换问题

应用内购买验证收据错误

如何使用 AppStoreReceiptUrl 在 Xamarin.iOS 中验证 StoreKit 交易

应用购买iphone中的自动续订验证