iOS 应用内购买:消耗品的服务器端收据验证

iOS In-app purchase: server side receipt validation for consumable products

我想为我正在开发的 iOS 应用实施 消费品 产品的应用内购买。我想按照 documentation:

中的指示在服务器端验证收据
  1. App 开始交易询问 Apple Store
  2. Apple Store return 应用收据
  3. 应用将收据发送到受信任的服务器
  4. 受信任的服务器通过 HTTP POST
  5. 向 Apple Store 发送收据(base 64 格式)
  6. Apple Store 通过验证
  7. 回复 HTTP POST
  8. 如果验证响应正常,则可以启用购买

我担心以下情况:用户购买产品,Apple Store 将收据发回应用程序(步骤 1,2)。然后,当应用程序尝试将收据发送到受信任的服务器时(第 3 步),连接断开。在这种情况下,必须在一秒钟内重试收据验证,但是,我有以下问题:

a) 在这种情况下,用户是否已经为产品付款?
b) 由于 consumable 产品 compare only at the time of the purchase 的收据,应如何管理验证重试?我应该在本地保存收据以便将来重新传输吗? 我可以简单地不将交易标记为“finished”吗?根据我阅读文档的理解,在这种情况下,StoreKit 应该再次调用事务队列观察器(再次传递收据?)直到事务被标记为 "finished",是否正确?

提前致谢

a) 在这种情况下,用户是否已经为产品付款?

PaymentTransaction观察者会告诉你用户的购买是什么状态 .Purchased, .Purchasing, .Failed 。 e.t.c.

因此我们可以根据您的问题假设用户的 状态为 .Purchased 并且您会收到付款。 现在,由于他们有收据并且希望是真实购买的,他们将等待您在您的服务器上验证并解锁购买,因为他们收到了包含有关他们购买的数据的收据。

b) 由于消耗品的收据仅在购买时进行比较,因此应如何管理验证重试?我应该在本地保存收据以便将来重新传输吗?我可以简单地不将交易标记为“完成”吗?根据我阅读文档的理解,在这种情况下,StoreKit 应该再次调用事务队列观察器(再次传递收据?)直到事务被标记为“完成”,是否正确?

你不需要存储在本地,在收据中存储有关购买的信息。这将一直保留到您的 paymentObserver 完成交易或收据再次刷新/更新。 您的应用程序将继续尝试与您的服务器进行验证,直到它通常在用户再次启动该应用程序时收到有关收据的响应, 到那时,如果我们假设它是有效的,您启用您的产品,然后在 SKPaymentQueue 上完成交易。

文档中说的是

“消费品的应用内购买收据在购买时添加到收据中。它会保存在收据中,直到您的应用程序完成该交易。在那之后,它会在下次更新收据时从收据中删除“

https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW1

还有: “例如,考虑用户在进入隧道之前在您的应用程序中购买东西的情况。由于没有网络连接,您的应用无法传送购买的内容。下次启动您的应用程序时,StoreKit 会再次调用您的事务队列观察器并在那时交付购买的内容。同样,如果您的应用未能将交易标记为已完成,StoreKit 会在您的应用每次启动时调用观察者,直到交易正确完成。”

我希望这对您有所帮助,我希望它能回答您的问题。