每次续订都有自己的 Google Play 订单号,退款前要核对的正是这个号码
像 GPA.1234-5678-9012-34567..2 这样的 Google Play 订单号对应一笔确切的扣款。本文说明如何读懂续订后缀,如何在 Play Console 或 Orders API 中查询订单,以及如何退还客户真正所指的那笔扣款,避免为错误的订单买单。

要点
- Google Play 订单号的格式类似 GPA.1234-5678-9012-34567,订阅续订会加上后缀,因此 GPA.1234-5678-9012-34567..0 是该订阅的第一次续订。
- 对于订阅续订,Play Billing Library 的 getOrderId() 返回的是初始订单的订单号,而不是续订本身的订单号;购买处于 PENDING 状态时则返回 null。
- Google 于 2025 年 5 月 21 日在 Play Developer API 的 Orders 资源中新增了 get 和 batchGet。batchGet 接受 1 到 1,000 个互不重复的订单号,只要其中任何一个找不到,整个请求就会失败。
- Orders API 返回的 Order 带有 PENDING、PROCESSED、CANCELED、PENDING_REFUND、PARTIALLY_REFUNDED 或 REFUNDED 状态,以及 developerRevenueInBuyerCurrency,该金额已扣除部分退款、税费和手续费。
- Google Play 的 orders.refund 方法无法退还超过 3 年的订单,传入 revoke=true 会立即终止客户对该订阅或商品的访问权限。
- 在 Play Console 中,“退款并撤销”(Refund and revoke)适用于订阅中最近的一笔订单,而“仅退款”(Refund only)适用于较早的订单,订阅保持有效。
- 购买后 48 小时内的退款请求由 Google Play 自行处理。超过 48 小时后,Google 会让客户联系开发者,这时订单号通常就会出现在你的客服收件箱里。
给 Google Play 客户退款之前,先看订单号的结尾。GPA.1234-5678-9012-34567 是一个订阅的第一笔扣款,GPA.1234-5678-9012-34567..2 是第三笔。它们共用同一个基础编号,却是不同的付款,退款时 Play Console 对它们的处理也不同。Google Play 订单号是客户唯一能看到的标识符,所以最终出现在你客服收件箱里的就是它。读对了,你就能把客户真正不满的那笔扣款退掉,而且只退一次。
Google Play 订单号能告诉你什么
Google 的 Play Billing Library 文档以示例说明了格式。订单号以 GPA 开头,后面是几组数字。对于订阅,每次续订都会在基础订单号后加上两个点和一个从零开始的计数器。因此,原始购买没有后缀,第一次续订是 ..0,第二次是 ..1,依此类推。
这样一来,看后缀就能快速判断客户已经付费了多久。来信提到 GPA.3333-4137-0319-36762..11 的客户已经续订了十二次。引用不带后缀的基础编号的客户,要么只买过一次,要么指的是他们的第一笔付款。
| 订单号 | 含义 |
|---|---|
| GPA.1234-5678-9012-34567 | 一次性购买,或订阅的第一笔扣款 |
| GPA.1234-5678-9012-34567..0 | 该订阅的第一次续订 |
| GPA.1234-5678-9012-34567..1 | 第二次续订 |
| Billing Library 中的 null | 仍处于 PENDING 状态、Google 尚未处理付款的购买 |
订单号出现在哪里,你拿到的是哪个版本
团队常在这里出错。不同的地方给你的是同一个编号的不同形式。
- 客户的 Google Play 收据显示的是该笔扣款对应的订单号,续订也包括在内。
- 在你的应用中,Play Billing Library 的 Purchase.getOrderId() 对订阅续订返回的是初始订单的订单号。Google 自己的示例:你拿到的不是 GPA.1234-5678-9012-34567..0,而是 GPA.1234-5678-9012-34567。
- 在服务器端,purchases.subscriptionsv2 为每个订单项提供 latestSuccessfulOrderId,即该项最近一笔成功订单的编号。Google 于 2025 年 5 月 21 日新增了这个字段。
- 在 Voided Purchases API 中,orderId 唯一标识一次性购买、订阅购买或订阅续订。Google 文档要求用 orderId 而不是购买令牌来区分各次续订。
购买令牌的用途
购买令牌标识的是整个购买。对于订阅,一个令牌覆盖原始扣款及之后的每次续订。这就是为什么它适合用来管理权益,却不适合用来退款。退款和拒付针对的是单笔扣款,而只有订单号能指向单笔扣款。
如何查询 Google Play 订单
在 Play Console 中
订单管理(Order management)的搜索框接受订单号或客户的完整电子邮件地址。每笔订单显示以下状态之一:已处理(Processed)、已取消(Cancelled)、待处理(Pending)、待退款(Pending refund)、已退款(Refunded)、待部分退款(Pending partial refund)或已部分退款(Partially refunded)。如果客户给你的是电子邮件地址而不是收据,就按电子邮件搜索,按日期找到那笔扣款,然后在操作前确认后缀。
使用 Orders API
自 2025 年 5 月 21 日起,Google Play Developer API 的 Orders 资源提供 orders.get 用于查询单笔订单,orders.batchget 用于查询一组订单。实际使用中有几项限制需要注意:
- batchget 每个请求接受 1 到 1,000 个订单号,且不得重复。
- 只要有一个订单号找不到或不属于该软件包,整个 batchget 请求就会失败。
- Orders API 的调用计入你的 Play Developer API 配额,默认每天 200,000 次调用。
真正有用的是返回的 Order。它包含订单的 state、purchaseToken、createTime 和 lastEventTime、总额和税额、salesChannel(如 IN_APP 或 PLAY_STORE),以及记录处理、取消、退款和部分退款事件的 orderHistory。它还包含 developerRevenueInBuyerCurrency,Google 将其定义为以买家货币计算、已扣除部分退款、税费和手续费的开发者收入。当 Google 是记录商家(merchant of record)时,买家地址只包含国家/地区。
| 订单状态 | Google 参考文档的说明 |
|---|---|
| PENDING | 已创建,等待处理 |
| PROCESSED | 已成功处理 |
| CANCELED | 在处理前已取消 |
| PENDING_REFUND | 已申请的退款正在等待处理 |
| PARTIALLY_REFUNDED | 订单金额已部分退还 |
| REFUNDED | 订单金额已全额退还 |
退还正确的订单
确定客户所指的是哪笔扣款后,Play Console 会根据该订单在订阅中的位置给你不同的选项。
| 选项 | 适用对象 | 结果 |
|---|---|---|
| 退款并撤销(Refund and revoke) | 订阅中最近的一笔订单 | 发放退款,立即移除订阅,取消后续续订 |
| 仅退款(Refund only) | 订阅中较早的订单 | 发放退款,订阅保持有效 |
| 部分退款(Partial refund) | 2018 年 3 月之后下单的应用内购买和订阅,不含付费应用 | 低于 100% 的任意比例,或低于订单总额的税前金额 |
| 取消订阅(Cancel subscription) | 有效的订阅 | 不退款,访问权限持续到当前结算周期结束 |
通过 API,orders.refund 接受软件包名称和订单号。超过 3 年的订单无法退款。可选的 revoke 参数设为 true 时,会立即终止对订阅或应用内商品的访问权限。Google 帮助文档还指出,退款一经发放便无法撤回,因此你传入的订单号就是最终决定。
为什么订阅者会出现一笔 $0.00 的订单?
Google 的订阅生命周期文档对此有说明。当用户在订阅到期前从你的应用再次注册同一个基础方案时,Google Play 会创建一笔 $0.00 的订单。用户不会被扣款,因为他们已经为当前周期付过费,正常结算会在原定续订日期恢复。这既不是免费试用,也不是促销。这笔订单没有可退的钱。如果客户想要退款,请找到它之前的那笔付费订单。
退错订单的代价
退款退还的是价格。部分退款按比例同理。Google 的示例:50% 的部分退款也会收回你 50% 的收入和 50% 的服务费。收不回来的是你为该客户提供服务所花的一切,包括算力、第三方 API 调用、存储以及任何联盟佣金。退错了订单,这些成本你就要付两次。
事情通常是这样发生的。一位月度方案的客户来信询问 ..4 那笔扣款,也就是上周那笔。你团队里有人按电子邮件搜索,看到最上面是第一笔订单,就对几个月前的基础订单点了“仅退款”。现在客户拿回了一个已经使用过的周期的钱,他们投诉的那笔扣款却原封未动,订阅也照常续订。他们仍然可以要求银行撤销上周的扣款。

如今,走银行这条路的代价最高。Google 表示,对于 2026 年 8 月 3 日之后下的订单,拒付一旦成立,开发者需承担购买价格(扣除 Play 服务费)以及银行收取的拒付费用。拒付在银行端是最终结果。一次看错后缀,最终可能损失相当于两次退款的钱,外加手续费。
哪些退款根本不会到你的收件箱
大多数 Google Play 退款根本不需要你,也不需要订单号。Google 的退款政策规定,客户在购买后 48 小时内可以通过 Google Play 获得退款,超过 48 小时则应联系开发者。对于你在三天内未确认的订阅,Google 也会退款并撤销。你会在事后通过 Voided Purchases API 得知这些情况,该 API 会报告 voidedSource(0 表示用户,1 表示开发者,2 表示 Google)以及 voidedReason,例如 Remorse、Chargeback 或 Unacknowledged_purchase。
只有一种 Google Play 退款流程需要你表态。当拒付需要开发者审核时,你有 24 小时通过 orders.reviewrefund 作出答复,提交 APPROVE、DECLINE 或 NEUTRAL 的退款偏好以及购买使用情况证据。RefundHalt 会在时限内用你已有的使用数据替你答复该审核,让有争议的订单得到你的证据,而不是沉默。
订单号客服工单简明检查清单
- 向客户索取 Google Play 收据上的完整订单号,包括后缀。
- 在 Play Console 中或用 orders.get 查询,并先检查其状态。
- 确认扣款日期与客户描述一致。
- “退款并撤销”只用于最近的一笔订单,较早的订单用“仅退款”。
- 记录你退款的订单号,这样以后另一笔订单发生拒付时就容易发现。
常见问题解答
- Google Play 订单号末尾的 ..0 是什么意思?
- 它表示订阅的第一次续订。Google Play 为每次续订分配的编号是订阅的基础订单号加上两个点和一个从零开始的计数器,因此 GPA.1234-5678-9012-34567..0 是第一次续订,..1 是第二次。不带后缀的基础编号是原始扣款。
- 为什么我应用中 getOrderId() 返回的订单号与客户收据上的不同?
- 因为对于订阅续订,Play Billing Library 返回的是初始订单的编号。Google 的示例是,对于第一次续订,getOrderId() 返回的不是 GPA.1234-5678-9012-34567..0,而是 GPA.1234-5678-9012-34567。请在服务器端使用 purchases.subscriptionsv2 的 latestSuccessfulOrderId 获取续订本身的编号。
- 如何按订单号查询 Google Play 订单?
- 在 Play Console 的订单管理(Order management)中搜索,它接受订单号或客户的完整电子邮件地址;也可以调用 Google Play Developer API 的 orders.get。orders.batchget 可一次查询 1 到 1,000 个互不重复的订单号,只要其中任何一个找不到,整个请求就会失败。
- 超过一年的 Google Play 订单还能退款吗?
- 可以,最长 3 年。Google 的 orders.refund 参考文档指出,超过 3 年的订单无法退款。对于订阅中较早的订单,Play Console 的“仅退款”(Refund only)选项会退还款项,订阅保持有效。
- 为什么订阅者会有一笔 $0.00 的 Google Play 订单?
- 当用户在订阅到期前从你的应用再次注册同一个基础方案时,就会出现这种订单。用户不会被扣款,因为他们已经为当前周期付过费,正常结算会在原定续订日期恢复。Google 表示,这并不意味着提供了免费试用或促销折扣。
来源和延伸阅读
- Android Developers: Purchase (Play Billing Library), getOrderId
- Google Play Developer API: REST Resource orders
- Google Play Developer API: orders.batchget
- Google Play Developer API: orders.refund
- Google Play Developer API release notes
- Google Play Developer API: purchases.voidedpurchases
- Play Console Help: Issue refunds or cancel orders
- Google Play Billing: Subscription lifecycle
- Google Play Help: Apps, games and in-app purchases refund policies
- Google Play Console Help: Updates to refund protection and chargeback cost responsibility
RefundHalt
App Store 和 Google Play 退款自动驾驶
继续阅读
过多的退款申请,代价可能远超退款本身,因为两大应用商店都把它当作质量信号
Apple 审核指南 5.6.4 把过多的退款申请列为应用未达质量标准的迹象,Google 的开发者分发协议也允许它依据退款率下架新开发者的应用。本文梳理两家商店的原文、下架的真实成本,以及如何避开风险。
在处理退款之前先验证 App Store 服务器通知,因为任何人都能向你的 webhook URL 发送请求
在检查签名之前,一条退款通知只不过是一个 HTTPS 请求。本文介绍如何验证 App Store 服务器通知和 Google Play RTDN 消息、每个商店签名的内容,以及伪造的退款或被错误拒绝的退款会让你付出什么代价。