跳轉到主要內容

Webhook 端點怎麼配置?多個接收地址、事件訂閲與簽名密鑰輪換

如何為支付配置 Webhook 端點:設置多個接收地址、選擇訂閲的事件、保存和輪換簽名密鑰,以及如何安全地暫停端點。

發佈於 約 4 分鐘閲讀

手繪插畫:一個事件源分發到三個帶事件清單的端點方框,旁邊是一把標着 24h 雙簽名的鑰匙,還有一個朝它們走來的人
本文目錄
  1. 為什麼要用多個 Webhook 端點?
  2. 如何創建 Webhook 端點
  3. 端點應該訂閲哪些事件?
  4. 立即保存簽名密鑰
  5. 如何輪換 Webhook 簽名密鑰而不丟失事件
  6. 暫停端點,而不是刪除
  7. 端點和訂單的 notify_url
  8. 測試新端點
  9. 總結

Webhook 端點是你服務器上用來接收支付事件的地址,比如付款成功、退款確認、拒付開案。大多數接入都從一個端點開始,但隨着業務增長,配置多個 Webhook 端點會更好:每個端點只接收自己需要的事件、各自有獨立的簽名密鑰,這樣履約、財務和告警就不會依賴同一個脆弱的地址。

這篇文章説明如何在 KukoPay 上配置 Webhook 端點:創建多個端點、選擇事件訂閲、保存和輪換簽名密鑰、暫停端點,以及端點和訂單 notify_url 的關係。

為什麼要用多個 Webhook 端點?

  • 職責分開。 發貨服務需要 payment.succeeded;財務需要退款和拒付事件;告警工具需要失敗事件。
  • 故障隔離。 每個端點各自重試,一個宕機的財務服務不會拖慢發貨。
  • 密鑰隔離。 每個端點有自己的簽名密鑰,一個系統泄露的密鑰,不能被用來向另一個系統偽造事件。
  • 平滑遷移。 新的接收服務可以和舊的並行運行,確認無誤後再停用舊的。

每個應用在每個環境下最多可以配置 5 個端點。沙箱和正式環境的端點相互獨立:沙箱端點永遠收不到正式事件。

如何創建 Webhook 端點

在控制台 開發者 → Webhook 中創建,或者通過 API:

curl -X POST "https://api.kukopay.com/v1/webhook_endpoints" \
  -H "X-Api-Key: $KUKOPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://api.yourshop.com/hooks/kukopay",
    "description": "訂單履約服務",
    "enabled_events": ["payment.succeeded", "refund.succeeded"]
  }'
字段作用
url事件發往的地址。正式環境必須是公網 HTTPS 地址
description備註,便於區分多個端點
enabled_events要接收的事件類型,省略則為全部

用 API 密鑰創建的端點屬於這把密鑰所在的應用,只接收該應用的事件,見 多個網站如何用一個商戶賬戶收款。接收所有應用事件的賬戶級端點,只能在控制台中創建和管理。

端點應該訂閲哪些事件?

端點的職責訂閲
履約發貨payment.succeeded
庫存與訂單清理payment.failed、payment.expired
財務與退款refund.succeeded、refund.failed、payment.duplicate_refunded
拒付處理dispute.created、dispute.updated、dispute.won、dispute.lost、dispute.closed

兩條原則:

  • 不要所有端點都只訂閲成功事件:沒有失敗和過期事件,那些永遠不會付款的訂單就會一直處於未結束狀態。每個事件對應哪種狀態變化,見 支付狀態詳解。
  • ["*"] 表示訂閲全部,並且包含之後新增的事件類型。 用它做兜底的日誌端點;有具體職責的端點請明確列出事件,這樣新增的事件類型不會讓它措手不及。

立即保存簽名密鑰

創建響應中包含端點的簽名密鑰:

{
  "object": "webhook_endpoint",
  "endpoint_id": "whe_8c2f41ab9d0e7635",
  "url": "https://api.yourshop.com/hooks/kukopay",
  "enabled_events": ["payment.succeeded", "refund.succeeded"],
  "status": "enabled",
  "secret": "whsec_4f81a2c9..."
}

secret 只在創建和輪換時返回。它加密存儲,之後永遠無法讀回,所以即使有人看到了你的控制台,也拿不到它。請立即保存到你的密鑰管理工具中;如果丟失了,只能輪換一把新的。

如何輪換 Webhook 簽名密鑰而不丟失事件

curl -X POST "https://api.kukopay.com/v1/webhook_endpoints/whe_8c2f41ab9d0e7635/rotate_secret" \
  -H "X-Api-Key: $KUKOPAY_API_KEY"

輪換會簽發一把新密鑰,並讓舊密鑰在 24 小時內繼續一起簽名。這段時間內的每一次投遞,都會在同一個請求頭裏帶上兩個簽名:

X-KukoPay-Signature: t=1762300800,v1=9c1f...,v1=3ea7...
                                  新密鑰      舊密鑰

所以你可以在這段時間內的任意時刻部署新密鑰,不需要和平台同一秒切換。唯一的要求是:只要任意一個 v1= 匹配,你的驗簽代碼就應該接受這次投遞。只保留第一個或最後一個簽名的代碼,會在輪換期間讓每一次投遞都失敗,這個坑見 收不到支付 Webhook 回調怎麼辦。

暫停端點,而不是刪除

curl -X POST "https://api.kukopay.com/v1/webhook_endpoints/whe_8c2f41ab9d0e7635" \
  -H "X-Api-Key: $KUKOPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "disabled" }'

停用會保留端點的投遞記錄,你仍然可以查看它漏掉了什麼。刪除的端點會丟失這些記錄,發往它的投遞也會停止。無論哪種方式,事件本身都不會丟失,都可以從事件接口讀回。

端點和訂單的 notify_url

訂單創建時…它的事件發往
傳了 notify_url只發往這個地址,用應用的回調簽名密鑰簽名
沒有傳 notify_url訂單所屬應用的、以及賬戶級的、訂閲了該事件類型的所有已啓用端點

當一筆訂單的事件只屬於某一個特定系統時,使用 notify_url;其他情況都用端點。沒有 notify_url 的正式訂單,需要至少一個訂閲了 payment.succeeded 的正式環境端點。

測試新端點

開發者 → 沙箱聯調 中的 發送測試回調,會向一個端點發送正確簽名的測試事件,並顯示你的服務器返回了什麼。它的 id 以 evt_test_ 開頭,帶有 "test": true,請確保你的處理代碼不會因為它而發貨。其他沙箱工具見 支付測試卡號大全。

總結

  • 用多個 Webhook 端點隔離職責、故障和密鑰,每個應用每個環境最多 5 個;
  • 讓每個端點只訂閲它的職責需要的事件,並確保失敗和過期事件有端點在接收;
  • 立即保存簽名密鑰,它只在創建和輪換時顯示;
  • 輪換期間新舊密鑰會一起簽名 24 小時,接受任意一個匹配的 v1=;
  • 停用而不是刪除,以保留投遞記錄;
  • 訂單的 notify_url 會覆蓋該訂單的端點投遞。

在沙箱裏把它跑通

註冊商戶後即可申請測試密鑰,不需要等待資質審核。