在StoreKit/应用内购买中区分初始购买和免费“重新购买”

4

从StoreKit指南中可以得到以下信息:

如果用户尝试购买他们已经购买过的非消耗品或可续订订阅,您的应用将会收到一笔常规交易而不是恢复交易。但是,用户不会再次被收费。您的应用程序应该像处理原始交易一样处理这些交易。

这在我正在开发的应用中带来了一个巨大的问题。我们已经从出版商那里获得了大量内容许可,以通过应用内购买进行销售。他们要求我们每次销售这些内容(即用户向我们付款)时,我们的服务器都必须调用他们服务器上的API来报告交易。这是为了会计目的,并最终用于确定我们在月底向他们支付多少款项,根据我们与他们的协议。

我已经读到了一些关于频繁调用restoreCompletedTransactions并在设备上维护对用户已经购买的内容的本地理解的建议,以便不能让他们再次购买。对我来说,这似乎应该能够在服务器端实现。然而,我们从Apple服务器收到的收据对于购买和重新购买确实是完全相同的,就像StoreKit指南所承诺的那样。

如果无法信任StoreKit的付款回调作为这种情况下的有效会计机制("您已经付款"与"您没有付款"),那么还有哪些实时交易流量洞察可用?我认为,我们正在与之合作的出版商如果告诉他们我们必须在月底之后等待45天才能从iTunes Connect中获得真正的付款金额,他们是不会高兴的。


相关(相同意图,但从何时使用恢复的角度来看待):https://dev59.com/AnHYa4cB1Zd3GeqPHhtM - Johannes Rudolph
3个回答

6

我最近研究了同样的问题。在我的情况下,我想要使用Mobile App Tracking来跟踪不同客户获取活动生成的准确收入。

幸运的是,有一种方法可以实现。需要注意的是,SKPaymentTransactionStatePurchasedSKPaymentTransactionStateRestored仅取决于初始操作,例如您发起还原或(重新)购买,所以这并不管用。

相反,有效的方法是检查SKPaymentTransaction.originalTransaction,对于恢复和重新购买,将会同时为!= nil。后者是未定义的行为(文档)。虽然我认为进行空值检查就足够了。

另一种选择是验证具有SKPaymentTransactionStatePurchased的交易收据,并检查返回的已验证收据中的original_transaction_id属性是否与transaction_id匹配。


请注意,在可续订的订阅情况下,当用户取消订阅并稍后重新开始订阅时,原始交易仍将设置为第一次购买交易(即不仅适用于自动续订,也适用于手动续订)。 - Frederik

4

坏消息是:在当前iOS版本(4.3.x)中,无法区分非消耗性产品的购买和重新购买。

为了缓解这种情况,我建议两件事:

第一

成功购买后,在设备上的NSUserDefaults中存储所购买产品的product identifier。然后,您可以隐藏已购买的产品,因此处理重新购买的情况。

NSUserDefaults在用户同步设备时由iTunes备份。因此,当用户获得新设备时,您存储的购买信息不会丢失。

第二

将收据数据与设备ID一起存储在您的服务器上。分析收据的产品标识符和设备ID。

如果您收到另一个具有相同产品标识符和设备ID组合的收据,则假定重新购买。至少这将允许您涵盖大多数重新购买情况。

假设普通iPhone用户每1-2年更换一次设备,那么您至少将涵盖大多数重新购买情况,也许苹果将来会修复此问题。


1
我认为你根本不应该将购买与设备绑定。购买是与Apple ID绑定的,我们对此无能为力,用户可以在100个设备上恢复非消耗品。 - Jonny

1

我有一个解决方案,

  1. 将产品配置为可消耗品。 这将解决问题 - (他们要求每次我们销售此内容的一件物品时(即用户向我们付款))。

  2. 接下来,您需要在产品购买选项中实现逻辑。以这样的方式,一旦用户购买了产品,购买选项就需要被删除,否则用户可能会不经意地再次购买同一设备上的相同产品而失去现金。 您可以使用NSUserdefaults来实现此目的。

谢谢,


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