所有文章
Playbook閱讀時間 8 分鐘

如果你的 App 仍在使用 App Store Server Notifications V1,Apple 永遠不會就訂閱退款徵詢你的意見

Apple 於 2023 年 6 月棄用了 App Store Server Notifications V1,而 V1 從未獲得訂閱的 CONSUMPTION_REQUEST、REFUND_DECLINED 或 REFUND_REVERSED。本文說明 V1 伺服器會錯過什麼、代價有多高,以及如何在不漏掉任何一筆退款的情況下遷移到 V2。

一個塞滿未拆信件的舊信箱,旁邊是一座現代伺服器機櫃,象徵在 App Store Server Notifications V1 上遺失的退款訊號

重點摘要

  • Apple 於 2023 年 6 月 5 日棄用了 App Store Server Notifications V1 與 verifyReceipt 端點。兩者目前仍可使用,但不再獲得任何新功能,也沒有公布終止支援日期。
  • Apple 的 V1 文件只針對消耗性 App 內購買列出 CONSUMPTION_REQUEST。針對自動續訂型訂閱的消耗資訊請求於 2024 年 4 月加入 App Store Server Notifications V2。
  • REFUND_DECLINED 與 REFUND_REVERSED 只存在於 App Store Server Notifications V2,因此 V1 伺服器永遠不會得知 Apple 拒絕了退款,或撤回了已核准的退款。
  • 在 V1 上,Apple 對自動續訂型訂閱的退款會以 CANCEL 送達。在 V2 上則以 REFUND 送達,並在簽署的交易中附上 revocationDate 與 revocationReason。
  • V2 通知傳送失敗時,Apple 會在大約一週內重試五次,分別在 1、12、24、48 與 72 小時後。V1 通知失敗只會重試三次,分別在 6、24 與 48 小時後,而且無法透過 Get Notification History 找回。
  • App 在 App Store Connect 中切換到 V2 後,新通知會立即以 V2 格式送達,而已在重試中的 V1 通知仍可能在約 78 小時內陸續抵達。

App Store Server Notifications 的 Version 1 仍會傳送退款通知,但它少了唯一一種能讓你為訂閱退款據理力爭的通知。Apple 於 2023 年 6 月 5 日棄用了 V1,同時棄用的還有 verifyReceipt 端點,此後新增的每一項退款功能都只加入 V2。如果你的 App Store Connect 設定仍顯示 Version 1,Apple 就能在從未向你的伺服器傳送 CONSUMPTION_REQUEST 的情況下決定訂閱退款。你不是在這場爭論中輸了,而是從一開始就沒有受邀參與。

Apple 棄用 App Store Server Notifications V1 代表什麼

棄用並不等於關閉。一位 Apple 工程師於 2023 年 6 月在開發者論壇上寫道,verifyReceipt 與 V1 通知會持續運作,直到公布終止支援日期為止,該日期尚未確定,而且會事先通知開發者。三年多過去了,設定伺服器 URL 時,App Store Connect 仍提供 "Version 1 (deprecated)" 這個選項。

棄用真正代表的是凍結。自 2023 年 6 月以來,Apple 通知更新紀錄中的每一項變更都是 V2 的變更:簽署交易中的新欄位、新的通知類型,以及 2026 年 4 月加入的 12 個月承諾資料。V1 伺服器一項都看不到。

V1 伺服器永遠收不到哪些退款訊號

根據 Apple 針對各版本的文件,同樣的退款事件會以下列方式分別送達 V1 伺服器與 V2 伺服器。

退款事件Version 1Version 2
顧客向 Apple 申請消耗性項目退款CONSUMPTION_REQUESTCONSUMPTION_REQUEST
顧客向 Apple 申請自動續訂型訂閱退款V1 文件中未列出CONSUMPTION_REQUEST,自 2024 年 4 月起
Apple 為自動續訂型訂閱退款CANCELREFUND
Apple 為消耗性項目、非消耗性項目或非續訂型訂閱退款REFUNDREFUND
Apple 拒絕顧客在你的 App 內發起的退款不提供REFUND_DECLINED
Apple 撤回已核准的退款不提供REFUND_REVERSED
找回服務中斷期間錯過的通知不提供Get Notification History

V1 還收得到 CONSUMPTION_REQUEST 嗎?

收得到,但僅限消耗性項目。Apple 的 V1 參考文件將 CONSUMPTION_REQUEST 描述為顧客針對消耗性 App 內購買發起退款申請時傳送的通知。一位 Apple 工程師於 2023 年在論壇上確認,V1 的消耗資訊請求會在符合資格的退款中觸發。缺口在於訂閱。Apple 的更新紀錄顯示,訂閱的消耗資訊請求於 2024 年 4 月 11 日在 V2 推出,而 Send Consumption Information 文件也說明,Apple 會透過你的 V2 端點傳送這項請求。

為什麼 V1 上的 CANCEL 容易被誤判

在 V1 上,當 Apple 為訂閱退款時,通知類型是 CANCEL,而且常常伴隨 DID_CHANGE_RENEWAL_STATUS。許多伺服器會把任何取消都當成顧客關閉了自動續訂,於是存取權限會一直保留到當期結束。V2 消除了這種模糊空間。退款以 REFUND 送達,顧客關閉續訂則以 DID_CHANGE_RENEWAL_STATUS 加上子類型 AUTO_RENEW_DISABLED 送達。

繼續使用 V1 在金錢上的代價

每一筆 App Store 退款都由 Apple 決定。CONSUMPTION_REQUEST 是你的使用資料進入這項決策的唯一途徑,Apple 要求你在 12 小時內回覆。在 V1 上,訂閱退款會跳過這個步驟。

以下用示意數字舉例說明。假設你的 App 販售每月 $9.99 的訂閱,內含 AI 圖像生成。某位訂閱者一個月內生成了 400 張圖像,每一次都會產生實際的模型推論成本。接著,他向 Apple 申請退款。

成本項目V1 伺服器V2 伺服器
你在這筆付款中的分潤若 Apple 核准則退還若 Apple 核准則退還
當月使用的運算、API 呼叫與儲存空間已支付,無法收回已支付,無法收回
向 Apple 展示這 400 次生成的機會沒有一次 CONSUMPTION_REQUEST,12 小時
得知 Apple 拒絕了退款永遠不會REFUND_DECLINED
得知退款已被撤回永遠不會REFUND_REVERSED

你損失的是自己的分潤,而不是標價。在訂閱者付費服務的第一年,Apple 會支付訂閱價格的 70%(扣除適用稅金),此後或對 App Store Small Business Program 的成員則為 85%。運算帳單卻不會跟著減少。推論、第三方 API 呼叫與檔案儲存,早在顧客使用時就已經付費了。

缺少的兩種結果通知同樣會造成損失。少了 REFUND_REVERSED,因退款而撤銷存取權限的伺服器在 Apple 撤回退款後永遠不會恢復權限,於是付費顧客一直被擋在門外,只好聯絡客服。少了 REFUND_DECLINED,你就無法分辨仍在處理中的退款與已被 Apple 拒絕的退款。

一位開發者的雙手將網路線從舊配線架的連接埠移到新的連接埠,旁邊是一台打開的筆記型電腦

如何從 V1 遷移到 V2,而不漏掉任何一筆退款

遷移到 V2 只需要修改伺服器,再加上一項設定。Apple 在論壇上的官方指引來自一位 App Store Commerce 工程師,發表於 2025 年 12 月,說明了切換當天會發生什麼事。

在切換設定之前先建好 V2 端點

  • 接受請求本文中帶有 signedPayload 的 POST 請求。V2 酬載是由 Apple 簽署的 JWS,因此在信任其中任何內容之前,請先驗證簽章。Apple 的 App Store Server Library 可以替你完成這件事。
  • 將原本的 CANCEL 處理邏輯對應到 REFUND,並把 REFUND_DECLINED 與 REFUND_REVERSED 當作新情況處理。
  • 使用 Send Consumption Information 回覆訂閱的 CONSUMPTION_REQUEST,而且只在顧客同意與 Apple 分享資料時回覆。Apple 表示,未取得同意時不應回覆。
  • 成功時回傳 HTTP 200 到 206。任何 40x 或 50x 都會讓 Apple 重試。

在 App Store Connect 中切換設定

在 App Store Connect 中開啟你的 App,在 "General" 下選擇 "App Information",找到 App Store Server Notifications,將 "Production Server URL" 設為你的 V2 端點,並選擇 Version 2。如果想先測試,可以先對沙盒 URL 做同樣的設定,再用 Request a Test Notification 確認你的伺服器能正常回應。

讓 V1 處理程式繼續運作約三天

切換之後,新通知會立即以 V2 格式送達,不論新舊訂閱都一樣。已在重試中的 V1 通知會繼續以 V1 格式抵達,直到成功或重試次數用完為止。Apple 表示最後一次可能的 V1 重試約在 78 小時後,也就是 6 加 24 加 48。請讓舊的處理程式運作超過這段時間,再將它移除。

順便替換 verifyReceipt

verifyReceipt 也在同一天遭到棄用。它仍會回應,但 Apple 建議伺服器改用 App Store Server API。Get Transaction Info 會回傳單筆簽署交易,Get Transaction History 會回傳顧客的交易紀錄,Get Refund History 則列出某位顧客所有已退款的購買項目。搭配 V2 通知,這些 API 足以涵蓋多數伺服器過去用收據完成的工作,包括以前在收據中標示退款的 cancellation_date 欄位。

RefundHalt 串接 App Store Server Notifications V2,並運用你的 App 已記錄的使用資料,在 12 小時時限內回覆每一個 CONSUMPTION_REQUEST。如果你仍在使用 V1,切換版本正是讓這一切得以實現的那一步。

常見問題解答

App Store Server Notifications V1 會被關閉嗎?
目前還不會。Apple 於 2023 年 6 月 5 日棄用了 V1 與 verifyReceipt,兩者目前仍可使用。Apple 表示尚無終止支援日期,並會事先通知開發者。在此期間,V1 不會獲得任何新功能。
在 V1 上收得到 CONSUMPTION_REQUEST 通知嗎?
根據 Apple 的 V1 文件,僅限消耗性項目。針對自動續訂型訂閱的消耗資訊請求於 2024 年 4 月加入 V2,Apple 會透過你的 V2 端點傳送。如果你販售訂閱卻仍使用 V1,就無法回覆這些退款申請。
訂閱退款在 V1 與 V2 上分別長什麼樣子?
在 V1 上,它以 CANCEL 送達,常常伴隨 DID_CHANGE_RENEWAL_STATUS。在 V2 上,它以 REFUND 送達,並在簽署的交易中附上 revocationDate 與 revocationReason。當 Apple 拒絕在你的 App 內發起的退款時,V2 還會傳送 REFUND_DECLINED;當 Apple 撤回已核准的退款時,則會傳送 REFUND_REVERSED。
從 V1 切換到 V2 時,通知會發生什麼事?
切換後不久,所有訂閱的新通知都會以 V2 格式送達。已在重試中的 V1 通知會繼續以 V1 格式抵達,直到成功或重試次數用完為止,Apple 表示這大約會持續到切換後 78 小時。在這段期間內,請讓兩個處理程式同時運作。
切換到 V2 之後還能回到 V1 嗎?
可以,依照 Apple 技術說明 TN3180 的描述,透過 App Store Connect API 的 Modify an App 端點即可。Apple 稱這屬於特殊情況,並仍將 V1 標示為已棄用,因此退回代表放棄訂閱的消耗資訊請求以及較新的退款通知。

資料來源與延伸閱讀

RefundHalt

App Store 與 Google Play 的退款自動駕駛

繼續閱讀

下一筆退款申請已經在路上。

讀完另一封關於未能抗辯退款的客服郵件所需的時間,就足夠您設定好 RefundHalt。