使用 Google Play RTDN 进行快速事件处理。使用 Voided Purchases API 检查已取消的订单并核对你的记录。对大多数付费应用而言,更稳妥的选择是两者都用。
如果你正在规划 应用的 Google Play 退款防御方案,不妨从这种划分入手。一条路径告诉你发生了什么变化,另一条路径让你的服务器获取已取消购买的列表,检查有哪些遗漏。
这个选择并不完全是在两个通知系统之间做取舍。Google Play RTDN 通过 Cloud Pub/Sub 推送消息,而 Voided Purchases API 是一个拉取式(pull)API:由你的后端主动调用它。
单独使用其中任何一个,都无法阻止用户申请退款。它们的价值在于检测变化、核查订单,并确保付费权限与购买状态保持一致。
关键要点
使用 RTDN 及时响应购买和订阅事件。
使用已取消购买列表作为检查受影响订单的第二条路径。
不要把订阅取消当作已退款的证据。
让两条路径使用相同的安全权限更新逻辑。
将待处理的拒付审核与已完成的取消购买区分开来。
什么是 Google Play RTDN?
Google Play 实时开发者通知(Real-Time Developer Notifications,通常简称 RTDN)会将与购买相关的事件发送到 Cloud Pub/Sub 主题。
你的后端接收消息后,将其路由给正确的工作进程(worker)。消息类型很关键:续订、取消和已取消购买并不是同一类事件。
在追踪退款时,请特别关注 voidedPurchaseNotification。它包含以下信息:
purchaseToken:将事件与某次购买关联起来。
orderId:标识受影响的订单。
productType:标识该项目是订阅还是一次性购买。
refundType:区分完全取消和基于数量的部分退款。
Google 的 RTDN 参考文档及事件定义详细说明了这些字段以及其他通知类型。
当你需要在变化发生后迅速采取行动时,RTDN 非常有用。但一条消息并不等同于你完整的购买数据库。在更改权限之前,请将消息与已存储的记录进行匹配,并在必要时获取相关的购买状态。
订阅取消是否意味着已退款?
不一定。用户可以停止后续续订,同时在当前计费周期剩余时间内仍保有付费权限。
不要构建一条规则,让系统一收到 SUBSCRIPTION_CANCELED 就撤销权限。应改为检查订阅状态和到期时间。撤销(revocation)和到期需要分别单独处理。
什么是 Voided Purchases API?
Google Play 的 Voided Purchases API 会返回在其支持范围内已被取消、已退款或已拒付的购买列表。
它适用于一次性应用内订单和订阅。你的服务器可以利用返回结果,检查哪些购买不应再授予权限。
该列表可以包含订单 ID、购买令牌(purchase token)、取消时间、取消来源和取消原因。对于支持的基于数量的部分退款,还可以包含已退款的数量。
Google 的 Voided Purchases API 指南说明其回溯窗口为 30 天。它并不是永久性的退款档案库,请将已处理的记录保存在你自己的系统中。
在工作进程中断、路由出现错误,或本地记录出现缺口之后,这个 API 尤其有用。它还能让你对已处理的事件进行常规核查。
RTDN 与 Voided Purchases API:实际差异
问题 | Google Play RTDN | Voided Purchases API |
它是如何运作的? | Google 将事件发布到 Pub/Sub。 | 你的服务器请求一份列表。 |
它的主要作用是什么? | 及时处理购买状态的变化。 | 检查并核对已取消的订单。 |
它涉及的事件是否超出退款范围? | 是的,包括续订和其他生命周期事件。 | 它专注于已取消的购买。 |
处理出现缺口之后,它能提供帮助吗? | Pub/Sub 的恢复能力取决于你的配置和保留策略。 | 它可以在 30 天窗口内列出可用的记录。 |
它是否需要防重复机制? | 需要。 | 需要,尤其是当扫描存在重叠或与 RTDN 共享事件时。 |
关键问题不是单独比较哪个工具更好,而是每个工具分别能帮你应对哪种故障。
RTDN 为你提供了快速路径,API 为你提供了核查路径,而你自己的数据库应该将两者整合起来。
你的应用应该使用哪一个?
速度至关重要时使用 RTDN
付费应用不应该等到定期扫描才发现购买状态的变化。
当你的应用需要针对订阅、一次性购买和已取消订单进行即时更新时,请使用 RTDN。请按事件类型分别路由,而不是对所有消息套用同一条退款规则。
完整性至关重要时使用该 API
使用定期的 API 检查,找出工作进程未能应用到你记录中的已取消订单。
例如,你的接收端可能已经接受了一条消息,但某个 bug 可能阻止了后续的权限更新。仅仅修复消息投递本身,并不能弥补这个本地缺口。
在生产环境的退款工作流中同时使用两者
对大多数付费应用而言,应将两者结合使用。让两条路径都汇入同一个共享的处理程序,由它检查订单并安全地应用任何变更。
这可以降低因遗漏事件而导致权限仍处于激活状态的风险,同时也能降低另一种相反的风险:针对同一笔退款重复撤销两次权限。
如何分步检测 Google Play 退款
1. 维护购买台账
存储应用包名、购买令牌、订单 ID、商品、用户映射关系以及已授予的数量。台账其实就是一份清晰的记录,说明购买了什么、授予了哪些权限。
对于订阅,也要存储续订的订单 ID。RTDN 参考文档指出,每次自动续订都会生成一个新的订单 ID。仅凭购买令牌不足以识别每一次受影响的续订。
2. 保护并路由 RTDN 消息
正确配置 Pub/Sub 的访问权限。对于推送(push)投递方式,要验证请求的身份认证;对于拉取(pull)投递方式,要限制谁可以读取该订阅。
先解码消息、检查包名并保存记录,然后才执行耗时较长的操作。请通过完整路径发送测试事件,而不仅仅是测试接收端点。
3. 运行定期的已取消购买扫描
使用合适的凭据和 Play Console 权限调用列表方法,并遍历所有结果分页。
有两个查询设置很容易被忽略:
type=1 会同时包含一次性购买和订阅;默认值 0 则仅包含一次性购买。
includeQuantityBasedPartialRefund=true 会包含受支持的基于数量的部分退款;其默认值为 false。
Google 的 voidedpurchases.list 方法参考文档介绍了请求参数和分页字段。
在各次扫描之间保留适度的重叠,并对结果去重。根据你的数据量、配额以及应用能够承受的延迟程度来选择扫描频率。不要等到回溯窗口即将结束才进行扫描。
4. 确保每项变更只应用一次
两条路径可能会报告同一次取消。请构建幂等(idempotent)处理机制:重复执行同一项变更不应改变结果。
不要仅凭订单 ID 就丢弃所有后续事件。一笔多数量的购买可能会发生多次部分退款。请跟踪已处理的调整记录和已退款数量,以避免遗漏后续真实发生的退款。
5. 监控缺口,而不仅仅是消息数量
跟踪上一次成功扫描的时间、未完成的分页、工作进程错误以及未匹配的订单。衡量从事件确认到权限更新所花费的时间。
如需更全面的报告方案,请参阅我们的 移动应用退款与拒付追踪工具指南。
示例:一次退款,两条检测路径
这是一个假设性的工作流示例,并非真实上报的客户案例。
某玩家购买了一个可获得 500 枚金币的一次性礼包,该购买后来被完全取消。
RTDN 发送一条已取消购买的消息。你的工作进程找到该订单,检查已记录的授予情况,并对与该购买关联的金币应用你已公布的政策。
随后,定期的 API 扫描返回了同一个订单。共享处理程序发现完全取消的调整已经应用过,于是记录下这次匹配,不再进行第二次扣减。
现在假设工作进程在应用第一次变更之前就失败了。扫描会找到该订单,为你的系统提供另一条处理路径。
这正是同时使用两者的意义所在:并非两次独立的处罚,而是通往同一个正确结果的两条路径。
如果部分金币已被消耗,不要盲目地从其他无关的付费礼包中扣除金币。请采用明确的政策,解释你的处理方式,并提供支持渠道。
待处理的退款审核是一条独立的工作流
当前的 Google 文档还列出了 pendingRefundReviewNotification,用于需要开发者审核的拒付请求。
对于该事件,Google 要求你在 24 小时内通过 orders.reviewrefund 提交退款建议和购买使用证据。
请不要将它与 voidedPurchaseNotification 混淆。一个涉及的是待处理的审核,另一个报告的是已经被取消的购买。
Voided Purchases API 并不能替代对待处理审核事件的处理。请将这条分支单独处理,并且不要假设每一次退款请求都会触发该事件。
App Store 退款与收入流失:开发者需要了解的事
收入流失不仅限于应用商店是否退还资金,也可能意味着在相关购买已不再支持的情况下,你的后端仍在持续授予付费权限。
对于同时在两个平台上运营的团队而言,目标是相似的:让资金、购买状态和权限记录保持一致。但两个平台的商店工具和事件规则各不相同,不要把 Apple 的工作流原样复制到 Google Play 上。
我们的 App Store 退款收入管理指南涵盖了更广泛的收入管理问题。对于这次 Google Play 集成,请先重点关注遗漏的取消、重复扣减以及错误的订阅权限变更。
Google Play 退款欺诈防范能做什么,不能做什么
Google Play 的退款欺诈防范始于可靠的记录和公平的规则。一个已取消的订单并不能证明用户存在不诚实的行为。
用户可能确实有合理的投诉,支付可能失败,你的应用也可能发送了错误的商品。
使用这些工具来核实情况并应用权限变更。结合具体情境审查反复出现的模式。避免仅凭一次退款就自动封禁账户,并允许用户对错误提出申诉。
无论是 RTDN 还是该列表 API,都不能保证你可以阻止、拒绝或撤销一次退款。
结语
对于大多数付费应用而言,RTDN 与 Voided Purchases API 之间的选择并不是非此即彼的决定。
使用 RTDN 快速响应,使用定期的已取消购买检查来核对记录。让两者都通过同一个安全的处理程序,并将待处理的审核与已完成的取消区分开来。
从一个小测试开始:让一次取消操作同时经过两条路径,并确认权限只变更一次。然后停止你的工作进程,检查恢复路径能否捕捉到这个缺口。
常见问题
RTDN 更适合快速处理事件,而该 API 更适合定期检查已取消的订单。大多数付费应用都能从两者中获益。
可以。它包含一个附带订单和退款类型详情的已取消购买通知(voided-purchase notification)。请将该事件与订阅取消分开处理。
你可以通过轮询检测可用的已取消购买记录,但检测结果要等到下一次成功扫描才能获取。此外,你也会错过 RTDN 更广泛的生命周期事件流。
Google 官方文档说明的回溯窗口为 30 天。如需更长期的检查和支持用途,请保留你自己的记录。
需要。请在列表请求中启用支持的部分退款结果,跟踪已退款数量,并考虑同一订单可能出现多次部分退款的情况。



