接收 Tokenz 事件到您的 Webhook 端點
在您的 Webhook (網路鉤子) 端點上監聽您 Tokenz 帳戶中的事件,以便您的系統整合能夠自動觸發反應。
金額格式: Webhook 酬載中的所有貨幣值(如 amount 欄位)均以各貨幣的最小單位表示。請參閱支援的貨幣以了解每種貨幣的確切編碼。
為何使用 Webhook
在構建 Tokenz Checkout (結帳) 整合時,您可能希望您的應用程序能夠在帳戶中發生事件時即時接收這些事件,以便您的後端系統能夠相應地執行操作。
要啟用 Webhook 事件,您需要註冊 Webhook 端點。註冊後,當您的 Tokenz 帳戶中發生事件時,Tokenz 可以將即時事件資料推送到您應用程序的 Webhook 端點。Tokenz 使用 HTTPS 將資料以 JSON 格式發送到您的應用程序。
我們強烈建議在處理從我們的結帳頁面重定向的基礎上整合 Webhook,以便能確保接收到結帳結果的通知。
事件概述
Tokenz 生成的事件資料可以用於通知您帳戶中的活動。
當事件發生時,Tokenz 會生成一個新的事件物件。單個 API 請求可能會導致創建多個事件。
藉由在您的 Tokenz 帳戶中註冊 webhook 端點,您可以啟用 Tokenz 自動將事件物件作為 POST 請求的一部分發送到您應用程序託管的註冊 webhook 端點。在您的 webhook 端點接收到事件後,您的應用程序可以執行後端操作(例如,在您收到 order.succeeded 事件後呼叫您的物流供應商的 API 來安排運輸)。
事件物件
我們發送到您的 webhook 端點的事件物件提供了發生變化的物件快照。webhook 總是包含事件發生所在的完整對象,連同事件的元數據。
查看我們發送到您 webhook 的事件類型完整列表。
事件酬載(payload)範例
以下事件顯示了一個訂單成功完成支付的事件。
{
"id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
"object": "order.succeeded",
"createdAt": "2025-09-24T03:22:20.297Z",
"test": true,
"eventData": {
"type": "order",
"version": "v2",
"data": {
"order": {
"id": "order_1D5xA9BnKfv_t",
"object": "order",
"status": "succeeded",
"amount": {
"amount": 3700,
"currency": "JPY"
},
"items": [
{
"id": "item_1D6F8mR5TnK_t",
"detail": {
"product": {
"price": {
"amount": 1200,
"currency": "JPY"
},
"quantity": 3,
"label": "ひとにぎりのエメラルド",
"description": "80+8",
"images": [
"https://images.ctfassets.net/z82qbo7cv7ia/1dWPbk5Qx2M1Qikj6Knyuc/e37b2c26829c0d30793a348ae3adb3b0/fake-pass.webp"
]
}
}
},
{
"id": "item_1xejV7puGeK_t",
"detail": {
"product": {
"price": {
"amount": 100,
"currency": "JPY"
},
"quantity": 1,
"label": "Diamond",
"description": "",
"images": [],
"sku": "sku_103843dfjhdfgiu",
"taxCategory": "VIRTUAL_CURRENCY"
}
}
}
],
"description": "Game items purchase",
"reference": "ORDER_2024_001",
"test": true,
"expiresAt": "2024-12-31T23:59:59Z",
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-01-15T10:05:30Z"
}
}
}
}
正式模式和測試模式
您可能會接收到來自正式模式和測試模式的事件傳送請求,這取決於您是否使用單個端點來處理這兩種模式。使用測試標誌來檢查對象是存在於正式還是測試模式,並確定事件的正確處理方式。
版本
version 表示事件的 API 版本並決定包含的 data.object 的結構。
事件的種類
| 種類 | 說明 |
|---|---|
order.created | 當有一個新的 order 物件透過 Create a Checkout Session API 建立時。 |
order.succeeded | 當有消費者成功的支付一筆 order 的款項時,這時您就可以提供產品給客戶。 |
order.expired | 當訂單已過期時。 |
order.canceled | 當訂單已被取消時。 |
order.failed | 當訂單付款失敗時。 |
refund.created | 當退款已建立時。 |
refund.failed | 當退款失敗時。 |
dispute.created | 當爭議已建立時。 |
dispute.closed | 當爭議已結案時。 |
redemption.completed | 禮品碼兌換或免費道具領取完成。使用 kind 區分流程(source 已棄用);免費道具領取不包含 code。 |
重試與冪等性
Tokenz 期望您的端點以 2xx 回應確認收到 Webhook。如果您的端點回傳其他狀態碼、逾時或無法連線,Tokenz 會在最多三天內自動重試投遞。首次重試大約會在投遞失敗後的 5 秒、15 秒和 30 秒進行。之後重試間隔會逐漸增加,頻率也會降低。重試時間可能略有變化;請勿依賴後續重試的精確時間表。測試模式的 Webhook 投遞可能採用不同的重試政策,因此請勿用它來衡量或驗證正式模式的重試時間。一旦您的端點回傳 2xx,Tokenz 將停止重試該事件。您的端點可能會多次收到同一事件,且事件到達順序不受保證。
請以冪等方式處理投遞:
- 在安全接收事件後盡快回傳 2xx,將耗時的處理改為非同步執行。
- 使用事件頂層的
id作為冪等鍵: 記錄已處理的事件 ID 並跳過已處理過的事件,避免重試導致訂單被重複履行。
疑難排解:我的端點沒有收到事件
絕大多數情況下,「Webhook 從未送達」其實意味著 Tokenz 確實發送了它,而你的端點拒絕了它。Tokenz 會將任何非 2xx 的回應(或逾時、無法連線的端點)視為投遞失敗,並在最多三天內自動重試——因此在你這一側看起來像是什麼都沒收到,而 Tokenz 卻一直看到同一次投遞不斷失敗(例如連續出現一串 HTTP 400)。
由於 Tokenz 不提供按端點劃分的投遞紀錄,請從你自己的端點進行診斷:
1. 檢查你的端點回傳的 HTTP 狀態碼。 這正是 Tokenz 所看到的——請在伺服器的存取紀錄/錯誤紀錄中查找收到的 POST 請求。
2xx— 事件已投遞並被確認。如果你的系統仍然沒有據此執行操作,那麼問題出在回應之後的處理器中,而不是投遞環節。400、401、403— 你的端點收到了事件但拒絕了它(見下文)。5xx或逾時 — 你的處理器發生錯誤,或回應太慢。
2. 如果你回傳的是 400,請先檢查簽名驗證——這是最常見的原因:
- 對原始請求本文進行驗證。 大多數框架會解析並重新序列化 JSON,這會改變位元組內容並破壞 HMAC。請讀取確切的原始位元組(例如使用
express.raw()),先驗證,然後再解析。參見保護你的 webhook 端點。 - 使用正確的簽名金鑰。 金鑰只在你註冊端點時顯示一次,並且是該端點專用的;被輪換或輸入錯誤的金鑰會導致每個事件都驗證失敗。
- 讓測試模式與正式模式相符。 用正式模式的簽名金鑰去驗證測試模式的事件(或反過來)永遠不會相符。如果一個端點同時處理兩種模式,請根據事件的
test旗標來選擇金鑰。 - 注意時鐘偏差。 如果你依 5 分鐘的時間戳容許誤差進行拒絕,伺服器時鐘嚴重偏差可能會導致原本有效的事件被拒絕。
3. 導致非 2xx 回應的其他原因:
- 端點前面的防火牆、WAF 或 IP 允許清單攔截了 Tokenz 的請求。
- 端點無法透過 HTTPS 公開存取,或在後台中註冊的 URL 有誤或指向了錯誤的環境。
- 在請求處理路徑中執行了繁重的工作導致逾時——請先用
2xx確認收到,然後再非同步處理。
4. 獨立確認投遞。 將你的端點(或其副本)指向 Webhook.site,以確認 Tokenz 正在投遞,並檢查確切的有效酬載和 header,然後用測試模式付款觸發一個事件。
一旦你的端點回傳 2xx,重試就會停止。由於重試可能會重新發送你已經處理過的事件,請保持你的處理器冪等(見上文)。