所有文章
深度解析閱讀時間 8 分鐘

Advanced Commerce API 退款是 iOS 開發者能主動發起退款的唯一管道,但最後拍板的仍是 Apple

多數 iOS 開發者沒辦法替顧客退款。使用 Apple Advanced Commerce API 的 App 可以提出退款請求、撤銷訂閱,或退回自訂金額。本文說明各個端點怎麼運作、Apple 仍可能拒絕什麼,以及金流最容易在哪裡出錯。

一名女性坐在居家辦公桌前,用筆電旁的 iPad 瀏覽龐大的有聲書與課程庫。這類大型目錄 App 可以向 Apple 送出 Advanced Commerce API 退款請求

重點摘要

  • 一位 Apple 工程師在 2026 年 6 月表示,一般的 App Store 購買,開發者無法直接退款。開發者唯一能提供的,是回覆 CONSUMPTION_REQUEST 時送出的使用資料與 refundPreference。
  • 獲准使用 Apple Advanced Commerce API 的 App,可以透過 Request Transaction Refund 端點,請 App Store 退還單次收費或訂閱交易的款項,另外還有 Revoke Subscription 與 Cancel a Subscription 端點。
  • 要呼叫 Advanced Commerce API 的退款、撤銷與取消端點,開發者的 Account Holder 必須簽署 Advanced Commerce API Addendum(增補條款)。Apple 表示,若尚未接受最新版本,呼叫會回傳錯誤。
  • Request Transaction Refund 端點的 refundType 可以是 FULL、PRORATED 或 CUSTOM。以幣別千分之一為單位的 refundAmount 只能搭配 CUSTOM 使用。Apple 表示,除了加拿大與美國,其他所有地區的金額都必須含稅。
  • Apple 的 refundRiskingPreference 欄位預設為 true,App Store 因此可以針對開發者自己提出的退款請求傳送 CONSUMPTION_REQUEST。Apple 要求在 12 小時內回覆。
  • Advanced Commerce API 的退款、撤銷與取消端點,在正式環境中每個 App 每秒上限 5 個請求,沙盒環境只有其 10%。
  • Revoke Subscription 呼叫成功後,Apple 會傳送 REFUND 通知,並要求開發者以其中的 revocationDate 為準停止服務,而不是在通知送達前就停止。

一般 iOS 開發者無法替顧客退款。2026 年 6 月,一位 App Store Commerce Engineer 在開發者論壇上只用一句話回答這個問題:目前開發者無法直接退款。例外只有一個,就藏在 Advanced Commerce API 裡。經 Apple 核准的 App 可以送出 Advanced Commerce API 退款請求、撤銷訂閱並退款,或要求退回自訂金額。錢最後退不退,還是 Apple 說了算。

Advanced Commerce API 是什麼,誰能用

Apple 在 2025 年 1 月 23 日推出 Advanced Commerce API。它專門處理超大型目錄的 Apple App 內購買項目,涵蓋自訂的單次購買、訂閱,以及附帶選購加購項目的訂閱。你不必在 App Store Connect 裡一一建立商品,而是在自己的伺服器上定義 SKU,於購買當下傳給 Apple。

使用權限是逐一 App 核發的。你要填寫申請表單,而 Apple 的資格頁面列出三種必須是 App 核心業務的商業模式:

  • 超大型的單次購買目錄,例如有聲書、課堂、課程或小程式。
  • 超大型的訂閱內容目錄,每位創作者的內容各自是一個獨立訂閱。
  • 附帶選購加購項目的訂閱,加購項目與主訂閱合併為一筆購買一起續訂,例如付費頻道或運動賽事。

若其他計畫需要用到這個 API,Apple 也開放 App 申請。Mini Apps Partner Program 就要求使用它。這項計畫會把託管小程式中符合資格的 App 內購買銷售額的 85% 分給成員。

退款端點是後來才加的,而且要先簽約

2025 年 3 月 24 日的 1.1 版新增了 Request Transaction Refund 與 Revoke Subscription。Apple 的計畫頁面提到,提供訂閱內容的 App 也可能有資格使用 Cancel、Revoke 與 Refund API,用來處理取消、在購買後驗證內容,以及管理目錄。每個端點頁面都附上同一項條件:你的 Account Holder 必須簽署 Advanced Commerce API Addendum,若尚未接受最新版本,呼叫就會回傳錯誤。列出各端點適用情境的是 Addendum,不是技術文件。

三個端點一次比較

Cancel a SubscriptionRevoke SubscriptionRequest Transaction Refund
路徑advancedCommerce/v1/subscription/cancel/{transactionId}advancedCommerce/v1/subscription/revoke/{transactionId}advancedCommerce/v1/transaction/requestRefund/{transactionId}
適用對象自動續訂型訂閱整個訂閱及其所有項目單次收費與訂閱交易
退款無FULL 或 PRORATEDFULL、PRORATED 或 CUSTOM,依 SKU 而定
使用權限持續到本期結束於 revocationDate 終止以 revoke 旗標逐項設定
正式環境速率上限每秒 5 個每秒 5 個每秒 5 個

Cancel a Subscription 停止下一次扣款

Cancel 會關閉自動續訂。Apple 表示,顧客可以使用到本期結束。完全不退款。顧客想退訂、而且已經用完付費期間時,這是正確的做法。

Revoke Subscription 立即終止一切

Revoke 會把自動續訂設為 false,並以全額或按比例退款的方式撤銷訂閱。請求內容包含 refundReason、refundRiskingPreference、refundType 與 requestInfo。接著 Apple 會向你的 App Store Server Notifications V2 端點傳送 REFUND 通知。Apple 的指示很具體:以通知裡的 revocationDate 為準停止服務,不要在通知送達之前就停止。

Request Transaction Refund 逐項處理

這是最精準的工具。你送出一份項目清單,每一項都要指定 SKU、refundReason、refundType 與 revoke 旗標。使用 CUSTOM 時,還要以幣別千分之一為單位送出 refundAmount,所以 4990 代表 4.99。若在 FULL 或 PRORATED 時送出金額,Apple 會以錯誤 4000155 拒絕。回應會附上已簽署的交易資訊,訂閱則另附已簽署的續訂資訊。

Apple 接受的 refundReason 值有:UNINTENDED_PURCHASE、FULFILLMENT_ISSUE、UNSATISFIED_WITH_PURCHASE、LEGAL、OTHER 與 MODIFY_ITEMS_REFUND。第七個值 SIMULATE_REFUND_DECLINE 僅限沙盒與 TestFlight 測試使用。它之所以存在,正是因為 App Store 可以說不。

你自己提出的退款請求,Apple 照樣可以拒絕

這個端點的名稱很老實。它就是一個「請求」。有兩個欄位點出了決定權真正的所在。

refundRiskingPreference 會引來使用資料審查

Apple 對 refundRiskingPreference 的說明是:App Store 是否要向你索取使用資料,作為退款決定的參考。預設值為 true。設為 true 時,你會針對自己提出的退款請求收到 CONSUMPTION_REQUEST,並透過 Send Consumption Information 回覆。Apple 要求開發者在收到 CONSUMPTION_REQUEST 後 12 小時內回覆。設為 false,就不會收到這則通知。

告訴你「不行」的錯誤

錯誤代碼Apple 的說明
AlreadyRefundedError4030021此交易已退款
PendingRefundError4000181此交易有待處理的退款
TransactionNotRefundableError4030024此交易無法退款
TransactionCannotBeRefundedContactSupportError4030025顧客可以聯絡 Apple 支援
RefundAmountWithoutCustomError4000155未搭配 CUSTOM 卻送出了金額

最需要事先規劃的是 PendingRefundError。常見的情況是:你的客服團隊還沒處理,顧客就已經透過 Report a Problem 向 Apple 申請了。Apple 的資格規定本來就要求這類 App 在 App 內提供退款管道,可以是 Report a Problem 連結,也可以是 beginRefundRequest API,所以兩扇門會同時開著。

一位開發者把 iPhone 拿在列印出來的交易明細上方,核對這筆 Advanced Commerce API 退款該涵蓋哪個項目

Advanced Commerce API 退款實際要花你多少錢

主動退款感覺比處理爭議划算。但錢終究是流出去了,而且這個 API 很容易讓某些錯誤大規模重複發生。

自訂金額裡的稅

Apple 表示,請求的 refundAmount 必須含稅,加拿大與美國除外。若團隊用未稅的 SKU 價格計算 CUSTOM 退款,在其他所有店面都會少退顧客錢,之後還得花客服時間一筆一筆補正。

拿不回來的成本

  • 分潤:在創作者目錄或小程式託管平台上,創作者的分潤通常在銷售時就已付出。退款給顧客並不會把這筆錢收回來。
  • 內容授權:有聲書或課程按作品支付給權利人的費用,依合約不同,可能在使用時就已觸發,退款也不會讓費用倒退。
  • 運算資源:為這筆購買所做的串流、轉碼與各種伺服器運算,費用早已列入你的帳單。
  • API 呼叫:按次計費的第三方服務,從語音到模型推論,退款之後照樣要付。

只想退一項,卻整筆退掉

Revoke Subscription 會退款並終止整個訂閱,連加購項目也一併取消。如果顧客只對其中一個加購項目有異議,Request Transaction Refund 可以只退那個 SKU,並只對該項目設定 revoke。為了單一項目的客訴去呼叫 Revoke Subscription,會連基本方案的營收都一起退掉。

啟用前的開發檢查清單

  • 確認你的 Account Holder 已接受目前版本的 Advanced Commerce API Addendum,並針對條款失效時回傳的錯誤設定警示。
  • 每個請求都產生新的 requestReferenceId UUID,只有在重試逾時的呼叫時才沿用同一個。
  • 把退款呼叫排入佇列。上限是每個 App 每秒 5 個,429 回應會附上以 UNIX 毫秒表示的 Retry-After 標頭。
  • 在沙盒中用 SIMULATE_REFUND_DECLINE 測試遭拒的情況,並記得沙盒上限是正式環境的 10%。
  • 依個案決定 refundRiskingPreference。若維持 true,就要備妥使用資料回覆機制,趕上 12 小時的期限。
  • 等 REFUND 通知送達後才停止使用權限,並以其中的 revocationDate 為準。
  • 記錄每個請求的原因、金額與 SKU,讓你在 Apple 注意到之前,先看清自己的退款率。

常見問題解答

iOS 開發者可以直接替顧客退款嗎?
一般的 App Store 購買不行。一位 Apple 工程師在 2026 年 6 月表示,開發者無法直接退款。獲准使用 Advanced Commerce API 且已簽署 Addendum 的 App,可以透過 Request Transaction Refund 端點提出退款請求,但最後仍由 Apple 決定。
Advanced Commerce API 的 Cancel 與 Revoke 有什麼不同?
Cancel 會關閉自動續訂,顧客可以使用到本期結束,不會退款。Revoke 會立即終止訂閱及其所有項目,並退還全額或按比例計算的金額。撤銷後,Apple 會傳送 REFUND 通知。
可以用 Advanced Commerce API 退回自訂金額嗎?
可以。把 refundType 設為 CUSTOM,並以幣別千分之一為單位傳入 refundAmount。Apple 表示,除了加拿大與美國,其他所有地區的金額都必須含稅;若在 FULL 或 PRORATED 時送出金額,會回傳錯誤 4000155。
我自己提出的退款,也會收到 CONSUMPTION_REQUEST 嗎?
有可能。refundRiskingPreference 預設為 true,App Store 因此可以透過 CONSUMPTION_REQUEST 向你索取使用資料,Apple 要求在 12 小時內回覆。設為 false,Apple 表示就不會傳送這則通知。
為什麼我的 Advanced Commerce API 退款請求失敗了?
先看錯誤代碼。4030021 代表交易已退款,4000181 代表已有待處理的退款,4030024 代表無法退款,4030025 代表顧客應聯絡 Apple 支援。Addendum 未簽署或版本過舊,也會回傳錯誤。

資料來源與延伸閱讀

RefundHalt

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

繼續閱讀

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

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