Webhook 還是輪詢?如何可靠地獲取支付結果
獲取支付狀態用 Webhook 還是輪詢:為什麼應該由 Webhook 驅動履約、哪些場景仍然需要查詢,以及如何兜底確保不漏掉任何一筆付款。
得知一筆付款成功有兩種方式。輪詢:你的服務器一遍又一遍地問支付接口「付了嗎?」。Webhook:支付平台在事情發生的那一刻主動告訴你的服務器。對支付狀態來説,Webhook 還是輪詢並不是二選一:由 Webhook 驅動你的業務流程,用單次查詢回答具體問題,再用補拉兜住任何遺漏。
這篇文章説明為什麼只靠輪詢不適合支付場景、哪些地方仍然需要直接查詢,以及如何把 Webhook、查詢和事件接口結合起來,確保永遠不漏掉任何一筆付款。
Webhook 和輪詢對比
| Webhook | 輪詢 | |
|---|---|---|
| 你如何得知 | 平台主動通知你 | 你不停地問 |
| 延遲 | 事件發生後幾秒內 | 最長等於你的輪詢間隔 |
| 成本 | 每個事件一次請求 | 每次檢查一次請求,大多是「沒有新消息」 |
| 調用頻率限制 | 不佔用你的 API 配額 | 每次檢查都計入 |
| 買家關掉頁面後還有效嗎 | 有效 | 只有你的輪詢程序一直運行才有效 |
| 需要公網 HTTPS 地址 | 需要 | 不需要 |
為什麼不只靠輪詢獲取支付狀態?
- 不是慢就是貴。 每 5 秒查一次,每筆未付款訂單每小時就是 720 次調用;每 5 分鐘查一次,買家又要等。
- 會耗光你的調用額度。 讀接口按商戶賬戶限流,所有應用和環境共用;對大量未付款訂單循環輪詢,可能讓你自己的請求也收到
429,見 API 調用頻率限制。 - 會漏掉長尾情況。 買家可能在離開你的頁面很久之後,才完成錢包授權或 3D Secure 驗證;幾分鐘後就放棄的輪詢程序永遠看不到這筆付款。
- 有些事件你根本想不到去輪詢,比如被通道拒絕的退款,或者幾週後才發起的拒付。
為什麼 Webhook 才是正確的默認選擇
在 KukoPay,每一次變化都會記錄為一個事件,比如 payment.succeeded、payment.failed、payment.expired、refund.succeeded、dispute.created 等,並在發生時立即投遞到你的端點:
- 投遞帶有簽名(HMAC-SHA256),驗簽後就可以信任;
- 10 秒內沒有收到 2xx 的投遞會被重試,在約 2 小時 45 分鐘內共嘗試 6 次;
- Webhook 的請求體就是查詢接口返回的同一個對象,一套解析代碼就能同時處理兩者。
驗簽、按事件 id 去重、儘快返回 2xx,然後再履約,做法見 Webhook 重複通知怎麼辦。
哪些地方仍然需要查詢
Webhook 驅動業務流程;單次查詢用來在某個特定時刻回答某個具體問題:
- 買家的回跳頁面。 買家到達你的
return_url時,由你的後端查詢一次訂單(GET /v1/orders/{trade_no}),以顯示正確的提示。如果還是pending,就顯示「正在確認你的付款」,讓 Webhook 完成剩下的事,見 return_url 和 notify_url 的區別。 - 客服問題。 「我付了款,但訂單顯示未付款」,查一次就能知道真相。
- 處理中的退款,如果你需要比 Webhook 更早知道結果:每 10 秒查一次、最多持續 5 分鐘,之後改為低頻查詢。
- 你自己的請求超時之後,確認訂單是否已經創建。
這些都是少量有針對性的調用,而不是對每一筆未付款訂單的循環查詢。
兜底:補回 Webhook 漏掉的事件
Webhook 是「至少投遞一次」,而不是保證一定送達;你的端點宕機的時間,可能比重試持續的時間還長。在 KukoPay,事件先記錄、後投遞,所以什麼都不會丟:
- 從事件接口補拉。 按事件類型和時間範圍拉取事件(
GET /v1/events),交給同一套處理代碼;因為有去重,重放也不會有任何影響,見 收不到支付 Webhook 回調怎麼辦。 - 每天對賬。 每天把你已履約的訂單和已付款訂單、資金流水比對一次,見 支付對賬怎麼做。
平台自己也有兜底:對賬任務會持續向通道重新讀取未決的付款,所以即使買家關掉了頁面、通道自己的通知也丟了,這筆付款仍然會入賬。
推薦的組合方式
- Webhook:訂閲成功、失敗、過期、退款和拒付事件,收到
payment.succeeded時履約。 - 有針對性的查詢:用在回跳頁面、客服和超時之後。
- 事件補拉:在接收端出現故障之後,以及作為定時補漏。
- 每日對賬:最後一道檢查,確認每一筆已付款訂單都已履約。
只能輪詢時怎麼辦
如果你的系統完全無法提供公網 HTTPS 地址,比如防火牆後面的內部工具,那就輪詢事件接口,而不是逐筆查詢訂單:每分鐘調用一次,拉取上次檢查之後的事件,一次請求就覆蓋了所有訂單,遠低於頻率限制。
總結
- Webhook 在付款狀態變化的那一刻通知你;輪詢不停地問,大多聽到的是「沒有新消息」;
- 只靠輪詢不是慢就是貴,會耗光調用額度,還會漏掉遲到的授權;
- 讓 Webhook 驅動履約,在回跳頁面、客服、超時和處理中的退款這些場景使用單次查詢;
- 用事件接口和每日對賬為兩者兜底;
- 如果無法接收 Webhook,就輪詢事件列表,而不是逐筆查詢訂單。
在沙箱裏把它跑通
註冊商戶後即可申請測試密鑰,不需要等待資質審核。