ECPay(綠界科技)是台灣中小型電商最常用的金流服務之一,文件看起來詳盡, 但實際串接時常常卡在簽章驗證和 Callback 處理這兩個地方。 這篇記錄從申請商店到正式上線的完整流程,以及踩過的坑。
申請流程與環境準備
開始寫程式之前,有兩件事要先確認:
- 先申請測試環境帳號: ECPay 提供測試環境(Stage)與正式環境(Production)兩組不同的 MerchantID、HashKey、HashIV,開發階段全部使用測試環境的參數, 千萬別搞混,這是最常見的低級錯誤來源。
- 確認你的網站有對外可存取的網址: Callback 通知需要 ECPay 主動打你的伺服器,本機開發環境(localhost) 收不到通知,開發階段建議用 ngrok 之類的工具把本機服務暴露到公網測試。
核心流程:三個關鍵步驟
ECPay 信用卡付款的標準流程可以拆成三個階段:
- 建立訂單並產生付款表單: 後端組出訂單參數(金額、商品名稱、Callback 網址等), 計算 CheckMacValue 簽章,前端用這些參數自動送出一個表單到 ECPay 的付款頁。
- 使用者在 ECPay 頁面完成付款: 這段完全在 ECPay 的網域內完成,你的系統不會接觸到任何卡號資訊, 這也是為什麼多數中小型電商選擇第三方金流而非自行處理信用卡的原因——PCI DSS 合規成本太高。
- 接收 Server 端 Callback 通知(ReturnURL): 付款結果由 ECPay 主動用 POST 打到你設定的 ReturnURL, 這裡才是真正確認交易成功、更新訂單狀態的地方——不是使用者瀏覽器導回的那個頁面。
最容易搞錯的地方:CheckMacValue 簽章
CheckMacValue 是 ECPay 用來驗證請求真偽的簽章機制,計算方式是把所有參數 依照參數名稱英文字母排序後串接,加上 HashKey 與 HashIV,做 URL Encode 後再 MD5(或 SHA256)雜湊。實務上最常見的錯誤:
-
URL Encode 的規則不一致:
ECPay 要求的編碼方式和一般語言內建的 URL Encode 函式在某些符號上行為不同
(例如空白要編碼成
+而不是%20), 需要照文件規則手動調整,不能直接呼叫語言內建函式。 - 參數排序沒有排對: 必須是「參數名稱」的字母順序,不是加入的順序,這個很容易在動態組參數時漏掉。
- 簽章大小寫: 官方文件要求最終結果轉為小寫,這個步驟經常被忽略導致驗證一直失敗。
建議做法:先寫一個獨立的簽章計算函式並搭配官方提供的範例參數做單元測試, 確認簽章結果與範例文件一致後,再串進實際的訂單流程,這樣除錯效率會高很多。
Callback 處理:記得回傳「1|OK」
ReturnURL 收到 ECPay 的付款結果通知後,處理完自己的訂單邏輯(更新訂單狀態、
扣庫存等)之後,必須回傳純文字 1|OK 給 ECPay,
否則 ECPay 會認定通知失敗,並持續重試發送通知(最多重試數次),
可能導致同一筆訂單的邏輯被重複執行多次。
// 處理完訂單邏輯後
echo "1|OK";
exit;
也因為重試機制的存在,訂單狀態更新的邏輯務必設計成「冪等」(Idempotent)—— 同一筆通知就算收到兩次,也不該讓訂單被重複扣款或重複出貨。 實務作法是先檢查訂單目前狀態,已經是「已付款」就直接回傳成功、不再重複處理。
結語
ECPay 串接本身邏輯不複雜,多數問題都出在簽章計算的細節和 Callback 的可靠性設計上。 建議開發時先把測試環境的完整流程走過一輪(包含模擬付款失敗的情境), 確認 Callback 能穩定收到且訂單狀態正確更新,再申請正式環境上線。