在StoreKit / In-App Purchase中区分初始购买和免费“重新购买”

从StoreKit指南:

如果用户试图购买他们已经购买的非消费品或可更新的订阅,那么您的应用程序会收到该项目的正常交易,而不是恢复交易。 但是,用户不会再为该产品付费。 您的应用程序应将这些交易视为与原始交易的交易完全相同。

这在我正在工作的应用程序中提出了一个巨大的问题。 我们已经通过应用程序内购买从发布商许可了大量内容供销售。 他们要求我们每次出售这些内容(即用户付款)时,我们的服务器会在其服务器上调用一个API来报告交易。 这是为了会计目的,并最终根据我们与他们达成的协议,最终用来确定我们在月底支付多less钱。

我已经阅读了几个关于SO和其他地方的build议,关于比较频繁地调用restoreCompletedTransactions,并且在设备上保持了用户已经购买了什么的本地理解,因此他们不能再被购买。 这对我来说似乎是应该能够在服务器端实现的东西。 但是,我们从Apple服务器获取的收据与StoreKit指南所承诺的购买和重新购买完全一样。

如果在这种情况下(即“您已经付款”和“您没有收到付款”),StoreKit的支付回拨无法作为有效的会计机制进行信任,那么还有什么其他的实时交易stream量见解? 我认为,如果我们告诉他们我们必须在本月底之后等待45天才能从iTunes Connect中获得REAL付款金额,我们认为我们正在与之合作的发行商会很高兴。

我最近看到了同样的问题。 就我而言,我想通过移动应用程序跟踪来实现准确的收入跟踪,以跟踪不同客户收购活动产生的收入。

幸运的是,有一种方法可以做到这一点。 应该注意的是, SKPaymentTransactionStatePurchasedSKPaymentTransactionStateRestored完全取决于初始化操作,例如是否启动了恢复或(重新)购买,因此不起作用。

什么工作,而不是检查SKPaymentTransaction.originalTransaction这将是!= nil为恢复重新购买。 后者是不幸的行为( 文档 )。 尽pipe如此,我认为一个空检查是足够公平的。

另一个select是validation与SKPaymentTransactionStatePurchased交易的交易收据,并检查返回的validation收据中的original_transaction_id属性是否与transaction_id匹配。

坏消息是:在当前的iOS版本(4.3.x)中,没有办法区分购买和重新购买非消费品。

为了缓解这种情况,我会推荐两件事:

第一

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

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

第二

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

如果您收到具有相同产品标识符和设备ID组合的另一个收据,则假定重新购买。 至less这可以让你覆盖大部分的再购买案例。

假设一个普通的iPhone用户每隔1 – 2年更换一次设备,至less可以覆盖大部分的重新购买案例,也许苹果公司将在未来解决这个问题。

我有一个解决scheme,

  1. 将产品configuration为消耗品。 这将解决问题 – (他们要求我们每次出售一个这样的内容(即用户付款))。

  2. 接下来,您需要在产品购买选项中实施逻辑。 一旦用户购买产品购买选项需要删除,否则用户可能会在同一设备中为同一产品再次发生购买而丢失现金。 你可以使用NSUserdefaults来达到这个目的。

谢谢,