訂單堆積如山? WooCommerce 物流 API 串接終極實戰,從黑貓、宅配通到超取,打造全自動出貨帝國!

2025/08/22 | WC 開發

文章目錄

訂單堆積如山? WooCommerce 物流 API 串接終極實戰,從黑貓、宅配通到超取,打造全自動出貨帝國!

嗨,我是浪花科技的 Eric。身為一個每天在程式碼跟伺服器之間打滾的工程師,我看過太多電商經營者被一個看似簡單、實則磨人的環節搞到心力交瘁——那就是「出貨」。當訂單從一天幾張變成幾十張、甚至幾百張時,那種手動複製貼上收件人資料、key-in 託運單、再把追蹤碼一個個填回網站後台的循環,根本就是一場沒有盡頭的惡夢。不只耗時,還非常容易出錯,寄錯地址的客訴電話接到手軟,真的是想到就頭皮發麻。

今天,我們就要來徹底終結這場惡夢。我要帶你深入 WordPress 的心臟地帶,手把手教你如何透過 物流 API 串接,將你的 WooCommerce 網站改造成一台全自動的出貨處理機器。無論你的合作夥伴是黑貓宅急便宅配通,還是人人都愛的超商取貨 (7-11/全家),這篇文章都會給你一個清晰的實戰藍圖。別再當複製貼上的工人了,把時間花在更重要的事情上吧!

為什麼你需要的是 API 串接,而不是更多的實習生?

在我們一頭栽進程式碼之前,先來聊聊「為什麼」。很多老闆可能會想:「請個工讀生來處理不就好了?」嗯,這是一個典型的線性思維。但身為工程師,我們追求的是可規模化、可擴展、且錯誤率趨近於零的解決方案。這就是 物流 API 串接 的價值所在。

簡單來說,API (Application Programming Interface) 就像是你的網站和物流公司系統之間的一個「專屬翻譯官兼傳令兵」。當顧客下單後,你可以透過 API 自動把訂單資訊(收件人、地址、電話、商品內容等)傳送給物流公司,物流公司處理完後,也會透過 API 回傳一個最重要的東西:託運單號(Tracking Number)。

  • 效率的極致: 從訂單成立到產生託運單,整個過程可以在幾秒鐘內自動完成。一天 1000 筆訂單?沒問題,你的伺服器不會喊累。
  • 準確性的保障: 機器不會像人一樣眼花看錯地址。只要顧客輸入的資料正確,傳送過去的資料就是 100% 正確,大幅降低寄錯貨的機率。
  • 提升顧客體驗: 託運單號自動回填到訂單,並透過 email 通知顧客。顧客可以隨時查詢包裹進度,這種透明、即時的服務是建立品牌信任感的關鍵。
  • 釋放寶貴人力: 你或你的團隊再也不用被困在出貨的瑣事中,可以專注於行銷、客服、產品開發等更有價值的工作。

老實說,看著程式自動跑完幾百筆訂單的出貨流程,那種成就感,絕對比手動 key-in 到半夜三點還要爽快多了。

開工前的準備:你的「軍火庫」盤點

在我們開始寫 Code 之前,請確保你已經準備好以下幾樣東西。記住,準備工作做得越足,後面的過程就越順利,這跟蓋房子打地基是同一個道理。

  • 一個穩定的 WordPress + WooCommerce 環境: 這應該不用我多說了。
  • 物流公司的 API 帳號與金鑰 (API Key/Secret): 這是你的通關密語。你需要向合作的物流商(黑貓、宅配通等)申請 API 串接服務。他們的審核流程和文件提供的完整度… 嗯,只能說每家都很有自己的風格。你需要耐心點,並準備好一杯濃咖啡來閱讀那些 API 文件。
  • 一個測試站 (Staging Environment): 這是最重要的! 我要用粗體字再強調一次。絕對、絕對、絕對不要在正式營運的網站上直接開發串接功能! 你不會想看到測試訂單真的被物流司機取走,或是正式訂單因為你的程式碼 bug 而遺失。
  • 基本的 PHP 和 WordPress Hooks 知識: 我們會用到 WordPress 的 Action Hooks 來觸發我們的程式,所以對 `add_action` 這類函式有點概念會很有幫助。如果你還不熟,可以先看看我們寫的 Action 和 Filter 你真的懂了嗎?資深工程師揭秘 WordPress Hooks 的『架構思維』

串接實戰:讓程式碼動起來!

好了,理論講完了,我們來點硬核的。接下來,我會以一個通用的邏輯框架,帶你走過整個串接流程。雖然每家物流的 API 欄位和格式略有不同,但核心思想是完全一樣的。

第一步:決定觸發時機 (The Trigger)

我們需要在一個完美的時機點,自動執行「傳送訂單到物流系統」這個動作。在 WooCommerce 的世界裡,最適合的時機點就是訂單狀態被更新為「處理中 (Processing)」的時候。因為這通常代表店家已經確認收到款項,準備要出貨了。

我們會使用 `woocommerce_order_status_processing` 這個 hook。把下面的程式碼加到你的子主題的 `functions.php` 或是自訂的功能性外掛中。


/**
 * 當訂單狀態變為「處理中」時,觸發物流 API 串接
 * @param int $order_id 訂單 ID
 */
add_action( 'woocommerce_order_status_processing', 'roamer_trigger_shipping_api', 10, 1 );

function roamer_trigger_shipping_api( $order_id ) {
    // 避免重複執行,先檢查是否已經有託運單號
    if ( get_post_meta( $order_id, '_shipping_tracking_number', true ) ) {
        return;
    }

    // 在這裡呼叫我們的主力函式
    roamer_create_shipment( $order_id );
}

這裡我加了一個小小的防呆機制:先檢查訂單是否已經有了託運單號 (`_shipping_tracking_number`)。這可以避免因為某些操作(例如手動更新訂單)導致重複向物流公司建立訂單,省下不必要的麻煩和費用。

第二步:撈取訂單資料並組裝 API 請求

觸發之後,我們需要從訂單中把物流公司需要的資料全部抓出來,然後組裝成他們看得懂的格式(通常是 JSON)。


function roamer_create_shipment( $order_id ) {
    $order = wc_get_order( $order_id );

    if ( ! $order ) {
        error_log( "無法取得訂單物件,訂單 ID: {$order_id}" );
        return;
    }

    // 組裝要發送到物流 API 的資料
    $api_data = array(
        'CustomerID' => 'YOUR_CUSTOMER_ID', // 你的客戶代號
        'SenderName' => '浪花科技',
        'SenderPhone' => '02-12345678',
        'SenderAddress' => '台北市信義區信義路五段7號',
        'ReceiverName' => $order->get_shipping_first_name() . ' ' . $order->get_shipping_last_name(),
        'ReceiverPhone' => $order->get_billing_phone(), // 通常送貨電話會填在帳單電話
        'ReceiverAddress' => $order->get_shipping_address_1() . $order->get_shipping_address_2(),
        'ParcelSize' => '2', // 1:小 2:中 3:大 (依據 API 文件)
        'CODAmount' => $order->get_payment_method() === 'cod' ? $order->get_total() : 0, // 如果是貨到付款,帶入金額
        'OrderNo' => $order->get_order_number() // 你的訂單編號,方便對帳
    );

    // 特別處理超商取貨:需要取得電子地圖選擇的門市代號
    if ( strpos( $order->get_shipping_method(), 'c2c' ) !== false ) {
        $store_id = get_post_meta( $order_id, '_c2c_store_id', true );
        if ( empty( $store_id ) ) {
            error_log( "超商取貨訂單缺少門市代號,訂單 ID: {$order_id}" );
            // 你可以在這裡新增一個管理員通知,或是將訂單標示為需要手動處理
            return;
        }
        $api_data['StoreID'] = $store_id;
        // 超商取貨通常不需要地址
        unset($api_data['ReceiverAddress']);
    }

    // 下一步:發送 API 請求
    roamer_send_api_request( $order_id, $api_data );
}

這段程式碼的重點在於:

  • 我們用 `wc_get_order()` 取得了完整的訂單物件。
  • 從訂單物件中,我們把收件人的姓名、電話、地址等資訊一個個拿出來。
  • 針對「貨到付款 (COD)」做了判斷。
  • 超商取貨的特別處理:這是一個大重點。通常超商取貨的流程是,客戶在結帳頁面點擊一個按鈕,跳出物流商提供的電子地圖,選擇門市後,該門市的「代號」會被存到訂單的 meta data 裡 (這裡我假設它叫 `_c2c_store_id`)。所以在組裝 API 資料時,我們需要去撈這個門市代號,而不是收件地址。

第三步:發送請求並處理回傳結果

資料組裝好了,接下來就是把它發射出去。WordPress 內建了 `wp_remote_post()` 函式,非常適合用來處理這種 API 請求。


function roamer_send_api_request( $order_id, $api_data ) {
    $api_url = 'https://api.logistics-company.com/v1/create-shipment'; // 這裡換成真實的 API 端點
    $api_key = 'YOUR_API_KEY'; // 你的 API 金鑰

    $args = array(
        'body'    => json_encode( $api_data ),
        'headers' => array(
            'Content-Type'  => 'application/json',
            'Authorization' => 'Bearer ' . $api_key // 認證方式可能不同,請參考文件
        ),
        'timeout' => 30, // 30 秒逾時
    );

    $response = wp_remote_post( $api_url, $args );

    if ( is_wp_error( $response ) ) {
        // 請求本身就失敗了,例如網路問題
        $error_message = $response->get_error_message();
        error_log( "物流 API 請求失敗,訂單 ID: {$order_id},錯誤:{$error_message}" );
        $order = wc_get_order( $order_id );
        $order->add_order_note( '物流 API 請求失敗:' . $error_message ); // 在訂單備註中留下紀錄
        return;
    }

    $response_code = wp_remote_retrieve_response_code( $response );
    $response_body = wp_remote_retrieve_body( $response );
    $result = json_decode( $response_body, true );

    if ( $response_code == 200 && !empty( $result['TrackingNumber'] ) ) {
        // 成功!我們拿到託運單號了!
        $tracking_number = $result['TrackingNumber'];
        update_post_meta( $order_id, '_shipping_tracking_number', $tracking_number );

        // 在訂單備註中加入成功訊息和單號
        $order = wc_get_order( $order_id );
        $order->add_order_note( '成功建立物流訂單,託運單號:' . $tracking_number );

        // (選做) 你甚至可以在這裡自動將訂單狀態更新為「已完成」,並觸發通知信
        // $order->update_status( 'completed', '已自動產生託運單號並完成訂單。' );

    } else {
        // API 回傳了錯誤
        $error_message = isset($result['ErrorMessage']) ? $result['ErrorMessage'] : '未知的錯誤';
        error_log( "物流 API 建立失敗,訂單 ID: {$order_id},回傳:{$response_body}" );
        $order = wc_get_order( $order_id );
        $order->add_order_note( '物流 API 建立失敗:' . $error_message );
    }
}

這段程式碼是整個流程的核心。我們做了幾件重要的事:

  1. 設定 API 的 URL 和認證資訊 (Authorization Header)。
  2. 使用 `wp_remote_post()` 發送請求。
  3. 滴水不漏的錯誤處理: 我們分別檢查了「請求本身是否失敗 (is_wp_error)」和「API 是否回傳成功 (HTTP status code 200)」。這非常重要!任何一個環節出錯,我們都必須記錄下來。
  4. 將錯誤或成功訊息寫入 `error_log` (給工程師看) 和訂單備註 `add_order_note` (給管理員看)。
  5. 如果成功,使用 `update_post_meta()` 將最重要的託運單號存起來。

有了這套機制,你的 WooCommerce 網站就從一個單純的商店,進化成一個具備初步自動化能力的電商大腦了。

結論:自動化不是終點,而是起點

恭喜你!跟著這篇文章走下來,你已經掌握了 WooCommerce 物流 API 串接 的核心技術與思維。從此以後,你再也不用害怕訂單爆量的甜蜜負荷。這套自動化流程不僅為你省下了無數小時的重複勞動,更重要的是,它為你的事業規模化鋪平了道路。

當然,現實世界的串接會比上面的範例更複雜一點,你可能需要處理更細緻的錯誤回報、列印標籤的 API、甚至是庫存同步等等。但萬變不離其宗,掌握了今天的核心框架,你就有了應對更複雜挑戰的基礎。

身為工程師,我們始終相信,好的技術就該為人類解決繁瑣的問題,讓我們能專注於創造與思考。如果你覺得這整個過程還是太過複雜,或是你需要一個更穩定、更全面的企業級電商自動化解決方案,浪花科技的團隊隨時準備好為你服務。我們專注於打造高效能、高穩定性的客製化系統,讓技術成為你事業成長的最強引擎。

準備好讓你的電商事業起飛了嗎?立即聯繫我們,讓我們聊聊如何為你打造專屬的自動化工作流!

延伸閱讀

常見問題 (FAQ)

Q1: 我一定要自己寫程式碼嗎?市面上有沒有相關的外掛?

A: 市面上確實有一些整合台灣物流的外掛。它們的優點是安裝方便,適合不想碰程式碼的使用者。但缺點是彈性較低,如果你的出貨流程有特殊需求(例如:根據商品類型選擇不同物流、需要客製化標籤等),客製化開發的方案才能提供最大的靈活性與控制權。身為工程師,我們當然更推薦後者,因為你可以完全掌握每一個細節。

Q2: 觸發 API 的時機點,除了「處理中」之外,還有其他選擇嗎?

A: 當然有。`woocommerce_order_status_processing` 是一個最常見的選擇。但有些商家的流程可能是在確認撿貨完成後才要建立託運單,這時你也可以考慮建立一個自訂的訂單狀態,例如「等待出貨 (Awaiting Shipment)」,並使用 `woocommerce_order_status_awaiting-shipment` 作為觸發點。WordPress Hooks 的美妙之處就在於它的彈性。

Q3: 超商取貨的電子地圖 (E-MAP) 是怎麼整合進結帳頁面的?

A: 這通常是整個流程中比較棘手的部分。物流商會提供一段 JavaScript 程式碼或是一個 API 端點,你需要將它整合到你的結帳頁面。當使用者點擊「選擇門市」按鈕時,觸發這個 JS 來打開電子地圖。使用者選擇完門市後,地圖會回傳門市的代號、名稱等資訊,你需要再用 JavaScript / AJAX 的方式,將這些資訊回存到後端,並在訂單成立時將門市代號存入訂單的 meta 欄位中,以供後續 API 串接使用。

Q4: 我的 API Key 和 Secret 這些敏感資料,該如何安全地儲存?

A: 這是個非常好的問題!絕對不要直接把金鑰寫死在 `functions.php` 裡面,這樣非常不安全,尤其如果你的程式碼是公開的。比較好的做法是,將它們定義在 `wp-config.php` 檔案中,因為這個檔案通常不會被納入版本控制。例如: `define(‘LOGISTICS_API_KEY’, ‘your_actual_api_key’);`。在程式中再透過 `LOGISTICS_API_KEY` 這個常數來取用。對於更大型的專案,我們會使用環境變數 (.env) 的方式來管理,這是最安全也最專業的做法。

 
立即諮詢,索取免費1年網站保固