iT邦幫忙

2026 iThome 鐵人賽

0

購物車與結帳這兩個區塊是整個 WooCommerce 區塊化程度最高、也最容易讓有經驗的開發者踩坑的地方,原因是它們表面上還是「一個頁面」,實際上運作方式跟舊版完全不同 — 舊版是 PHP 產生表單、送出後整頁重載;新版是 React 畫的介面,透過 Store API 跟後端溝通。

先看舊版怎麼運作

回憶一下舊版結帳頁的生命週期:

  1. 使用者打開 /checkout/,PHP 執行 [woocommerce_checkout]
  2. WooCommerce 跑一連串 hook 組出 HTML 表單(woocommerce_checkout_fields 這時候生效)
  3. 使用者填完按「下單」,表單 POST 到伺服器
  4. PHP 驗證、建立訂單、呼叫金流的 process_payment()
  5. 回傳導向網址,整頁跳轉

整個流程的重心在伺服器端,前端只是一張表單。所以要改任何東西,改 PHP 就對了。

新版的生命週期

區塊結帳頁完全不同:

  1. 使用者打開 /checkout/,PHP 只輸出一個容器加上初始資料
  2. React 接手,打 GET /wc/store/v1/cart 拿購物車狀態,畫出表單
  3. 使用者每改一個東西(地址、運送方式、折價券),前端就打對應的 API,拿回完整的購物車狀態再重繪
  4. 按下單時前端打 POST /wc/store/v1/checkout,把表單資料一次送出
  5. 後端建立訂單、跑金流,回傳 payment_result
  6. 前端依 payment_result 決定要導向哪裡

差別在於:表單長什麼樣是前端決定的,後端只提供資料與 schema。 你在 PHP 端改 HTML 沒有意義,因為那段 HTML 根本不存在。

購物車端點回傳什麼

實測一下(這是公開端點,不用登入):

$ curl https://your-site.com/wp-json/wc/store/v1/cart

回傳的頂層欄位:

items, items_count, items_weight, totals, fees, coupons,
shipping_rates, shipping_address, billing_address,
needs_payment, needs_shipping, has_calculated_shipping,
payment_methods, payment_requirements, cross_sells, errors, extensions

幾個值得注意的:

  • totals 是後端算好的,前端不做任何金額計算 — 這很重要,代表折扣、稅、運費的邏輯全部留在 PHP,前端只負責顯示
  • shipping_rates 是可選的運送方式清單,選了之後打 /cart/select-shipping-rate 會拿回重算過的 totals
  • errors 是結構化的錯誤,前端據此顯示訊息
  • extensions 是留給你的空間,等一下會講

結帳端點 POST /wc/store/v1/checkout 接受的欄位則是:

billing_address, shipping_address, customer_note,
payment_method, payment_data, extensions

回傳裡最關鍵的是 payment_result

{
  "payment_result": {
    "payment_status": "success",
    "redirect_url": "https://your-site.com/checkout/order-received/123/..."
  }
}

前端拿到 payment_statusredirect_url 之後才決定跳轉。這個結構在之後串金流時會非常關鍵,因為你的金流要把使用者導到哪裡,是透過這個欄位傳回前端的

為什麼你熟悉的 hook 失效了

看這幾個常見的舊 hook:

舊 hook 在區塊結帳頁
woocommerce_checkout_fields ❌ 無效,表單不是 PHP 產生的
woocommerce_after_checkout_billing_form ❌ 無效,沒有這個插入點
woocommerce_checkout_process ⚠️ 部分情況不觸發
woocommerce_checkout_create_order ✅ 有效,訂單仍由 PHP 建立
woocommerce_thankyou ✅ 有效
woocommerce_order_status_* ✅ 有效

規律很清楚:跟「畫面」有關的 hook 失效,跟「訂單」有關的 hook 仍然有效。 因為訂單的建立、金流的處理、狀態的變化都還在 PHP 端跑,只有介面那一層搬到前端去了。

這也是為什麼之後提到金流、發票、物流時,很多做法跟舊版是一樣的,那些都發生在後端,只有當要新增欄位時,因為牽涉到畫面才需要用新的 API。

要放自訂資料,用 extensions

如果你需要在購物車或結帳的 API 回應裡帶自己的資料(例如「這張訂單符合免運資格」、「這個會員有多少點數」),對應的機制是 ExtendSchema

use Automattic\WooCommerce\StoreApi\StoreApi;
use Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema;

add_action( 'woocommerce_blocks_loaded', function () {
	$extend = StoreApi::container()->get( ExtendSchema::class );

	$extend->register_endpoint_data(
		array(
			'endpoint'        => 'cart',            // 只能是有效的 Store API 端點.
			'namespace'       => 'my-plugin',       // 必填,你的外掛命名空間.
			'schema_callback' => function () {
				return array(
					'points_balance' => array(
						'description' => __( '會員點數餘額', 'my-plugin' ),
						'type'        => 'integer',
						'readonly'    => true,
					),
				);
			},
			'data_callback'   => function () {
				return array( 'points_balance' => (int) get_user_meta( get_current_user_id(), 'points', true ) );
			},
		)
	);
} );

註冊之後,你的資料會出現在 /cart 回應的 extensions 底下:

{ "extensions": { "my-plugin": { "points_balance": 350 } } }

三件要注意的事:

  1. namespace 是必填的,而且要用你的外掛前綴,這是避免跟其他外掛撞名的唯一保護
  2. endpoint 必須是有效端點,給錯會直接丟例外,訊息會列出所有合法值
  3. 要掛在 woocommerce_blocks_loaded 之後,太早呼叫拿不到容器

交給 AI 時最容易拿到的錯誤答案

這一篇的內容是整個第四部裡 AI 最容易答錯的地方。你問「怎麼在 WooCommerce 結帳頁加一個欄位」,十次有八次會拿到 woocommerce_checkout_fields 的寫法,那是舊版做法,網路上有上千篇文章這樣寫,而區塊結帳頁上它一點反應都沒有。

分辨方法很簡單,看它給的東西碰不碰得到畫面

  • 只碰訂單、狀態、金流 → 舊做法多半仍然正確
  • 要改結帳頁的欄位、版面、驗證訊息 → 舊做法幾乎都無效,要用新的 API

還有一個實用的除錯習慣:遇到「改了沒反應」,先確認那個站的結帳頁到底是哪一種。打開結帳頁看原始碼,搜尋 wp-block-woocommerce-checkout 就是區塊版,看到 <form class="checkout woocommerce-checkout"> 就是傳統短代碼版。

明白資料怎麼流之後,下一篇我們用 WooCommerce 提供的 Additional Checkout Fields API,在區塊結帳頁加一個真正會存進訂單的自訂欄位。


Hi, 我是 Oberon Lai,十多年前我從一個不懂程式的平面設計師,一頭栽進 WordPress 的世界。從佈景主題到外掛開發,從接案到自研產品,這段旅程讓我深刻理解:好的技術不只是寫出能跑的程式碼,而是真正解決人的問題。

我積極投入參與社群,公開演講紀錄如下:

我專精 WordPress 開發,從企業形象網站的設計與開發、佈景主題客製化,到既有網站的改版升級,提供完整的 WordPress 建置服務。開發面涵蓋外掛開發與維護、區塊編輯器(Gutenberg)客製區塊、ACF 與 Custom Post Type 的資料架構設計,以及 REST API 整合與 Multisite 多站架構建置。同時也協助網站效能改善與 SEO 調校、安全性檢測與強化,並導入自動化部署與版本控制流程,搭配長期的技術顧問與維運支援,讓網站上線後也能穩定運作。

亦提供 WooCommerce 商店的建置與設定,並串接綠界、LINE Pay、藍新等台灣主流金流。可依需求進行結帳頁面客製化、訂單狀態自動化流程設計,以及商品管理與庫存系統的客製開發;也支援 WooCommerce Subscription 定期定額、REST API 應用開發、報表與數據匯出等進階需求。此外,透過購物流程 UX 改善、電商網站效能調校與 HPOS 高效能訂單儲存相容開發,全面提升營運效率,並提供電商營運技術顧問服務。

AI 浪潮席捲而來,我選擇擁抱而非恐懼,我把 AI 融入開發工作流以及客戶的產品中,也持續累積「AI 看不見的部分」:真實踩坑經驗、最新漏洞情報那些只有第一線工程師才看得見的細節,如果你有任何 WordPress 的客製化需求或是 AI 開發相關的問題非常歡迎加入 LINE 官方帳號與我聯繫:

https://page.line.me/vrf7844t?oat_content=url&openQrModal=true

如果想要獲取 AI 開發實戰經驗也能訂閱我的電子報,每週五上午準時出刊:

https://oberonlai.blog/wordpress-newsletter/


上一篇
WooCommerce 區塊初探:商品列表、購物車與結帳區塊
下一篇
WooCommerce 客製結帳頁面:用 Checkout Block 的擴充點加自訂欄位
系列文
從一句話到一個網站:用 Vibe Coding 開發 WordPress Block Theme 的 30 天35
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言