每一筆訂閱升級退款都由商店決定,不由你決定,而且直接從你的收入中扣除
當客戶升級到更高層級時,商店會為舊方案上未使用的天數發放一筆訂閱升級退款,並自動減少你的收入。本文說清升級退款在 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 的退款自動駕駛
繼續閱讀
過多的退款申請,代價可能遠超退款本身,因為兩大 App 商店都把它視為品質訊號
Apple 審查準則 5.6.4 把過多的退款申請列為 App 未達品質標準的跡象,Google 的開發人員發布協議也允許它依退款率下架新開發人員的 App。本文整理兩家商店的原文、下架的實際成本,以及如何避開風險。
在處理退款之前先驗證 App Store 伺服器通知,因為任何人都能向你的 webhook URL 發送請求
在檢查簽章之前,一則退款通知只不過是一個 HTTPS 請求。本文說明如何驗證 App Store 伺服器通知和 Google Play RTDN 訊息、各商店簽署的內容,以及偽造的退款或遭錯誤拒絕的退款會讓你付出什麼代價。