付款通知內容
付款通知的處理方式、重送規則與回查做法,請先看付款通知(webhook)。這一頁列出每一種通知的欄位。
HTTP 格式
Section titled “HTTP 格式”POST到你在 CRM 設定的「交易資料回傳網址位置」。- Header 有
Content-Type: application/json、OenPay-Event-Id、OenPay-Delivery-Attempt;在 CRM 產生簽章密鑰後另外帶OenPay-Signature,驗證方式見確認通知的真假。charge、token、schedule_subscription的 body 沒有事件編號,請依OenPay-Event-Id的算法由 body 重算;需要開啟的五種通知與subscription_card_changed,body 的id本身就是事件編號。 - 用 body 的
purpose分辨是哪一種通知。
| purpose | 什麼時候送 | 預設會送嗎 |
|---|---|---|
charge |
單次付款與定期定額每一期的結果;超商代碼、ATM 取號;LINE Pay 等待確認 | 會 |
token |
綁卡頁完成或失敗 | 會 |
schedule_subscription |
預約定期定額在結帳頁完成或失敗 | 會 |
refund |
退款建立、完成或取消 | 要請應援開啟 |
subscription_cancelled |
定期定額被取消(API 或 CRM) | 要請應援開啟 |
subscription_retry |
定期定額扣款失敗後,已排定重扣或重扣次數用完 | 要請應援開啟 |
invoice_issued |
API 交易的電子發票開立成功 | 要請應援開啟 |
invoice_voided |
API 交易的電子發票作廢成功 | 要請應援開啟 |
subscription_card_changed |
消費者在換卡頁換卡成功 | 會 |
refund、subscription_cancelled、subscription_retry、invoice_issued、invoice_voided 五種共用同一個開關,要請應援在後台開啟「Webhook 新版事件」才會送出。開啟後五種都會收到,用不到的請依 purpose 略過;不認得的 purpose 也請一律略過,不要回錯誤。沒有開啟新版事件也可能收到新的 purpose(例如 subscription_card_changed)。
charge
Section titled “charge”單次付款、定期定額每一期的結果。同一筆交易可能收到多則,例如超商代碼先送取號(charging),繳費後再送 charged。
| 欄位 | 型別 | 出現 | 說明 |
|---|---|---|---|
purpose | string | 一定有 | charge |
id | string | 一定有 | 交易的內部 id。用它呼叫 GET /transactions/{id} 回查 |
transactionId | string | 一定有 | 同 id |
transactionHid | string | 一定有 | 交易編號(P 開頭) |
merchantId | string | 一定有 | 你的網域名稱 |
orderId | string | 可能沒有 | 你的訂單編號 |
action | string | 可能沒有 | onetime 或 subscription |
status | string | 一定有 | 交易狀態:charging、charged、claimed、authorized、failed 等 |
success | boolean | 可能沒有 | 只在最終結果才有:status 不是 failed 時為 true。取號、等待確認(charging)時沒有這個欄位 |
paymentMethod | string | 可能沒有 | card、applePay、linePay、cvs、atm |
amount | number | 可能沒有 | 金額 |
currency | string | 可能沒有 | 幣別,小寫,例如 twd |
paymentInfo | string | object | 可能沒有 | 信用卡:卡號末四碼字串(Apple Pay 的付款通知可能不帶 paymentInfo);超商:{ cvsName, code, expiredAt };ATM:{ bankName, bankCode, account, expiredAt };LINE Pay:LINE Pay 交易編號 |
authCode | string | 可能沒有 | 授權碼 |
customId | string | 可能沒有 | 你帶入的自訂資料 |
productDetails | array | 可能沒有 | 建立交易時的商品明細 |
userPhone | string | 可能沒有 | 消費者在結帳頁填的手機 |
createdAt | string | 可能沒有 | 交易建立時間,不是通知送出的時間 |
paidAt | string | 可能沒有 | 付款完成時間 |
message | string | 可能沒有 | 失敗原因。超商代碼、ATM、LINE Pay 逾期時是 PAYMENT_EXPIRED;3D 驗證開始後 10 分鐘沒完成是 3DS_ABANDONED |
subscriptionId | string | 可能沒有 | 定期定額編號(S 開頭),定期定額才有 |
period | integer | 可能沒有 | 定期定額的第幾期 |
numberOfPeriods | integer | 可能沒有 | 定期定額總期數 |
isRetry | boolean | 可能沒有 | 定期定額:這次是否為失敗後的重新扣款 |
failureCode | string | 可能沒有 | 定期定額扣款失敗的原因:invalid_card_number、invalid_cvv、expired_card、exceeds_credit_limit、payment_refused、duplicate_payment、charge_failed |
scheduleStatus | string | 可能沒有 | 定期定額狀態:pending、trialing、active、retrying、error、cancelled、completed |
nextChargeAt | string | 可能沒有 | 定期定額下次扣款時間。請以查詢定期定額明細為準 |
firstPeriodDiscount | object | 可能沒有 | 首期折扣 { method, value, label, discountAmount },使用首期折扣的第一期才有 |
originalAmount | number | 可能沒有 | 折扣前的每期金額,使用首期折扣的第一期才有 |
範例
{ "purpose": "charge", "action": "onetime", "merchantId": "ming", "orderId": "A20260928001", "id": "2HhndgEquCbDzC5OyVxWSGZmd2l", "transactionId": "2HhndgEquCbDzC5OyVxWSGZmd2l", "transactionHid": "P20260928AB12CD34", "status": "charged", "success": true, "paymentMethod": "card", "amount": 1200, "currency": "twd", "paymentInfo": "4242", "authCode": "831000", "customId": "cart-8812", "createdAt": "2026-09-28T02:40:25.502Z", "paidAt": "2026-09-28T02:41:03.118Z", "productDetails": [ { "productionCode": "SKU-001", "description": "手沖咖啡豆 200g", "quantity": 2, "unit": "包", "unitPrice": 600 } ], "message": ""}超商代碼取號時(還沒繳費,沒有 success 欄位):
{ "purpose": "charge", "action": "onetime", "merchantId": "ming", "orderId": "A20260928002", "id": "2HhnkQ3vXy8LpA1cB0dE9fG2hIj", "transactionId": "2HhnkQ3vXy8LpA1cB0dE9fG2hIj", "transactionHid": "P20260928UV12WX34", "status": "charging", "paymentMethod": "cvs", "amount": 500, "currency": "twd", "paymentInfo": { "cvsName": "超商代碼繳費", "code": "XXXXXXXXXXXX", "expiredAt": "2026-09-30T02:00:00.000Z" }, "message": ""}消費者繳費後,同一個 id 會再收到一則 status: charged、success: true 的通知。逾期未繳則是 status: failed、message: PAYMENT_EXPIRED。
建立綁卡頁後,消費者完成或放棄綁卡時送出。這是拿到 token 的唯一管道。
| 欄位 | 型別 | 出現 | 說明 |
|---|---|---|---|
purpose | string | 一定有 | token |
id | string | 一定有 | 建立綁卡頁時回傳的 id |
transactionId | string | 一定有 | 同 id |
merchantId | string | 一定有 | 你的網域名稱 |
success | boolean | 一定有 | 是否綁卡成功 |
token | string | 可能沒有 | 成功時才有。用來呼叫用 token 扣款,請當成密碼一樣保存 |
paymentInfo | string | 可能沒有 | 卡號末四碼 |
customId | string | 可能沒有 | 建立綁卡頁時帶的自訂資料 |
message | string | 可能沒有 | 失敗原因。3D 驗證開始後 10 分鐘沒完成是 3DS_ABANDONED |
範例
{ "purpose": "token", "merchantId": "ming", "id": "2HhngP9sVb3mK1xYdQe7Wc0RtUi", "transactionId": "2HhngP9sVb3mK1xYdQe7Wc0RtUi", "success": true, "token": "2HhnhWm8Qe0sPz4LbXv9KdYt1Ra", "paymentInfo": "4242", "customId": "M001", "message": ""}schedule_subscription
Section titled “schedule_subscription”建立預約定期定額後,消費者在結帳頁完成或失敗時送出。之後每一期的扣款結果以 charge 通知送出。
| 欄位 | 型別 | 出現 | 說明 |
|---|---|---|---|
purpose | string | 一定有 | schedule_subscription |
id | string | 一定有 | 建立時回傳的 id |
subscriptionId | string | 一定有 | 定期定額編號(S 開頭) |
merchantId | string | 一定有 | 你的網域名稱 |
success | boolean | 一定有 | 是否成功 |
amount | number | 可能沒有 | 每期金額 |
currency | string | 可能沒有 | 幣別(小寫) |
period | integer | 可能沒有 | 已扣期數 |
numberOfPeriods | integer | 可能沒有 | 總期數 |
interval | integer | 可能沒有 | 每幾個月扣一次 |
startedAt | string | 可能沒有 | 開始時間 |
nextChargeAt | string | 可能沒有 | 下次扣款時間 |
paymentInfo | string | 可能沒有 | 成功時為卡號末四碼 |
customId | string | 可能沒有 | 你帶入的自訂資料 |
productDetails | array | 可能沒有 | 商品明細 |
message | string | 可能沒有 | 失敗原因 |
範例
{ "purpose": "schedule_subscription", "merchantId": "ming", "id": "2HhnfZ1kqRmA7cX0TQwq8vBn3Ls", "subscriptionId": "S20260928EF56GH78", "success": true, "amount": 1500, "currency": "twd", "period": 0, "numberOfPeriods": 4, "interval": 3, "startedAt": "2026-10-15T00:00:00.000Z", "nextChargeAt": "2026-10-15T01:00:00.000Z", "paymentInfo": "4242", "message": ""}subscription_card_changed
Section titled “subscription_card_changed”消費者在換卡頁換卡成功時送出。不需要開啟「Webhook 新版事件」,有設定通知網址就會收到。
| 欄位 | 型別 | 出現 | 說明 |
|---|---|---|---|
purpose | string | 一定有 | subscription_card_changed |
id | string | 一定有 | 換卡請求的 id。同一次換卡的 id 固定,可以用來判斷重複 |
transactionId | string | 一定有 | 同 id。不是交易編號 |
merchantId | string | 一定有 | 你的網域名稱 |
success | boolean | 一定有 | 固定是 true |
status | string | 一定有 | 固定是 succeeded |
subscriptionId | string | 一定有 | 定期定額編號(S 開頭) |
period | integer | 可能沒有 | 已扣期數 |
nextChargeAt | string | 可能沒有 | 下次扣款時間。請以查詢定期定額明細為準 |
paymentInfo | string | 可能沒有 | 新卡末四碼 |
cardBrand | string | 可能沒有 | 新卡卡別 |
orderId | string | 可能沒有 | 你的訂單編號 |
userId | string | 可能沒有 | 你帶入的會員編號 |
customId | string | 可能沒有 | 你帶入的自訂資料 |
refund(需開啟)
Section titled “refund(需開啟)”| 欄位 | 說明 |
|---|---|
purpose |
refund |
id |
這則退款事件的 id,每則都不同 |
refundId |
退款單 id |
chargeId、chargeHumanId |
原交易的內部 id 與交易編號(P 開頭) |
amount、origAmount |
退款金額、原交易金額 |
currency |
幣別(小寫) |
refundStatus |
refunding(處理中)、refunded(完成)、cancelled(取消) |
reason |
退款原因 |
paymentMethod |
原交易的付款方式 |
requestedAt、resolvedAt |
申請時間、完成時間 |
customId |
原交易的自訂資料 |
subscriptionId、period |
定期定額交易才有 |
subscription_cancelled(需開啟)
Section titled “subscription_cancelled(需開啟)”| 欄位 | 說明 |
|---|---|
purpose |
subscription_cancelled |
subscriptionId |
定期定額編號 |
source |
誰取消的:merchant_api(API)或 crm(後台) |
reason |
取消原因 |
cancelledAt |
取消時間 |
cancelledFromStatus |
取消前的狀態 |
period、numberOfPeriods |
已扣期數、總期數 |
customId |
自訂資料 |
subscription_retry(需開啟)
Section titled “subscription_retry(需開啟)”| 欄位 | 說明 |
|---|---|
purpose |
subscription_retry |
outcome |
scheduled:已排定重新扣款;exhausted:重扣次數用完,定期定額停止 |
retryAttemptNumber |
第幾次重扣 |
nextRetryAt |
下次重扣時間(scheduled 才有) |
failureCode |
扣款失敗的原因 |
chargeId、chargeHumanId |
失敗那一期的交易 |
subscriptionId、period |
定期定額編號與期數 |
invoice_issued、invoice_voided(需開啟)
Section titled “invoice_issued、invoice_voided(需開啟)”API 交易的電子發票開立成功(invoice_issued)或作廢成功(invoice_voided)時送出。要請應援開啟才會送,見電子發票號碼與狀態。
| 欄位 | 型別 | 出現 | 說明 |
|---|---|---|---|
purpose | string | 一定有 | invoice_issued 或 invoice_voided |
id | string | 一定有 | 這則通知的事件編號,格式是 invoice#<發票 id>#issued 或 invoice#<發票 id>#voided。同一張發票的同一種通知 id 固定,可以用來判斷重複 |
transactionId | string | 一定有 | 同 id。不是交易編號,交易請看 chargeId |
merchantId | string | 一定有 | 你的網域名稱 |
chargeId | string | 一定有 | 發票所屬交易的內部 id(27 字元),和 charge 通知的 id 相同。用它呼叫 GET /transactions/{id} 回查 |
orderId | string | 可能沒有 | 你的訂單編號 |
invoiceNumber | string | 一定有 | 發票號碼。invoice_voided 時是被作廢的那張 |
invoiceStatus | string | 一定有 | invoice_issued 固定是 issued,invoice_voided 固定是 voided。值和查詢 API 的 invoice.invoiceStatus 相同 |
invoiceDate | string | 一定有 | 發票開立時間(UTC,ISO 8601)。換算成台北時間就是發票日期 |
randomNumber | string | 一定有 | 4 碼隨機碼 |
invoiceAmount | number | null | 一定有 | 發票金額(含稅),是發票品項的加總。品項資料不完整時是 null |
createdAt | string | 一定有 | 這則通知建立的時間(和 charge 通知不同,不是交易建立時間) |
message | string | 可能沒有 | 固定是空字串 |
範例
{ "purpose": "invoice_issued", "id": "invoice#2HhnqT4cWz0mR8bLxN3vYs6KdPa#issued", "transactionId": "invoice#2HhnqT4cWz0mR8bLxN3vYs6KdPa#issued", "merchantId": "ming", "chargeId": "2HhndgEquCbDzC5OyVxWSGZmd2l", "orderId": "A20260928001", "invoiceNumber": "ZZ00001234", "invoiceStatus": "issued", "invoiceDate": "2026-09-28T02:41:30.000Z", "randomNumber": "0000", "invoiceAmount": 1200, "createdAt": "2026-09-28T02:41:31.204Z", "message": ""}invoice_voided 的欄位相同,purpose 是 invoice_voided、invoiceStatus 是 voided,id 結尾是 #voided;invoiceNumber、invoiceDate、randomNumber 是被作廢的那張發票。什麼時候會送、什麼時候不會送,見電子發票號碼與狀態。
導覽助手暫停服務中。請使用右上角的搜尋,或聯絡客服。
我可以幫你選擇收款方式、回答 API 串接與 CRM 操作問題,並附上文件出處。
