跳到內容

撥款指示 API

在 ChatGPT 開啟在 Claude 開啟

一般商家由應援依撥款頻率自動撥款。被應援設定為指示制撥款的商家,每一期要自己送出撥款指示,應援才會把款項撥給你。撥款指示 API(Partner Payout API)讓你的系統查詢目前可以撥的交易、決定這一期撥到哪一筆、送出指示,之後用查詢或 webhook 追蹤銀行的處理結果。

  1. 查詢可撥交易:GET …/available-transactions 回傳這一期的結算區間、可撥金額,以及可撥交易清單(最舊的在前)。
  2. 送出撥款指示:POST …/instructions 用 lastTransactionId 指定撥到哪一筆,比它早的可撥交易會一起包含進來;也可以送 ALL 撥全部。這些交易會被這張指示預留,不會再出現在可撥清單;指示有結果之前,被預留的交易不能退款,要退款請先取消指示。
  3. 應援在執行日處理:指示從 pending 變成 processing(已產生銀行匯款檔),銀行回覆成功後變成 executed,失敗則是 failed。同一個網域一次只處理一張指示,執行日較早的先處理,其餘的可能延到下一次。
  4. 追蹤結果:用查詢單張指示或 webhook 取得狀態。指示 failed 或 cancelled 時會釋放預留,仍符合撥款條件的交易會回到可撥清單,可以在下一期再送。

撥款完成後,交易在 Payment API 查詢的狀態會變成 claimed(已入帳,見 Transaction 物件)。

環境 Base URL
正式環境 https://api.oen.tw/partner-payout/v1

所有路徑都以 /domain/{domain} 開頭,{domain} 是你的網域名稱。例如應援頁是 https://ming.oen.tw,就填 ming。

每個請求都要帶:

Authorization: Bearer <access token>
  • access token 由應援的 OAuth 服務(https://openapi.oen.tw)核發。開通時,應援會為你建立帶 merchant:payout 權限的 OAuth client,並提供取得與更新 token 的方式。
  • 完成授權的 CRM 帳號必須是這個網域的管理員。
  • 以下情況一律回 401 X022:token 無效或過期、沒有 merchant:payout 權限、授權帳號不是 {domain} 的管理員,或應援已停用這個 OAuth client、移除它的權限。後兩種情況重新取得 token 也無法解決,請聯絡應援確認開通狀態。
  • CRM 產生的 Payment API token 不能用在這支 API。
  • 請求與回應都是 JSON(UTF-8)。金額是新台幣整數(元),currency 一律是 TWD。
  • 時間格式是 ISO 8601。submittedAt、executedAt 是 UTC(結尾 Z);結算區間的 start、end 帶台北時區(+08:00);executionDate 是台北日期 yyyy-MM-dd。請用一般的 ISO 8601 解析,不要假設一定以 Z 結尾。

成功的回應一律包在 data 裡。單筆資料是物件,指示列表是陣列,並多一個 paging:

{ "data": { "instructionId": "pi_2sTk9Yx3Qm7bV1nWc4Rz8Lp0FhA", "status": "pending", "...": "..." } }
{ "data": [ { "instructionId": "pi_2sTk9Yx3Qm7bV1nWc4Rz8Lp0FhA", "...": "..." } ], "paging": { "next": null } }

業務錯誤帶 error 與 errno,部分錯誤另有 detail。正式環境不回 message。

{
"error": "instruction_already_exists",
"errno": "PY003"
}

少數錯誤沒有 errno,請一定也看 HTTP 狀態碼:

  • body 欄位格式不對時回 400,detail.fieldValidationErrors 會指出是哪個欄位。
  • body 不是合法的 JSON 時回 400 X027。
  • PUT、PATCH 等這支 API 完全不接受的 method 回 405 { "error": "method_not_allowed" };GET、POST、DELETE 用在不支援的路徑(例如 POST …/available-transactions)則回 404 X024。

各個 errno 的意思見錯誤碼。

指示制撥款每週撥款一次,執行日是星期五;星期五遇到銀行休息日時,順延到下一個銀行營業日。

送出指示的時間(台北時間) 執行日
星期四 12:00:00 以前 當週星期五
星期四 12:00:00 起(含週末) 下週星期五
  • 每張指示都屬於一個結算區間:以這一期原定的星期五計算,從往前 8 天的 00:00 到往前 2 天的 23:59:59.999(星期四到星期三)。回應的 settlementWindow 就是這個區間。
  • 銀行休息日只會順延 executionDate,不會改變結算區間與星期四中午的截止時間。例如 2026 年 10 月 9 日(星期五)銀行休息,那一期的執行日是 10 月 12 日,結算區間仍是 10 月 1 日到 10 月 7 日。
  • 每個網域在同一個結算區間只能有一張指示,已取消或失敗的指示也算。同一期再送會被拒絕,通常回 409 PY003;如果交易都已被第一張預留,可能會先回 PY004 或 PY007。交易要等下一期再送。
  • 結算區間只用來標示「這是哪一期的指示」,不限制可以撥哪些交易。可撥的交易見下一節。

可撥清單裡的交易同時符合:

  • 狀態是 charged(付款成功、等待撥款)。
  • 還沒撥款、沒有被其他指示預留,也沒有進行中或結果未定的退款。
  • 已過保留期:交易建立時間(sortAt)在「今天往前 7 天的台北時間 0 點」(含)以前。例如 10 月 1 日白天建立的交易,10 月 9 日起才會出現在清單。政治獻金擬參選人的網域是 3 天。

清單依 sortAt 由舊到新排序。還在保留期的交易不會出現;拿它當 lastTransactionId 會回 400 PY006。

欄位 說明
gross 可撥交易的金額合計,加上符合條件的「已退款、還沒撥款」交易的原始金額。這類交易要有退款時間紀錄,而且退款時間在「今天往前 7 天的台北時間 0 點」(含)以前才計入;款項由收單機構直接撥給你的付款方式(例如 LINE Pay、藍新)不列入
reserved 已被指示預留、還沒撥款的交易金額合計,不計入 netAvailable
adjustmentDeduction 撥款後才退款、還沒從撥款扣回的金額。這筆扣回紀錄本身也要過了保留期才會計入,剛產生的不會立即反映
netAvailable gross 扣掉上述交易的退款金額,再扣 adjustmentDeduction。可能是 0 或負數
currency TWD
partial true 表示這次沒有讀完(交易太多或讀取超過時間),清單只有最舊的一部分,金額可能偏高或偏低。false 才表示這次讀完了
  • 即使 partial 是 false,金額仍受上述時間條件限制:adjustmentDeduction 是 0 不代表所有待扣回的款項都已結清,較早的歷史退款也可能不在這個試算裡。對金額有疑問請洽應援。
  • 部分退款後剩下的金額,符合上述條件才會計入 netAvailable;這些交易不在可撥清單、不能逐筆指定,所以 netAvailable 可能和清單金額合計不同。netAvailable 只是查詢當下的試算,不是實際匯款金額。
  • 這次算出的 adjustmentDeduction 大於 0 時,目前無法送出指示:送出會回 422 PY004,detail.reason 是 unpaid_adjustments。請聯絡應援處理。
  • partial 是 true 時,見讀取不完整時。
Method 路徑 說明
GET /domain/{domain}/available-transactions 查詢可撥交易
POST /domain/{domain}/instructions 送出撥款指示
GET /domain/{domain}/instructions 查詢指示列表
GET /domain/{domain}/instructions/{instructionId} 查詢單張指示
DELETE /domain/{domain}/instructions/{instructionId} 取消指示

各端點列出的錯誤之外,都可能回 X022、X030、5xx,以及共通規格提到的格式錯誤。

GET /domain/{domain}/available-transactions

終端機視窗
curl "https://api.oen.tw/partner-payout/v1/domain/ming/available-transactions" \
-H "Authorization: Bearer $OEN_PAYOUT_TOKEN"

回應 200:

{
"data": {
"settlementWindow": {
"start": "2026-09-03T00:00:00.000+08:00",
"end": "2026-09-09T23:59:59.999+08:00",
"executionDate": "2026-09-11"
},
"balance": {
"gross": 14300,
"reserved": 3500,
"adjustmentDeduction": 0,
"netAvailable": 13800,
"currency": "TWD",
"partial": false
},
"transactions": [
{ "transactionId": "2sTjQ8vLx0Kq9Wm3Yb7Rn1Zc5Fd", "orderId": "O0820K3M7P2QX", "amount": 1200, "paidAt": "2026-08-20T03:12:44.000Z", "sortAt": "2026-08-20T03:12:40.512Z", "status": "charged" },
{ "transactionId": "2sTnB4cHy2Pw6Vd8Lq1Xr9Ma3Ge", "orderId": "O0824R1S8T4VZ", "amount": 3600, "paidAt": "2026-08-24T10:05:02.000Z", "sortAt": "2026-08-24T10:04:58.107Z", "status": "charged" },
{ "transactionId": "2sTpF7dJz5Rt2Wg4Nk8Ys6Bh1Ci", "orderId": "O0827W6X2Y9AB", "amount": 8000, "paidAt": "2026-08-27T14:41:19.000Z", "sortAt": "2026-08-27T14:41:15.330Z", "status": "charged" }
],
"nextCursor": null
}
}
欄位 說明
settlementWindow 現在送出指示會歸到的結算區間與執行日
balance 見 balance 欄位
transactions[].transactionId 交易的內部 id(27 字元),跟 Payment API Transaction 物件的 transactionId 相同,不是 P 開頭的 id
transactions[].orderId 交易上的訂單編號。用 Payment API 建立的交易是你帶的 orderId;其他來源的交易可能沒有這個欄位
transactions[].amount 交易金額
transactions[].paidAt 付款時間;沒有記錄時欄位不會出現
transactions[].sortAt 交易建立時間(UTC)。清單排序與保留期都以這個欄位為準
transactions[].status 一律是 charged
nextCursor 目前固定是 null,這個端點沒有分頁。是否讀完請看 balance.partial

可能的錯誤:PY002、PY009、X024。

POST /domain/{domain}/instructions

Header 除了 Authorization,還要帶 Content-Type: application/json 與 Idempotency-Key(見 Idempotency-Key)。

Body 欄位 必填 說明
lastTransactionId 必填 撥到哪一筆交易(含)。比它早的可撥交易會全部包含,不能跳過。送 ALL 表示可撥清單全部。1 到 128 字元,不能帶其他欄位
終端機視窗
curl -X POST "https://api.oen.tw/partner-payout/v1/domain/ming/instructions" \
-H "Authorization: Bearer $OEN_PAYOUT_TOKEN" \
-H "Idempotency-Key: 9f1c2a7e-4b1d-4e2a-bc77-2f0e1d3a9c01" \
-H "Content-Type: application/json" \
-d '{ "lastTransactionId": "2sTnB4cHy2Pw6Vd8Lq1Xr9Ma3Ge" }'

回應 201,data 是建立好的指示:

{
"data": {
"instructionId": "pi_2sTk9Yx3Qm7bV1nWc4Rz8Lp0FhA",
"status": "pending",
"settlementWindow": {
"start": "2026-09-03T00:00:00.000+08:00",
"end": "2026-09-09T23:59:59.999+08:00",
"executionDate": "2026-09-11"
},
"executionDate": "2026-09-11",
"transactionIds": ["2sTjQ8vLx0Kq9Wm3Yb7Rn1Zc5Fd", "2sTnB4cHy2Pw6Vd8Lq1Xr9Ma3Ge"],
"transactionCount": 2,
"totalAmount": 4800,
"currency": "TWD",
"submittedAt": "2026-09-05T02:30:11.412Z",
"executedAt": null,
"failureCode": null,
"failureMessage": null
}
}

送出時依下列順序檢查,前面的檢查沒通過,就不會回後面的錯誤:

  1. 網域設定:不是指示制撥款 PY002、撥款未啟用或被暫停 PY011、撥款頻率不是每週五 PY009。
  2. 來源 IP 頻率限制 X030。
  3. Idempotency-Key:缺少或格式不對 X034、內容不符 PO004、處理中 PO005;同一把 key 已有結果就直接回那個結果。
  4. 網域的頻率限制 X030。
  5. 有撥款後退款還沒扣回:PY004(detail.reason 是 unpaid_adjustments)。
  6. lastTransactionId:
    • ALL:讀取不完整時 PY013;沒有可撥交易時 PY004。
    • 指定交易:查不到或不是這個網域的交易 PY005;還在保留期 PY006;讀取不完整、無法確認時 PY013;確定不能撥(已退款、退款處理中、已預留或已撥款)PY007,detail 帶 ineligibleId 與 status。
    • 超過 99 筆 PY008:請改用較早的交易當 lastTransactionId,其餘留到下一期。
  7. 建立指示:這一期已經有指示 PY003;有交易在這一刻剛被撥款、退款或預留 PY010,detail.transactionId 是那一筆。

交易很多或讀取太久時,系統只會讀到最舊的一部分(balance.partial 是 true)。這時:

  • 送 ALL 會回 422 PY013。
  • 指定的交易如果無法確認在已讀到的範圍內,也會回 PY013。
  • PY013 的 detail 帶 readableCount(讀到的可撥筆數)、lastReadableTransactionId、lastReadableSortAt;讀到 0 筆時後兩個是 null。
  • 請重新查詢可撥交易,用清單裡第 99 筆或更早的交易當 lastTransactionId,其餘留到下一期,或稍後再試。PY013 可以用同一把 Idempotency-Key 重送。

GET /domain/{domain}/instructions?limit={limit}&page={page}

查詢參數 說明
limit 每頁幾張,1 到 500,預設 100
page 下一頁的游標,原樣帶回上一頁回應的 paging.next。第一頁不用帶,也不要自己組

由新到舊排列。列表裡的指示不含 transactionIds,要看交易明細請用查詢單張指示。paging.next 是 null 時表示沒有下一頁。

{
"data": [
{
"instructionId": "pi_2sTk9Yx3Qm7bV1nWc4Rz8Lp0FhA",
"status": "pending",
"settlementWindow": { "start": "2026-09-03T00:00:00.000+08:00", "end": "2026-09-09T23:59:59.999+08:00", "executionDate": "2026-09-11" },
"executionDate": "2026-09-11",
"transactionCount": 2,
"totalAmount": 4800,
"currency": "TWD",
"submittedAt": "2026-09-05T02:30:11.412Z",
"executedAt": null,
"failureCode": null,
"failureMessage": null
}
],
"paging": { "next": null }
}

可能的錯誤:X024、X028、X034。

GET /domain/{domain}/instructions/{instructionId}

回應 200,data 是完整的指示(含 transactionIds)。不是這個網域的指示一律回 404 PY001。

{
"data": {
"instructionId": "pi_2sQe4Hb8Wn1Ks6Zt3Mv9Xc2RaAB",
"status": "failed",
"settlementWindow": { "start": "2026-08-27T00:00:00.000+08:00", "end": "2026-09-02T23:59:59.999+08:00", "executionDate": "2026-09-04" },
"executionDate": "2026-09-04",
"transactionIds": ["2sQa1Lm4Kp7Xw2Nc9Vb3Rt6Yh8J", "2sQb2Hn5Jq8Zx3Md1Wc4Su7Ti9K"],
"transactionCount": 2,
"totalAmount": 21500,
"currency": "TWD",
"submittedAt": "2026-08-31T01:02:03.000Z",
"executedAt": null,
"failureCode": "BANK_REJECTED",
"failureMessage": "帳號錯誤"
}
}

可能的錯誤:PY001、X024。

DELETE /domain/{domain}/instructions/{instructionId}

  • 只有 pending 的指示可以取消。取消後狀態變成 cancelled,預留會釋放,仍符合撥款條件的交易回到可撥清單。
  • 已經是 cancelled 的指示再取消,會回 200 與目前的內容,可以安心重送。
  • processing、executed、failed 的指示不能取消,回 409 PY012。指示剛好在取消時被應援開始處理,也會回 PY012,請重新查詢指示確認狀態。
  • 取消後,同一個結算區間不能再送新指示,交易要等下一期(見結算區間與執行日)。
  • 取消前同樣會檢查網域設定(PY002、PY011)。不需要 Idempotency-Key。

回應 200,data 是取消後的指示,status 是 cancelled。

可能的錯誤:PY001、PY002、PY011、PY012、X024。

欄位 說明
instructionId 指示編號,pi_ 開頭
status 指示狀態,見下表
settlementWindow 結算區間:start、end、executionDate
executionDate 預定執行日,台北日期 yyyy-MM-dd。不代表當天一定處理完成,請以 status 為準
transactionIds 這張指示包含的交易編號。列表不回這個欄位
transactionCount 交易筆數
totalAmount 這些交易的金額合計,不是實際匯款金額
currency TWD
submittedAt 送出時間
executedAt 撥款成功的時間;還沒成功時是 null
failureCode 失敗原因代碼,見下表;沒有失敗時是 null
failureMessage 失敗說明;銀行拒絕時是銀行回覆的原因
狀態 說明 之後可能變成
pending 已送出,等待執行日處理。可以取消 processing、failed、cancelled
processing 應援已產生銀行匯款檔,等待銀行回覆 executed、failed
executed 撥款成功 不會再變
failed 撥款失敗,預留已釋放 不會再變
cancelled 你取消了這張指示,預留已釋放 不會再變
代碼 發生在 說明
REVALIDATION_FAILED pending 執行日重新檢查時,指示裡的交易已不符合撥款條件(例如已退款)
AMOUNT_BELOW_MINIMUM pending 實際匯款金額(扣除手續費、加計部分退款剩餘金額之後)低於 60 元。送出指示時不會檢查這一項
SFTP_FAILED processing 匯款檔沒有送達銀行
BANK_REJECTED processing 銀行拒絕匯款,原因見 failureMessage

失敗的指示不會自動重送。仍符合撥款條件的交易回到可撥清單後,請在下一期重新送出;銀行拒絕通常跟收款帳戶有關,請先確認撥款帳戶資料。

送出撥款指示一定要帶 Idempotency-Key,沒帶或格式不對會回 400 X034。

  • 格式:1 到 255 個可見 ASCII 字元,不能有空白。
  • 每一張新指示都要用新的 key,例如新產生一組 UUID。key 不會過期,下週沿用同一把 key 再送 ALL,只會拿到上次的結果。
  • 同一把 key、同樣的內容重送,會回第一次保存的結果(原本的 HTTP 狀態碼與當時的指示內容),包括第一次回的業務錯誤(例如 PY003 到 PY008、PY010),不會重複建立指示。重送的回應是當時的快照,指示目前的狀態請用查詢取得。
  • 重送前仍會先做檢查順序的第 1 到 2 步,例如網域在這段時間被暫停,重送會回 PY011。
  • 同一把 key、不同的內容,回 409 PO004。
  • 第一次的請求還在處理中,回 409 PO005,稍後用同一把 key 再送。超過約 5 分鐘還沒有結果,下一次重送會重新處理。
  • 以下情況不會保存結果,可以用同一把 key 重送:429 X030、422 PY013、沒有 errno 的系統錯誤。
  • 逾時或收到 5xx 時,先用查詢指示列表確認這一期有沒有建立指示,再用同一把 key 重送,不要直接換新 key。
  • 因為業務錯誤被拒絕、修正後要重新送出時,請用新的 key。

指示狀態改變時,應援會送出 webhook。接收網址與簽章密鑰由應援在開通時幫你設定;設定完成前,請用查詢單張指示確認狀態。

Webhook 可能重複、延遲,少數情況也可能沒有送達,到達的順序也不一定等於狀態改變的順序。請保留定期查詢指示的對帳機制,不要讓晚到的 processing 覆蓋已經是終態(executed、failed、cancelled)的指示。

事件 什麼時候
payout.instruction.processing 應援產生了銀行匯款檔
payout.instruction.executed 撥款成功
payout.instruction.failed 撥款失敗,原因見 failureCode、failureMessage
payout.instruction.cancelled 指示被取消

送出指示(pending)不會發 webhook,建立結果直接看 API 回應。

POST https://shop.example.com/oen/payout-webhook
Content-Type: application/json
OenPay-Event-Type: payout.instruction.executed
OenPay-Event-Id: evt_4f3a9c1d2e8b7a6f5c4d3e2f
OenPay-Signature: t=1789124412,v1=<HMAC-SHA256 簽章>
{
"id": "evt_4f3a9c1d2e8b7a6f5c4d3e2f",
"type": "payout.instruction.executed",
"api_version": "2026-06-01",
"created": 1789124412,
"data": {
"instructionId": "pi_2sTk9Yx3Qm7bV1nWc4Rz8Lp0FhA",
"domainId": "2aB3cD4eF5gH6iJ7kL8mN9oP0qR",
"domain": "ming",
"status": "executed",
"totalAmount": 4800,
"currency": "TWD",
"executionDate": "2026-09-11",
"executedAt": "2026-09-11T11:00:12.000Z",
"failureCode": null,
"failureMessage": null,
"transactionCount": 2,
"occurredAt": "2026-09-11T11:00:12.000Z"
}
}
欄位 說明
id 事件編號,evt_ 開頭
type 事件名稱,同 OenPay-Event-Type
api_version 事件格式版本
created 事件建立時間(Unix 秒)。重試時不變;驗證簽章請用 header 裡的 t
data.instructionId、data.status 哪一張指示、變成什麼狀態
data.domain、data.domainId 網域名稱與網域編號
data.totalAmount、data.currency、data.executionDate、data.transactionCount 同指示物件
data.executedAt、data.failureCode、data.failureMessage 同指示物件,沒有值時是 null
data.occurredAt 狀態改變的時間

data 只有上面這些欄位,不帶 transactionIds、settlementWindow、submittedAt;需要時請用查詢單張指示。除了 instructionId、domainId、status、transactionCount、occurredAt,其他欄位都可能是 null。

重試時沿用原本的 id、created 與 body,另外加上 OenPay-Retry-Count header;簽章與 t 會重新產生。

同一個狀態改變可能送到不只一次,而且每次的 id 可能不同。請以 data.instructionId 加 data.status 判斷是否處理過:

  • id 相同:同一次投遞的重送。
  • id 不同,但 instructionId 與 status 相同:仍是同一個狀態改變,不要重複入帳。

驗證簽章通過後,先把事件與已處理紀錄可靠地存下來,再回 2xx,耗時的處理放到背景做;存檔失敗就回非 2xx,讓應援重試。

OenPay-Signature 的格式是 t=<Unix 秒>,v1=<hex>,簽章是以簽章密鑰對 `${t}.${原始 body}` 做 HMAC-SHA256。驗證簽章時要用收到的原始 body,並檢查 t 與現在相差不超過 5 分鐘。更換密鑰期間會帶兩個 v1=,任一個相符就通過。

終端機視窗
# 在本機模擬一個帶簽章的通知,測試你的驗簽程式(測試資料,不是實際的通知)
BODY='{"id":"evt_test_0001","type":"payout.instruction.executed","api_version":"2026-06-01","created":1790000000,"data":{"instructionId":"pi_test_0001","domainId":"test_domain_id","domain":"ming","status":"executed","totalAmount":4800,"currency":"TWD","executionDate":"2026-09-11","executedAt":"2026-09-11T11:00:12.000Z","failureCode":null,"failureMessage":null,"transactionCount":2,"occurredAt":"2026-09-11T11:00:12.000Z"}}'
T=$(date +%s)
SIG=$(printf '%s.%s' "$T" "$BODY" | openssl dgst -sha256 -hmac "$OEN_PAYOUT_WEBHOOK_SECRET" | sed 's/^.* //')
curl -X POST "http://localhost:3000/webhooks/oen" \
-H "Content-Type: application/json" \
-H "OenPay-Event-Type: payout.instruction.executed" \
-H "OenPay-Event-Id: evt_test_0001" \
-H "OenPay-Signature: t=$T,v1=$SIG" \
-d "$BODY"
  • 回 2xx、並且完整收到回應才算成功。回應 body 請保持精簡(例如回 204 或很短的 200),超過 2048 bytes 也算失敗。
  • 不會跟隨轉址(3xx 算失敗);連線或回應超過 30 秒沒有動靜也算失敗。
  • 每個事件最多投遞 5 次(第一次加上 4 次重試)。每次失敗後,分別約 5 分鐘、30 分鐘、2 小時、24 小時再試一次,實際時間可能稍晚。
  • 接收網址必須是 https,不能指向內部網路位址。
errno HTTP error 意思 建議處理
PY001 404 instruction_not_found 找不到這張指示,或不是這個網域的指示 確認 instructionId 與網域
PY002 400 mode_not_instruction_required 網域不是指示制撥款 聯絡應援
PY003 409 instruction_already_exists 這個結算區間已經有指示(含已取消、失敗的) 下一期再送
PY004 422 insufficient_net_available 送 ALL 但沒有可撥交易;或有撥款後退款還沒扣回(detail.reason 是 unpaid_adjustments) 沒有可撥交易就等下一期;unpaid_adjustments 請聯絡應援
PY005 404 transaction_not_found lastTransactionId 查不到,或不是這個網域的交易 改用可撥清單裡的 transactionId
PY006 400 transaction_out_of_window lastTransactionId 的交易還在保留期 改用可撥清單裡的 transactionId
PY007 422 cursor_skips_earlier_transactions lastTransactionId 的交易不能撥(已退款、已預留或已撥款),detail 帶 ineligibleId、status 重新查詢可撥交易後,用新的 key 再送
PY008 422 too_many_transactions_in_range 超過 99 筆 改用較早的交易當 lastTransactionId
PY009 400 settlement_window_unavailable 撥款頻率不是每週五 聯絡應援
PY010 409 transaction_not_reservable 送出當下有交易剛被撥款、退款或被其他指示預留,detail.transactionId 是那一筆 重新查詢可撥交易,用新的 key 再送
PY011 403 payout_not_enabled 這個網域的撥款沒有啟用或已被暫停(送出與取消時檢查) 聯絡應援
PY012 409 instruction_not_cancellable 指示不是 pending,不能取消(已經是 cancelled 的會直接回 200) 查詢指示目前的狀態
PY013 422 eligible_set_partial 讀取不完整,無法處理這個 lastTransactionId;detail 帶 readableCount、lastReadableTransactionId、lastReadableSortAt 見讀取不完整時
PO004 409 idempotency_key_reused 同一把 Idempotency-Key 用在不同的請求內容 換一把新的 key
PO005 409 idempotency_key_in_progress 同一把 key 的請求還在處理中 稍後用同一把 key 再送
X022 401 Unauthorized token 無效、過期或權限不足,見驗證 重新取得 token;仍失敗請聯絡應援
X024 404 Not Found 網域不存在或路徑錯誤 確認 {domain} 與路徑
X027 400 JSON_BODY_PARSE_FAILED body 不是合法的 JSON 修正 body
X028 400 PAGINATION_PARSE_FAILED page 參數無法解析 原樣帶回上一頁的 paging.next
X030 429 rate_limit_exceeded 超過頻率限制 見頻率限制
X034 400 Bad Request 缺少或格式不對的 Idempotency-Key、limit 超出範圍,或 page 不屬於這個網域 修正請求內容
(無) 405 method_not_allowed 這支 API 完全不接受的 HTTP method(例如 PUT、PATCH) 確認 method 與路徑
端點 每個網域每小時
查詢可撥交易 120 次
送出撥款指示 30 次
查詢指示列表 300 次
查詢單張指示 300 次
取消指示 30 次
  • 每個端點的額度分開計算。另外,每個來源 IP 每分鐘最多 60 次,這個額度與應援其他合作夥伴 API 共用。
  • 超過時回 429 X030,header 帶 Retry-After(建議等待的秒數)與 X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset(Unix 秒)。等待後仍可能超過,請逐步拉長間隔再試。
  • 正常的回應通常也會帶 X-RateLimit-* header,數字是當下最接近上限的那一項(可能是 IP,也可能是網域)。這些 header 偶爾會沒有,程式請不要依賴它們一定存在。