何时使用restoreCompletedTransactions进行应用内购买恢复?

51

对于一个只有非消耗性内购的基本应用程序,有人想出了使用SKPaymentQueue的 restoreCompletedTransactions 的最佳实践吗?

观察

我知道注册交易观察器以接收待处理事务总是被推荐的,但这是一个不同的问题。看起来restoreCompletedTransactions是应用程序必须主动决定何时调用以轮询客户已经完成的所有购买。

据我所知,该方法旨在检索可能丢失的购买记录。例如,客户可能会以某种方式安装或将应用程序移动到新设备上,在这种情况下,应用程序对先前付款的本地记录可能会丢失或重置。

担忧

对我而言,不清楚如何以可靠的方式自动检测此情况(即如何决定何时轮询缺失购买),我不想搞砸并冒险拒绝客户访问他们已经支付的功能。

同时,我也不想每次启动应用程序时都调用restoreCompletedTransactions以确保安全,因为99.9%的时间我已经知道它们的事务。(除了应用内购买,我的应用程序不需要任何网络连接。)

注释

Apple文档澄清,客户不会再次为他们已经完成的任何非消耗性购买支付费用。如果他们尝试重新购买,则仍然向应用程序发送付款事务。

最坏的情况是,客户可以通过这种方式恢复购买记录,但我仍然希望避免让他们沿着类似于重新购买已经支付的东西的道路走下去。


9
我现在也在为同样的问题苦恼。我认为问题出在用户界面(UI)上,立即调用restoreCompletedTransactions会要求用户输入iTunes密码,这对于初次启动应用程序的人来说是非常令人困惑的,特别是对于那些尚未购买升级的人来说。我考虑过在商店视图控制器显示时进行检查,但它会立即提示输入密码,这会让第一次购买者感到非常不舒服。 - Dave Verwer
2
是的,我的想法和你一样。我真的不想在用户第一次运行应用程序或进入商店页面时自动提示他们输入帐户密码。最后,我选择了一个“恢复购买”按钮,这似乎很有效。到目前为止,我没有收到任何关于此的客户投诉或困惑。 - otto
3个回答

37

更新(2022年6月)

苹果公司已经给这个主题起了一个名字,并专门进行了整个 WWDC 会议的演讲。

(如果链接最终失效了,那就是指的 2022 年 WWDC 的第 110404 场次。)

该会议为期20分钟,涵盖了大量内容,强烈推荐观看。有很多细节需要处理,但我会提供两个亮点。

  • 在首次启动全新安装的应用程序时,可以 自动 账户预先存在的购买,而无需提示用户进行 Apple ID 登录或确认。(restoreCompletedTransactions 不用于此。)
  • 苹果仍然需要一个“恢复购买”按钮,用户可以回退并使用它。

您的应用程序唯一需要调用 restoreCompletedTransactions 的时间是当用户点击“恢复购买”按钮时。(自从本文发布以来,这基本上一直是我们的建议。)


之前的答案(2019年6月)

苹果公司有关此主题的文档已于2018年更新,内容非常全面。它的许多建议与我们在这里得出的结论一致。自2009年首次发布该问题以来最大的发展是iOS 7中的应用商店收据。

如果链接在未来的某个时间失效了,我将在此引用部分文档。

恢复已购买的产品

用户恢复交易以保持对其已经购买内容的访问权限。例如,当他们升级到新手机时,他们不会失去在旧手机上购买的所有物品。在您的应用程序中包含某些机制,以便让用户恢复其购买,例如“恢复购买”按钮。恢复购买会提示用户提供 App Store 凭据,这会打断您的应用程序的流程:因此,请不要自动恢复购买,特别是不要在每次启动应用程序时都这样做。

在大多数情况下,您的应用程序只需要刷新其收据并提供其中的产品即可。更新后的收据包含了用户在此应用程序、此设备或任何其他设备上购买的记录。但是,某些应用程序需要采取其他方法,原因如下:

  • 如果您使用 Apple 托管的内容,则恢复完成的交易会为您的应用程序提供用于下载内容的交易对象。
  • 如果您需要支持早于 iOS 7 的 iOS 版本,其中应用程序收据不可用,请改为恢复已完成的交易。
  • 如果您的应用程序使用非续订订阅,则您的应用程序负责恢复过程。

刷新收据会向 App Store 请求最新的收据副本。刷新收据不会创建任何新的交易。虽然您应避免连续刷新多次,但此操作将产生与仅刷新一次相同的结果。

恢复完成的交易会为用户完成的每笔交易创建一个新的交易,从而重新播放事务队列观察器的历史记录。在正在恢复交易时,您的应用程序会保持自己的状态,以跟踪它正在恢复已完成的交易的原因以及如何处理它们。多次恢复将为每个已完成的交易创建多个已恢复的交易。

一个选项是在用户默认设置中记录是否已经调用并成功完成了restoreCompletedTransactions。如果没有,则应用程序在启动时调用它一次。由于这个标志可以存储在与非消耗性支付相同的位置,如果用户默认设置稍后被清除,那么当应用程序启动时会再次调用恢复方法。

这样,如果现有客户以某种方式进行了应用程序的全新安装,他们仍然会自动恢复其购买。如果他们是从未启动过应用程序的新客户,则恢复操作将不返回任何内容。

无论哪种情况,restoreCompletedTransactions只会在第一次启动时调用,而不是在每次启动时调用。

手动(推荐)

另一个选项是在某个地方提供一个“恢复购买”按钮给客户使用,将其连接到restoreCompletedTransactions,并让他们决定是否以及何时需要恢复购买。

(下面的评论解释了为什么手动恢复比尝试自动恢复更好。)


启动时检查标记并自动恢复的处理方式非常巧妙。我最终采用了一个按钮来实现,Ramp Champ也是如此。但是当进行购买时,这两个应用程序都会下载大型文件。 - Carl Coryell-Martin
12
是的,我又倾向于加上一个恢复按钮。对于自动恢复,我忘记了一个显而易见的问题 - 用户可能会被提示输入他们的账户密码。这是我最不想在用户第一次运行应用程序时强制要求他们做的事情。 - otto
1
按钮是我认为最好的选择。我看到的每个应用程序都在使用它。 - ySgPjx
3
我认为这个情况最近有所改变。在早期版本的iOS中,用于下载应用的登录名和密码会持续15分钟。也就是说,在下载应用后的15分钟内首次运行该应用程序将允许restoreCompletedTransactions调用而无需任何提示。由于这种功能的滥用,Apple已经改变了其行为,现在总是需要单独身份验证才能进行应用内购买(这也是您看到的情况)。基于这种新方法,我看不到在没有提示的情况下自动调用restoreCompletedTransactions的方法。 - chris
3
我的一个应用因为没有“恢复购买”按钮而被拒绝了。我认为这个按钮必须一开始就存在。 - badweasel
显示剩余2条评论

16
不要忘记一个Apple ID可以跨多个设备使用。因此在一个设备(比如用户的iPhone)上维护一个标志,告诉你是否已经恢复过一次,是无法检测到客户在另一个设备(比如他的iPad)上进行了购买并需要被恢复到iPhone上的情况的。因此,即使您有自动方法,手动启动还是必要的。
更糟糕的是,我还没有弄清楚当IAP退款时您会收到哪些通知。我猜想恢复过程将简单地返回未退款交易的列表。因此,a)在进行恢复时,需要删除记录的用户IAP,以防退款产品在恢复期间未被报告,b)需要定期自动执行恢复,以便获取退款。
所有这些都凸显了Apple IAP的问题-它设计不佳且文档不足-现在对于像电子书读者这样已经拥有完全运作良好的基于Web的商店的应用程序来说,它是必须的。 (例如Kindle)。

3
这是一个很好的观点,也许这就是为什么非消耗品必须有“恢复购买”按钮,否则将被应用商店拒绝。 - Reuben Scratton

5

每当您有一个非消耗性应用内购买,例如新的赛车赛道时,您需要在应用程序中实现一个“恢复”按钮,以便用户可以在更改设备或删除应用程序后恢复其购买。这是强制性的,我曾经因为没有实现“恢复”按钮而被苹果拒绝过一次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接