金流 Webhook 的可靠性設計:為什麼你的訂單會「漏接」付款通知
在串接綠界金流的過程中,最令人焦慮的問題莫過於「消費者明明付了款,後台訂單狀態卻沒更新」。這並非綠界的 Bug,而是 Webhook 通知機制天生就不是百分之百可靠的。理解這個前提,才能設計出真正穩健的收款架構。
首先,讓我們釐清綠界的通知流程。當消費者完成付款後,綠界會以 HTTP POST 的方式將交易結果推送到你在建立訂單時指定的 ReturnURL。你的伺服器必須在收到資料後回應純文字「1|OK」,綠界才會認定通知已成功送達。如果綠界沒有收到正確的回應,它會在 5 到 15 分鐘後重新發送,最多重試四次。換句話說,你一共有五次機會接住這筆通知——但如果五次都失敗,這筆訂單就會「靜悄悄地消失」。
漏接通知最常見的三個原因如下。第一,伺服器在回應前就拋出了例外。許多開發者在 ReturnURL 的處理邏輯中先做完所有業務操作(寫入資料庫、發送通知信、更新庫存),再回應 1|OK。一旦中間任何一步出錯,整個 Request 就逾時或回傳 500,綠界會判定為通知失敗。正確做法是:先驗證 CheckMacValue,確認金額與訂單號無誤後,立即回應 1|OK,再將後續的業務邏輯推入背景佇列非同步執行。
第二,防火牆或 CDN 擋住了綠界的回調請求。綠界的通知來自特定 IP 段,如果你的伺服器使用了 WAF 或 Cloudflare 等服務,突發的多筆 POST 請求可能被判定為攻擊而遭封鎖。建議在防火牆規則中將綠界的 IP 加入白名單,並確保 ReturnURL 使用標準的 443 Port。
第三,缺乏冪等性處理導致重複通知引發錯誤。綠界在重試時會發送完全相同的資料。如果你的程式在第一次收到通知時已經更新了訂單狀態,第二次收到時卻因為「狀態重複更新」而拋出例外,反而會讓綠界以為通知失敗而繼續重試,形成惡性循環。解決方案是在處理通知前先檢查訂單是否已為「已付款」狀態,若是則直接回應 1|OK 而不做任何操作。
除了被動接收通知,我們強烈建議加入「主動對帳」機制作為最後一道防線。利用綠界提供的「查詢訂單 API」,定時(例如每 30 分鐘)掃描所有「待付款」超過一定時間的訂單,主動向綠界查詢實際付款狀態。這樣即使五次 Webhook 通知全部漏接,你的系統仍然能在短時間內自動修復訂單狀態。
最終的架構建議是三道防線並行:ReturnURL 即時接收為主、冪等性確保重試安全、主動輪詢作為兜底。金流系統不怕多做一次確認,怕的是少做一次。