訂單臨門一腳,錢卻進不來?WordPress 金流串接終極指南:ECPay 與 HitPay API 實戰全解析
大家好,我是浪花科技的資深工程師 Eric。在我們開發團隊,最常聽到的緊急求救大概就是:「Eric!客戶說他付了錢,但後台訂單狀態還是『待付款』,怎麼辦?!」這種事通常發生在半夜或假日,相信我,半夜被叫起來處理掉單問題,絕對不是什麼有趣的經驗。
網站的最後一哩路——金流,往往也是最脆弱的一環。一個不穩定的金流外掛、一次未經測試的更新,都可能讓你的訂單停擺,營收瞬間歸零。今天,我不想只教你裝哪個外掛,而是要帶你深入核心,從 API 的角度,徹底搞懂 WordPress 的第三方支付 API 串接實作,並以台灣最普及的 ECPay (綠界) 和放眼國際市場的 HitPay 為例,一步步帶你打造穩定又可控的金流系統。
為什麼你需要手動串接 API,而不是只用現成外掛?
我知道,你心裡可能在想:「WordPress 社群有上百個金流外掛,為什麼我要自找麻煩去碰程式碼?」這問題問得很好。身為一個有點囉嗦的工程師,我得說,方便的工具往往隱藏著你看不到的代價。
我遇過一個客戶,他的 WooCommerce 網站原本用某個知名的金流外掛,運作順暢。直到有一天,外掛作者發布了一個「安全性更新」,結果更新後,結帳頁面直接白畫面。整整半天,一筆訂單都沒成交,損失慘重。這就是過度依賴單一外掛的風險。
手動串接 API 聽起來很嚇人,但它能帶給你無可取代的優勢:
- 高度客製化的結帳流程: 不再被外掛的版型綁架,你可以自由設計符合品牌形象與使用者體驗的結帳頁面,甚至整合分期付款、紅利點數折抵等複雜邏輯。
- 卓越的效能與穩定性: 現成外掛為了應付各種情境,常常包山包海,載入一堆你根本用不到的程式碼,拖慢網站速度。自己串接,程式碼精簡高效,只做你需要的事,穩定性自然高。
- 滴水不漏的安全性: 你完全清楚每一行程式碼的用途,可以親自把關資料傳遞的每個環節,避免外掛潛在的後門或漏洞。
- 擺脫「外掛孤兒」的窘境: 你再也不用擔心外掛作者停止維護,或是更新後跟你的佈景主題、其他外掛打架。系統的命脈,掌握在自己手裡。
當然,這不代表外掛一無是處。對於標準需求的網站,它們是快速上線的好幫手。但如果你追求極致的穩定、效能與客製化,那麼,捲起袖子跟著我一起搞懂 API 吧!
金流串接前的準備:你需要知道的「黑話」
在我們一頭栽進程式碼的大海前,得先搞懂幾個金流世界的術語,不然你會像在海上沒帶羅盤一樣,很快就迷失方向。這就像我們工程師在溝通前,要先對齊彼此對「規格」的定義一樣重要。
關鍵角色:特店、收單行、發卡行
- 特店 (Merchant): 就是你,經營網站的店家。
- 收單行 (Acquirer Bank): 與你簽約、處理你信用卡交易的銀行或第三方支付公司(例如 ECPay、HitPay)。
- 發卡行 (Issuer Bank): 核發信用卡給消費者的銀行。
簡單說,客人刷卡後,錢是從「發卡行」到「收單行」,最後再由「收單行」撥款給你這位「特店」。
關鍵流程:授權 (Authorization) vs. 請款 (Capture)
- 授權 (Authorization): 客人按下結帳按鈕,金流系統會先向發卡行確認這張卡是否有效、額度是否足夠,如果都 OK,就先「圈存」這筆金額,但錢還沒真的轉出去。
- 請款 (Capture): 你確認要出貨時,再通知金流系統進行「請款」,這時錢才會真正從客人的戶頭扣除,轉到你的帳戶。
大部分第三方支付都將這兩步合併為一步,但理解這個概念有助於你處理更複雜的交易,例如訂金或延遲扣款。
關鍵技術:API、SDK、Webhook
- API (Application Programming Interface): 應用程式介面。你可以把它想像成一個「點餐窗口」,你的網站(客戶端)透過 API 向金流商的伺服器(廚房)下訂單(發起交易請求),廚房處理完後再透過 API 把餐點(交易結果)送回來。
- SDK (Software Development Kit): 軟體開發套件。如果 API 是點餐窗口,SDK 就是金流商幫你準備好的「點餐專用 App」。它把複雜的 API 呼叫打包成簡單好用的函式,讓你不用自己拼湊原始的請求,是工程師的好朋友。
- Webhook: 這非常、非常重要!你可以把它想像成一個「叫號通知器」。當客人在金流商的頁面完成付款後,金流商的伺服器會「主動」發送一個通知到你指定的網址(Webhook URL),告訴你「嘿!這筆訂單付錢囉!」。這是確認訂單狀態最可靠的方式,絕對不能只依賴使用者跳轉回來的頁面,因為使用者可能在跳轉前就關掉瀏覽器了。
實戰開始:串接台灣主流金流 ECPay (綠界科技)
好了,理論課結束,開始動手吧!ECPay 在台灣的市佔率極高,幾乎是電商網站的標配。我們這裡不透過官方外掛,直接用 PHP 來實作一個基本的交易流程。
Step 1: 取得 ECPay 測試金鑰
首先,你必須到 ECPay 的廠商後台,在「系統開發管理」>「系統介接設定」中,取得你的測試用的「特店編號 (MerchantID)」、「HashKey」和「HashIV」。切記!開發階段一定要用測試環境,不要拿真錢開玩笑。
Step 2: 建立訂單傳送表單與 CheckMacValue
ECPay 的運作方式是,你的網站需要產生一個 HTML 表單,裡面包含所有交易資訊,然後自動提交到 ECPay 的伺服器。其中最重要的參數是 CheckMacValue,這是一個「交易驗證碼」,用來防止訂單資料在傳輸過程中被惡意篡改。
這段 PHP 程式碼會示範如何生成這個表單,你可以把它放在你的結帳頁面邏輯中:
<?php
// 引入 ECPay SDK (假設你已經透過 Composer 安裝)
// require __DIR__ . '/vendor/autoload.php';
// 為了方便展示,這裡直接定義產生 CheckMacValue 的函式
function generate_ecpay_check_mac_value($params, $hashKey, $hashIV) {
ksort($params);
$macValue = 'HashKey=' . $hashKey;
foreach ($params as $key => $value) {
$macValue .= '&' . $key . '=' . $value;
}
$macValue .= '&HashIV=' . $hashIV;
$macValue = urlencode($macValue);
$macValue = strtolower($macValue);
// 處理特殊字元,這是 ECPay 文件要求的
$macValue = str_replace('%2d', '-', $macValue);
$macValue = str_replace('%5f', '_', $macValue);
$macValue = str_replace('%2e', '.', $macValue);
$macValue = str_replace('%21', '!', $macValue);
$macValue = str_replace('%2a', '*', $macValue);
$macValue = str_replace('%28', '(', $macValue);
$macValue = str_replace('%29', ')', $macValue);
$macValue = hash('sha256', $macValue);
return strtoupper($macValue);
}
// ECPay 測試環境資訊
$merchantID = '2000132'; // 測試用特店編號
$hashKey = '5294y06JbISpM5x9'; // 測試用 HashKey
$hashIV = 'v77hoKGq4kWxNNIS'; // 測試用 HashIV
$apiURL = 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5'; // 測試用 API URL
// 訂單基本資訊 (這些應該從你的 WooCommerce 訂單動態產生)
$tradeNo = 'Roamer' . time(); // 訂單編號,每次都要不一樣
$tradeDate = date('Y/m/d H:i:s');
$totalAmount = 1500;
$tradeDesc = '浪花科技商品一批';
$itemName = 'WordPress 技術顧問服務';
// 建立要加密的參數陣列
$params_to_encode = [
'MerchantID' => $merchantID,
'MerchantTradeNo' => $tradeNo,
'MerchantTradeDate' => $tradeDate,
'PaymentType' => 'aio',
'TotalAmount' => $totalAmount,
'TradeDesc' => $tradeDesc,
'ItemName' => $itemName,
'ReturnURL' => 'https://roamer-tech.com/ecpay-return', // 接收後端通知的 Webhook URL
'ChoosePayment' => 'Credit',
'EncryptType' => 1, // 固定為 1
];
// 計算 CheckMacValue
$checkMacValue = generate_ecpay_check_mac_value($params_to_encode, $hashKey, $hashIV);
// 建立完整表單參數
$form_params = array_merge($params_to_encode, ['CheckMacValue' => $checkMacValue]);
// 產生 HTML 表單
echo '<form id="ecpay-form" method="post" action="' . $apiURL . '">';
foreach ($form_params as $key => $value) {
echo '<input type="hidden" name="' . $key . '" value="' . $value . '" />';
}
echo '</form>';
echo '<script type="text/javascript">document.getElementById("ecpay-form").submit();</script>';
Step 3: 處理 ECPay 的回傳通知 (Webhook)
當使用者付款成功後,ECPay 會發送一個 POST 請求到你在 ReturnURL 指定的網址。你的任務就是建立一個端點來接收這個通知,並且「反向驗證」它回傳的 CheckMacValue,確認這筆通知真的是 ECPay 發來的,而不是駭客偽造的。
<?php
// 假設這段程式碼放在 /ecpay-return 這個端點
// 取得 ECPay POST 回來的資料
$ecpay_response = $_POST;
// 再次取得你的 HashKey 和 HashIV
$hashKey = '5294y06JbISpM5x9';
$hashIV = 'v77hoKGq4kWxNNIS';
// 把回傳的 CheckMacValue 暫時取出來,不要加入驗算
$received_mac_value = $ecpay_response['CheckMacValue'];
unset($ecpay_response['CheckMacValue']);
// 用同樣的邏輯,產生一次本地的 CheckMacValue
$local_mac_value = generate_ecpay_check_mac_value($ecpay_response, $hashKey, $hashIV); // 假設 generate_ecpay_check_mac_value 函式已定義
// 比對收到的和本地產生的 CheckMacValue
if ($received_mac_value === $local_mac_value) {
// 驗證成功!
// 根據 $ecpay_response['RtnCode'] 的值來判斷交易是否成功
if ($ecpay_response['RtnCode'] == '1') {
// 交易成功!
$order_id = $ecpay_response['MerchantTradeNo'];
// 在這裡更新你的 WordPress 資料庫,將對應的訂單狀態改為「已付款」
// 例如:wc_get_order($order_id)->payment_complete();
echo '1|OK'; // 必須回傳這個字串給 ECPay,不然他會一直重試
} else {
// 交易失敗
// 記錄錯誤 log
error_log('ECPay payment failed: ' . print_r($ecpay_response, true));
}
} else {
// 驗證失敗!這可能是偽造的請求,千萬不要更新訂單狀態
error_log('ECPay CheckMacValue verification failed.');
echo '0|Error';
}
跨足東南亞:串接 HitPay
如果你的業務範圍涵蓋東南亞或全球,HitPay 是一個非常方便的選擇,它整合了各國主流的在地支付方式。它的串接邏輯和 ECPay 略有不同,它更偏向於 server-to-server 的 API 呼叫。
Step 1: 取得 HitPay API 金鑰
登入 HitPay 後台,在「Settings」>「Payment Gateway」>「API Keys」中,你可以產生一組 API Key 和 Salt。這兩個值就是你跟 HitPay API 溝通的憑證。
Step 2: 使用 cURL (或 wp_remote_post) 發送付款請求
與 ECPay 不同,HitPay 建議由你的伺服器直接向他們的 API 發起請求來建立一筆交易,成功後會回傳一個付款頁面的 URL,你再把使用者導向那個 URL 即可。
<?php
// HitPay API 資訊
$apiKey = 'YOUR_HITPAY_API_KEY'; // 替換成你的 API Key
$salt = 'YOUR_HITPAY_SALT'; // 替換成你的 Salt
$apiURL = 'https://api.sandbox.hit-pay.com/v1/payment-requests'; // 測試環境 URL
// 訂單資訊
$amount = 25.50;
$email = 'customer@example.com';
$order_id = 'RoamerHP' . time();
// 建立簽名 (HMAC)
// HitPay 要求將參數值串接起來用 Salt 加密
$data_string = $amount . $email . $order_id;
$signature = hash_hmac('sha256', $data_string, $salt);
// 準備 POST 的資料
$body = [
'amount' => $amount,
'email' => $email,
'reference_number' => $order_id,
'webhook' => 'https://roamer-tech.com/hitpay-webhook', // 你的 Webhook URL
'redirect_url' => 'https://roamer-tech.com/thank-you',
'hmac' => $signature
];
$args = [
'body' => json_encode($body),
'headers' => [
'Content-Type' => 'application/json',
'X-BUSINESS-API-KEY' => $apiKey,
'X-REQUEST-ID' => uniqid()
],
'method' => 'POST',
'data_format' => 'body'
];
// 使用 WordPress 內建的方式發送請求
$response = wp_remote_post($apiURL, $args);
if (is_wp_error($response)) {
// 請求失敗
error_log('HitPay API request failed: ' . $response->get_error_message());
} else {
$response_body = json_decode(wp_remote_retrieve_body($response), true);
if (!empty($response_body['url'])) {
// 成功取得付款網址,將使用者導過去
wp_redirect($response_body['url']);
exit;
}
}
Step 3: 驗證 HitPay Webhook
同樣地,最關鍵的步驟在於接收並驗證 Webhook。HitPay 會將交易結果 POST 到你指定的 Webhook URL,並在 POST data 中附上一個 hmac 簽名,你需要用同樣的方式在你的伺服器端產生一次簽名並比對。
<?php
// 假設這段程式碼放在 /hitpay-webhook 端點
// 取得 HitPay POST 回來的資料
$hitpay_response = $_POST;
// 你的 Salt
$salt = 'YOUR_HITPAY_SALT';
// 取得收到的 hmac
$received_hmac = $hitpay_response['hmac'];
// 組合要驗證的字串
$data_to_verify = $hitpay_response['payment_request_id'] . $hitpay_response['reference_number'] . $hitpay_response['status'] . $hitpay_response['amount'];
// 在本地產生一次 hmac
$local_hmac = hash_hmac('sha256', $data_to_verify, $salt);
if ($received_hmac === $local_hmac) {
// 驗證成功!
if ($hitpay_response['status'] === 'completed') {
// 付款成功
$order_id = $hitpay_response['reference_number'];
// 更新 WordPress 訂單狀態
// wc_get_order($order_id)->payment_complete();
http_response_code(200); // 回應 200 OK 給 HitPay
} else {
// 其他狀態(失敗、待處理等)
error_log('HitPay payment status: ' . $hitpay_response['status']);
}
} else {
// 驗證失敗
error_log('HitPay HMAC verification failed.');
http_response_code(400); // 回應錯誤
}
工程師的小囉嗦:金流串接的魔鬼細節
程式碼能動,不代表專案就完成了。金流是網站的心臟,任何一點小疏忽都可能造成災難。身為一個踩過無數坑的工程師,請容我再囉嗦幾句:
- 日誌記錄 (Logging) 是你的救命稻草: 拜託,務必、一定要記錄所有金流相關的 Log!包括你發送出去的請求、收到的回應、Webhook 的內容。當客戶、金流商、你三方資訊對不起來時,Log 是你唯一的真相來源。
- 滴水不漏的錯誤處理: 如果 ECPay 的伺服器剛好在維護,你的 API 請求失敗了怎麼辦?要設計好重試機制,或是提示使用者稍後再試,而不是直接讓網站掛掉。
- 交易的冪等性 (Idempotency): 這是一個很重要的概念。要確保同一個操作,不管執行一次還是執行一百次,結果都一樣。例如,防止使用者因為網路延遲,重複點擊結帳按鈕,導致被重複扣款。最簡單的方式就是用獨一無二的訂單編號來識別每一筆交易。
- 安全,安全,還是安全: 永遠不要在你的資料庫儲存完整的信用卡號碼。所有敏感的通訊都必須在 HTTPS (SSL) 加密下進行。務必驗證所有來自 Webhook 的請求,因為那是唯一能確認付款狀態的管道,如果被偽造就完了。
看到這裡,是不是覺得金流串接的水比想像中深?沒錯,這是一個需要極度細心與嚴謹的領域。它不只關乎技術,更關乎客戶的信任與公司的營收。
相關閱讀
- 告別手動上架地獄!WooCommerce 商品 API 終極實戰,讓你的庫存、ERP 同步自動化!
- 告別手動複製貼上!WooCommerce Webhook 終極指南:打造零失誤、全自動的訂單處理流程
- 結帳頁面卡關=訂單掰掰?資深工程師帶你動刀 WooCommerce,打造絲滑結-帳體驗,轉換率飆升!
如果你正在為金流整合問題頭痛,或是希望打造一個更客製化、更穩定的電商平台,浪花科技的團隊擁有豐富的 API 串接與 WooCommerce 開發經驗。我們不只會幫你「接起來」,更會為你考慮到所有潛在的風險與效能問題。歡迎點擊這裡,填寫表單與我們聯繫,讓我們為你的事業打造最穩固的數位金庫!
常見問題 (FAQ)
Q1: 為什麼不直接使用現成的金流外掛就好?
A1: 對於標準需求的網站,現成外掛是快速方便的選擇。但若您追求高度客製化的結帳流程、極致的網站效能、或是需要整合特殊的商業邏輯(如訂閱制、分期付款),手動串接 API 提供了無可比擬的彈性與穩定性。此外,也能避免因外掛更新出錯或停止維護,而導致整個金流系統癱瘓的風險。
Q2: ECPay (綠界) 和 HitPay 應該如何選擇?
A2: 這完全取決於您的目標市場。如果您的主要客戶群在台灣,ECPay 提供了最完整的在地支付選項(信用卡、超商代碼、ATM轉帳等),是首選。如果您的業務放眼國際,特別是東南亞市場,HitPay 則整合了多國的在地支付方式 (如 PayNow, GrabPay 等),能提供更友善的在地化付款體驗。
Q3: 在金流 API 串接中最常犯的錯誤是什麼?
A3: 最常見也最致命的錯誤,就是「沒有確實驗證 Webhook 的簽名 (CheckMacValue 或 HMAC)」。很多開發者只依賴使用者從付款頁面跳轉回來的前端訊息來更新訂單狀態,這是非常不安全的。駭客可以輕易偽造一個請求,讓您的系統誤以為訂單已付款。請務必以後端對後端 (Server-to-Server) 的 Webhook 通知為準,並嚴格驗證其來源的真實性。
Q4: 我的網站要串接金流,一定要安裝 SSL 憑證嗎?
A4: 是的,絕對必須!這不是選項,而是標配。安裝 SSL 憑證啟用 HTTPS 加密連線,是保障您與客戶之間資料傳輸安全的基礎。所有主流金流服務商都強制要求您的網站必須使用 HTTPS。這不僅是為了安全,更是為了建立客戶對您網站的信任感,沒有人敢在一個顯示「不安全」的網站上輸入信用卡資訊。






