一次购买的 Apple 应用内购买 transaction_id 有时会发生变化

Posted

技术标签:

【中文标题】一次购买的 Apple 应用内购买 transaction_id 有时会发生变化【英文标题】:Apple In-app purchase transaction_id of one purchase changes sometimes 【发布时间】:2017-07-07 20:45:36 【问题描述】:

一旦我从客户端获得收据并通过苹果服务器验证它,我就会在此收据中获得新购买的交易 ID(它是自动订阅购买)。几天后,我从同一个客户那里得到一张新收据并验证它,奇怪的事情发生了:那个旧购买的交易ID改变了。

我对比了这次购买在旧收据中的数据和新收据中的数据,唯一变化的是transaction_id字段,original_transaction_id、purchase_date、expires_date、web_order_line_item_id等字段是完全一样。

比我查数据库,我发现大约1%的交易记录有同样的情况。而且有一个特点,他们的交易id大部分增加或减少了1-2

我以前认为交易 id 是购买的标识符。有没有人遇到同样的问题或知道原因?

【问题讨论】:

我现在面临同样的问题,想知道您是如何解决这个问题的? 由于我现在不能依赖transaction_id或web_order_line_item_id,所以我将使用新transaction_id和新web_order_line_item_id的购买视为新购买。 【参考方案1】:

是的,我们也看到了这种情况。我们看到这是由“恢复购买”按钮点击触发的。

如果您的“恢复购买”按钮使用restoreCompletedTransactions API,那么这将导致您的交易 ID 发生变化。我们已经通过 Apple 开发者支持确认了这一点。

显然,您可以致电SKReceiptRefreshRequest,它只会获取最新的收据,而不是重播所有交易。据我了解,这不会导致交易 ID 发生变化。

有趣的是,我们见证了 web_order_line_item_id 的值不会随着对 restoreCompletedTransactions 的调用而改变。然而,当我们要求确认时,我们最多只收到了来自 Apple 开发人员支持的模棱两可的回复:

关于 web_order_line_item_id 字段,该值将在每次后续续订时更改。

您可以使用它,只要您在续订订阅事件到来时继续存储新值。

我们认为这意味着web_order_line_item_id 在每次续订时都是唯一的。这既不确认也不否认它在对restoreCompletedTransactions的调用中保持不变@

此外,我发现 Apple/Google/Amazon 定期计费的会议录音非常有帮助(尽管不适用于这种特殊情况):

Rosa Gutierrez - The recurring nightmare. Implementing cross platform in-app subscription purchases

【讨论】:

感谢您的回答。最终,您是否使用 web_order_line_item_id 实现了每笔交易的唯一性? @Sriram 我仍然不能 100% 确定 web_order_line_item_id 是全球唯一的。我们改用重复数据删除记录并开始使用SKReceiptRefreshRequest 刚才我们在我们的应用程序中测试了恢复购买功能,虽然它按预期工作,但它没有更改收据中的任何交易标识符。 @Sriram,是的,我们也注意到了同样的事情。虽然它没有总是更改事务 ID,但有时会发生这种情况。文档说它“为每个以前完成的可以恢复的交易提供一个新的交易”。我不确定是什么情况和/或条件导致交易 ID 发生变化。您可以测试但我们没有测试的一件事是使用与执行购买的设备完全不同的设备调用restoreCompletedTransactions 谢谢你们的好消息,original_transaction_id 无论如何都不会改变,对吗?【参考方案2】:

基于最新的 Apple 开发者文档,

web_order_line_item_id - 跨设备购买事件的唯一标识符,包括订阅续订事件。 此值是识别订阅购买的主键。

transaction_id - 您可以将此值用于:

    在您的帐户数据库中管理订阅者。存储每个交易的 transaction_id、original_transaction_id 和 product_id,作为存储每个客户的交易记录的最佳实践。 每次订阅自动续订或在新设备上恢复时,App Store 都会为 transaction_id 生成一个新值。 将购买交易与恢复或续订交易区分开来。在购买交易中,transaction_id 始终与 original_transaction_id 匹配。 对于订阅,它表示第一次订阅购买。对于恢复或续订,transaction_id 与 original_transaction_id 不匹配。 如果用户多次恢复或续订同一购买,则每次恢复或续订都有不同的 transaction_id。

【讨论】:

那么你如何处理用户 A 购买的可更新订阅 -> 然后删除应用程序/时间流逝/订阅自动续订 -> 现在用户 B 使用不同的帐户登录(但仍然是相同的 iTunes 帐户) 并恢复购买 -> 应该在服务器上保留什么 ID,以及当 userB 恢复购买时应该比较什么? (在这种情况下,我们必须弄清楚订阅实际上属于用户 A,用户 B 不应该从中受益)。 @PawelKlapuch 我使用 App Store 服务器通知来跟踪订阅续订事件。所以我的数据库有所有订阅续订信息,用户A是否删除了应用程序并不重要。用户 B 只有在使用相同的 iTunes 帐户并且订阅仍然有效时才能恢复购买。因此,当用户 B 恢复购买时,我将使用 web_order_line_item_id 检查该订阅是否已存在于数据库中,因为它是唯一标识符。如果是,则通知用户 B iTunes 帐户在另一个应用帐户上具有有效订阅。

以上是关于一次购买的 Apple 应用内购买 transaction_id 有时会发生变化的主要内容,如果未能解决你的问题,请参考以下文章

带有托管内容的 Apple 应用内购买 - 不下载文件

如何从 Apple 服务器获取应用内购买列表

如何通过Apple TestFlight测试应用内购买?

使用自动续订订阅的应用是不是需要 Apple 应用内购买?

使用真实 Apple ID 的应用内购买行为

iOS 11.1.2 中的 Apple 应用内购买错误