每一笔订阅升级退款都由商店决定,不由你决定,而且直接从你的收入中扣除
当客户升级到更高档位时,商店会为旧套餐上未使用的天数发放一笔订阅升级退款,并自动减少你的收入。本文讲清升级退款在 App Store 和 Google Play 上的运作方式,以及 Apple 为何不把这个金额发给你的服务器。

要点
- 订阅升级退款是自动发生的。当客户在周期中途升级到更高档位时,商店会不经你同意就为旧套餐上未使用的天数记入抵扣或退款,而这笔钱来自你已经入账的收入。
- 在 App Store 上,升级会立即生效,Apple 按比例退还原订阅的相应金额。降级则要等到下一个续订日,且不退任何款。
- Apple 不会把升级退款的金额发送到你的服务器。升级后的交易会被标记为 isUpgraded,但价格字段仍显示新档位的全价,因此你根据 App Store Server Notifications 计算的收入会偏高。
- App Store Connect 财务报告是唯一记录按比例升级退款的地方。Apple 员工表示,这个金额无法通过 App Store Server API、Notifications 或 StoreKit 获取。
- 在升级时,Google Play 不会把钱退回到卡里。它会抵扣未使用的时长,或收取价格差额,具体是哪一种取决于你设置的替换模式。默认是 WITH_TIME_PRORATION。
- 升级退款不是客户的退款申请。它没有 CONSUMPTION_REQUEST,也没有拒付审查,因此没有 12 hours 或 24 hours 的窗口,也没有可以申诉的对象。你只需对账,不必去争。
- 替换模式是一个关乎收入的决定。WITH_TIME_PRORATION 会把额外的付费时长交给客户,而你要按更高档位的成本去交付;CHARGE_PRORATED_PRICE 则当场收取差价,因此错误的默认设置会让利润随着每一次升级一点点流失。
客户点了升级,从你的 five dollar 档位换到 ten dollar 档位,你入账了一笔更大的销售。就在同一刻,商店做了另一件你永远看不到的事。它为客户在旧套餐上已经付过款的那些天,发放了一笔订阅升级退款,而这笔钱从你的收入里扣。没有人征求你的意见。在 App Store 上,你甚至无法在服务器收到的事件里找到这个金额。
这不是你能去争的那种退款。它不是 Apple 的 CONSUMPTION_REQUEST,也不是 Google Play 的拒付审查。它是按比例分摊,内建在两家商店让用户更换套餐的机制里,每当订阅者升到更高一档时,它就自动运行一次。下面讲清升级退款在每家商店上究竟是什么,Apple 为何不把金额发给你的服务器,以及错误的 Google Play 设置会让你付出多少代价。
订阅升级退款究竟是什么
升级退款是商店为客户已付款但用不到的时间所做的结算。它与投诉、争议或你的退款政策毫无关系。它仅凭套餐变更这一动作本身触发。
它是按比例分摊,不是客户投诉
当订阅者在一个计费周期中途升级到更高档位时,他其实已按旧价格付到了这个周期的结束。商店会为他补偿未使用的那部分。Apple 会按比例退还原订阅的金额。Google Play 会把未使用的价值抵扣到新套餐上。两者都不经过一个你能回应的流程,也都不等你批准。
只有升级才会触发它
变更的方向决定了钱怎么走。在 App Store 上,升级是指换到同一订阅组内排名更高的产品,只有这一动作是立即生效并退款的。降级是指换到排名更低的产品,它会在下一个续订时生效,且不退款。同级切换是指在同一排名的产品之间更换,其生效时间取决于所涉及的时长。如果你在 App Store Connect 里把产品排名排错了,一次你以为是升级的变更就会表现得像别的东西。
| App Store 变更 | 生效时间 | 资金如何处理 |
|---|---|---|
| 升级到更高档位 | 立即 | Apple 按比例退还原订阅的相应金额 |
| 降级到更低档位 | 在下一个续订日 | 不退款,按更低价格续订 |
| 同级切换,预付时长相同 | 立即 | 开始新订阅,付费服务继续 |
| 同级切换,时长不同 | 在下一个续订日 | 周期中不退款 |
App Store 为何对你的服务器隐藏升级退款
接下来是让收入报告失真的那一部分。Apple 发放了升级退款,却从不告诉你的服务器它退了多少。
isUpgraded 是唯一的信号,而价格是错的
新交易到达时带有设为 true 的 isUpgraded,它告诉你发生了一次套餐变更。那笔交易上的价格字段仍显示新档位的完整标示价,而不是 Apple 从旧档位收回的金额。没有任何 App Store Server Notification 携带这个退款数字。用 Apple 自己在开发者论坛上的话说,按比例退款的金额无法通过 App Store Server API、Notifications 或 StoreKit 获取,而 App Store Connect 报告才是你所有财务核算用途的来源。
财务报告是唯一诚实的记录
App Store Connect 财务与销售报告会核算按比例的升级退款,因为正是这些报告决定了 Apple 实际付给你多少钱。这让它们成为任何曾经升级过的订阅者的唯一真实来源。从报告出发去做核算,把服务器事件当作权益信号,而不是收入。

它会让你付出多少钱
升级退款不是一个可以忽略的舍入误差。它是实实在在的收入,而在 Google Play 上,你还要选择放弃多少未使用的时长。
退款是你已经入账的收入
假设一位订阅者在你的 9.99 每月档位上,在一个 30 day cycle 的 day 20 升级到 19.99。这个月大约三分之一还没用完,因此 Apple 会从原来的 9.99 中退还约 3.33。你并没有丢掉整笔销售。你退回的是客户预付却用不到的那一部分。关键在于,这笔退还是自动发生的,而且落在旧的那笔销售上,所以你已经算进去的收入会在事后缩水。把它乘以每一位在周期中途升级的订阅者,它就成了一条你本应看得见的账目,而不是你在结算时才发现的缺口。
在 Google Play 上,替换模式才是真正的成本杠杆
在升级时,Google Play 不会把钱退回到卡里。它会以几种方式之一来结算未使用的时长,而你在发起购买流程时通过传入一个替换模式来选择用哪一种。这个选择决定了你是把付费时长送给客户,还是向他收取差价。Google 建议升级用 CHARGE_PRORATED_PRICE,降级用 DEFERRED,但库的默认值是 WITH_TIME_PRORATION,所以一个你从未配置过的流程正在悄悄地抵扣时长。
| Google Play 替换模式 | 生效时间 | 未使用时长如何处理 |
|---|---|---|
| WITH_TIME_PRORATION(默认) | 立即 | 作为额外时长记入新套餐,下一个扣费日顺延 |
| CHARGE_PRORATED_PRICE(仅升级) | 立即 | 立即收取剩余周期的差价,扣费日不变 |
| WITHOUT_PRORATION | 立即 | 当前不结算,新价格从下一个续订开始生效 |
| CHARGE_FULL_PRICE | 立即 | 立即收取新套餐全价,剩余价值结转或按比例处理 |
| DEFERRED | 在下一个续订 | 当前套餐运行至到期,然后开始新套餐 |
如何不让升级退款给你的账目带来意外
你无法关闭按比例分摊,你也不会想关,因为正是它让套餐变更对客户公平。你能做的是看见它、给它定价,并把它和你真正能申诉的退款分开。
把 Apple 升级与财务报告对账
由于退款金额从不到达你的服务器,App Store Connect 财务与销售报告是按比例升级退款唯一出现的地方。每个周期都把订阅者收入拿去和这些报告对账,不要用 Server Notifications 的累计流水去计算收入。isUpgraded 标记告诉你发生了一次变更。报告告诉你它的代价是多少。
有意识地选择 Google Play 替换模式
为每一次套餐变更都刻意传入一个替换模式。当你想在升级时立即收取价格差额,就用 CHARGE_PRORATED_PRICE。只有当你确实想把剩余时长送给客户时,才保留 WITH_TIME_PRORATION。降级用 DEFERRED,这样你能在期限结束前保住当前收入。默认值是一个决定,而错误的默认值会让利润随着每一次升级一点点被送掉。
把升级退款与你能申诉的退款分开
升级退款在设计上就是自动且最终的。它不是客户要求退钱。你真正能影响的是客户主动发起的退款,也就是 Apple 发来 CONSUMPTION_REQUEST 并给你 12 hours 回应的那种,以及 Google Play 通过 orders.reviewrefund 开启拒付审查、给你 24 hours 窗口的那种。给你的数据打上标签,让这两者永远不会混在一起。一条是你去对账的账目。另一条是你要在限时内回应的账目。
简短版
当客户升级订阅时,商店会自动为他结算未使用的时长。Apple 立即按比例退还旧套餐的金额,且从不把这个数字发给你的服务器,因此 App Store Connect 财务报告是唯一准确的记录。Google Play 会抵扣时长或收取差价,取决于你设置的替换模式,而默认设置会把付费时长交给客户,由你按成本交付。这一切都不经过 CONSUMPTION_REQUEST 或拒付审查,因此没有什么可申诉的。把升级退款对好账,有意识地设置你的 Google Play 模式,并把它和你仍然能去争的退款分开。
常见问题解答
- 订阅升级退款会征求我的同意吗?
- 不会。订阅升级退款是自动的。当客户在周期中途升级到更高档位时,商店会自行结算旧套餐上未使用的时长,不会向你发出任何请求,也没有回应的窗口。Apple 按比例退还原订阅的金额,Google Play 则根据你设置的替换模式,抵扣未使用的时长或收取价格差额。
- 为什么升级之后我的 App Store 收入和结算金额对不上?
- 因为 Apple 不会把升级退款的金额发送到你的服务器。升级后的交易带有设为 true 的 isUpgraded,但价格字段仍显示新档位的全价,也没有任何 App Store Server Notification 包含退款。用服务器事件算出的收入计入了新销售,却漏掉了旧套餐上的退款,所以在你拿它去和 App Store Connect 财务报告对账之前,它会一直偏高。
- 客户升级时,Google Play 会把钱退回到卡里吗?
- 不会。Google Play 把未使用的时长当作抵扣,而不是现金退款。根据替换模式,它要么把剩余时长抵扣到新套餐上并顺延下一个扣费日,要么收取剩余周期的价格差额。默认模式是 WITH_TIME_PRORATION,它抵扣时长。
- 我可以申诉一笔订阅升级退款吗?
- 不可以。升级退款不是客户的退款申请。没有来自 Apple 的 CONSUMPTION_REQUEST,也没有来自 Google Play 的拒付审查,因此没有 12 hours 或 24 hours 的窗口,也没有可以提交的内容。升级退款你只需对账。你只对客户主动发起的退款和拒付进行申诉。
- 降级会给客户退款吗?
- 不会。在 App Store 上,降级在下一个续订日生效,且不退任何款,因为客户会保留更高的档位直到付费周期结束。在 Google Play 上,处理降级推荐的方式是 DEFERRED 替换模式,它会保留当前套餐直到到期,然后再启动更低的那一个。
- 升级时我应该用哪个 Google Play 替换模式?
- Google 建议升级用 CHARGE_PRORATED_PRICE,它会立即收取剩余周期的价格差额,并让扣费日保持不变。默认的 WITH_TIME_PRORATION 则会把未使用的时长作为更高档位上的额外服务抵扣掉,所以只有当你确实想把这段时长送出去时才使用它。
来源和延伸阅读
- Apple Developer: Auto-renewable subscriptions (upgrade, downgrade, and crossgrade behavior and prorated refunds)
- Apple Developer Forums: Retrieving the prorated refund amount after an upgrade (Apple staff on isUpgraded, the price field, and financial reports as the source)
- Android Developers: BillingFlowParams.SubscriptionUpdateParams.ReplacementMode (all replacement mode constants)
- Android Developers: About subscriptions (proration, default replacement mode, upgrade and downgrade recommendations)
- Google Play Developer API: Method orders.reviewrefund (chargeback review, 24 hours)
- Apple Developer: Send Consumption Information (CONSUMPTION_REQUEST response window)
RefundHalt
App Store 和 Google Play 退款自动驾驶
继续阅读
儿童未经授权的应用内购买几乎每次都会退款给家长,而成本由你承担
当孩子在家长的手机上购买一个金币包时,Apple 和 Google 都会退款,而且都不会先征询你的意见。监管机构就是这样设计的。下面介绍这些未经授权的应用内购买退款在每个商店如何运作、资金流失的那 15 分钟窗口,以及一次退款到底会让你付出多少代价。
应用退款税从来不是你的,所以退款损失的是你的那一份,而不是收据上的总额
为一笔应用内购买办理退款,收据上会显示价格加税一并退回。那笔税从来都不是你的钱。Apple 和 Google 作为登记商户负责收取并上缴,退款时再以同样方式冲回,完全不动你的那一份。这篇讲清楚一笔退款到底损失多少,以及唯一一种让税变成你责任的设置。