本篇記錄開發WooCommerce金流的心得,使用GitHub Copilot協同開發,開發過程更理解了WooCommerce的完整流程,基本上此流程可以套用在不同第三方金流平台會更加順手。
本次開發採用的精誠金流串接~
精誠金流API與WordPress外掛
https://github.com/systexfintech/WooCommerce8.9.x
https://www.systexfintech.com/api-page
付款流程圖

快速觀念總結
- 回調策略:只保留 Server 回調(ReturnURL)即可;OrderResultURL 可省略,用 ClientBackURL 導回感謝頁。
- 標準 endpoint:使用 woocommerce_api_{slug} Action,而非在 init 手動讀 wc-api。
- 分期 UI:後台可多選 3/6/12/24;結帳頁下拉選單 + validate_fields 驗證。
- 驗簽:CheckMacValue 按金流規範排序與編碼計算;回調時必驗。
- 訂閱:除 Server 回調外,需加 PeriodReturnURL(週期扣款通知)。
一、回調與導回設計
- Server 回調(必要)
- 金流 POST 到你的 ReturnURL。用來更新訂單與紀錄交易。
- WooCommerce 建議使用 woocommerce_api_{gateway_id} 綁定處理器。
- 前端導回
- OrderResultURL:可省略。
- ClientBackURL:導回感謝頁($order->get_checkout_order_received_url())。
- 訂閱專用
- PeriodReturnURL:每次週期扣款完成的通知,必須實作。
二、正確註冊 WooCommerce API endpoint
- 一次付清與分期:只保留 Server 回調
- 訂閱:加上週期回調
<?php
// 一次付清(Server 回調)
add_action('woocommerce_api_orca_syspay_credit', [$this, 'handle_payment_callback']);
// 分期(Server 回調)
add_action('woocommerce_api_orca_syspay_installment', [$this, 'handle_payment_callback']);
// 訂閱(Server 回調 + 週期回調)
add_action('woocommerce_api_orca_syspay_subscription', [$this, 'handle_payment_callback']);
add_action('woocommerce_api_orca_syspay_subscription_period', [$this, 'handle_payment_period_callback']);
// 產生回調 URL(送單時帶給金流)
$return_credit = WC()->api_request_url('orca_syspay_credit');
$return_inst = WC()->api_request_url('orca_syspay_installment');
$return_period = WC()->api_request_url('orca_syspay_subscription_period');
三、信用卡分期:後台設定 + 結帳 UI
- 後台設定:orca_wooplus_syspay_installment_terms 多選 3/6/12/24(未儲存時前端回退預設)
- 結帳頁
- 設定 $this->has_fields = true 才會渲染自訂欄位。
- payment_fields() 輸出下拉;validate_fields() 驗證期數是否在允許清單。
<?php
// 允許的分期期數(未設定則回退)
private function get_allowed_installment_terms() {
$default = ['3','6','12','24'];
$raw = get_option('orca_wooplus_syspay_installment_terms', $default);
if (!is_array($raw)) {
$raw = trim((string) $raw);
$raw = ($raw === '') ? [] : array_map('trim', explode(',', $raw));
}
$valid = ['3','6','12','24'];
$filtered = array_values(array_intersect($valid, array_map('strval', $raw)));
return empty($filtered) ? $default : $filtered;
}
四、建立交易參數與感謝頁導回
- 必要參數:MerchantID、MerchantTradeNo、MerchantTradeDate、TotalAmount、TradeDesc、ItemName、ChoosePayment、ReturnURL
- 分期額外:CreditInstallment(3/6/12/24)
- 導回感謝頁:ClientBackURL = $order->get_checkout_order_received_url()
- 不送 OrderResultURL (ps:僅使用Server Callback回傳就好,不需要多前端的)
<?php
$params = [
'MerchantID' => $this->merchant_id,
'MerchantTradeNo' => $this->generate_merchant_trade_no($order),
'MerchantTradeDate' => date('Y/m/d H:i:s'),
'TotalAmount' => (int) $order->get_total(),
'TradeDesc' => sprintf('訂單 #%s', $order->get_order_number()),
'ItemName' => $this->get_item_name($order),
'ChoosePayment' => 'Credit',
'ReturnURL' => $return_inst, // or $return_credit
'ClientBackURL' => $order->get_checkout_order_received_url(),
// 分期才需要
'CreditInstallment' => (string) $term,
];
$params['CheckMacValue'] = $this->generate_check_mac_value($params);
五、CheckMacValue 驗簽重點
- 刪掉 CheckMacValue → 依 A-Z 排序 → 串 HashKey/參數/HashIV → urlencode → 小寫 → 特殊字元替換 → SHA256 → 大寫。
- Server 回調時必須重算比對,才更新訂單。
六、常見錯誤與排除
- 子類簽名不相容(Fatal: must be compatible)
- 子類 prepare_payment_params($order, $term = null) 保持與父類 abstract protected function prepare_payment_params($order) 相容。
- 分期 UI 不顯示或判定未設定
- 沒有儲存選項時 get_option 可能回空;前端以 3/6/12/24 回退。
- 確認 $this->has_fields = true。
- 回調驗證失敗
- 確認使用 woocommerce_api_{gateway_id} endpoint,回調以 POST 送達。
- 必填欄位齊全(MerchantID、MerchantTradeNo、RtnCode、CheckMacValue…)且檢查碼一致。
- 感謝頁網址
- $order->get_checkout_order_received_url()(/checkout/order-received/{id}?key=wc_order_xxx)
- $order->get_checkout_order_received_url()(/checkout/order-received/{id}?key=wc_order_xxx)
- 目前我專案是使用$this->get_return_url($order) 只是 WooCommerce Gateway 的包裝,內部會回傳 $order->get_checkout_order_received_url(),並套用過濾器 woocommerce_get_return_url。
- 因此兩者都指向感謝頁(order-received),差別只在前者可被外掛過濾器攔截調整,較建議在金流模組內使用。
七、最佳實務清單
- 僅用 Server 回調更新訂單;前端導回以 ClientBackURL。
- 訂閱必加 PeriodReturnURL。
- 後台提供「啟用分期」與「分期期數」設定。
- 記錄交易資料與回調原文於安全日誌,避免洩漏 HashKey/HashIV。
- 在測試環境完整走一次:下單 → 付款 → 回調 → 感謝頁 → 訂單狀態與備註。