Wordpress

WooCommerce 區塊結帳外掛「消失」?先查相容性宣告三管道

結帳頁少了一個客戶天天在用的付款選項,後台設定明明還是啟用狀態,前台卻整個不見,只剩下兩三個陌生的替代方式。有時掉的不是付款方式,而是原本要顧客填統一編號或到貨備註的自訂欄位,整組欄位憑空消失,訂單資料因此少了一大截。

這個症狀通常都在同一個轉折點上出現。網站換成了 WooCommerce 區塊結帳Checkout Block)之後,才踩進這一連串新規則。這是 WooCommerce 官方力推的新一代結帳頁面,用 React 在瀏覽器端即時畫出整個購物車與結帳畫面,資料透過Store API存取,取代舊版靠[woocommerce_checkout]短碼、由伺服器組出整頁 HTML 的做法。根據 WooCommerce 官方文件,2023 年 11 月 WooCommerce 8.3 之後新建立的商店,區塊結帳已經是預設體驗;既有商店即使升級版本,也不會被強制換掉,只有在頁面編輯器裡主動把短碼換成區塊,才會踩進這個轉折點。換版面看起來只是外觀變了,實際上是整套擴充機制被重寫,這正是外掛忽然「不見」的根本原因。

問題不在於外掛壞掉、版本錯誤,也不是設定被誰誤改,而是舊時代的技術銜接方式在新架構裡失靈了。這兩套結帳系統的底層差異,決定了要怎麼判斷外掛真的還沒跟上、還是只差一步宣告,也決定了在等外掛更新的過渡期裡,能不能安全切回舊版結帳。

在 WordPress 區塊編輯器開啟結帳頁,WooCommerce 區塊結帳以前端即時渲染出付款與地址欄位和訂單摘要
區塊結帳把整個結帳頁改成前端即時渲染,付款方式與欄位能不能出現,取決於外掛有沒有完成相容整合。

區塊結帳的前端渲染機制取代了短碼時代的伺服器掛勾

短碼結帳的運作方式很老派,也正因為老派,外掛開發者才有那麼多年時間摸熟它的規則。WordPress 收到請求後,先在伺服器端用 PHP 把整頁 HTML 組好,[woocommerce_checkout]短碼負責在頁面裡插入結帳表單;外掛想加一個付款方式、多一個欄位,靠的是 WordPress 核心的 action 與 filter 機制,也就是在 PHP 執行到某個特定時間點時「掛」上自己的程式碼,讓系統多跑一段邏輯。這套掛勾系統運作了十幾年,幾乎所有 WooCommerce 外掛的付款整合、欄位擴充都是照這個邏輯寫的。

Checkout Block則是完全不同的做法。頁面不再是伺服器組好整頁 HTML 再送出去,而是瀏覽器收到一份精簡的資料後,用 React 即時畫出購物車與結帳畫面,使用者填資料、切換付款方式時,畫面透過Store API跟後端交換資料,不再整頁重新整理。這個轉變意味著,原本寫在伺服器端 PHP 裡的那些 action、filter 掛勾,很多根本不會在瀏覽器渲染的這一層被觸發到。並不是外掛的程式碼壞了,而是它原本要插入內容的那個「時間點」,在新架構裡幾乎不存在。

這也是為什麼同一支外掛,短碼結帳用得好好的,換成區塊結帳卻像被抽掉一塊。這不是網站中毒,也不是外掛版本壞掉,更不是哪個設定被誰誤改,而是兩個完全不同世代的技術在做同一件事,銜接方式從根本上就不一樣。搞懂這一層,後面遇到任何東西不見了的狀況,才不會急著去重灌外掛或搬回舊版主機。

短碼結帳靠伺服器端 PHP 掛勾組出整頁,區塊結帳改由前端 React 渲染與 JS 註冊,外掛銜接方式整個改變
付款方式或欄位不見,不是外掛壞掉,而是舊的 PHP 掛勾時間點在前端渲染的區塊結帳裡不再被觸發。

付款方式消失與自訂欄位消失來自兩種不同的失效機制

同樣都是東西不見了,實際卻是兩條完全不同的故障路徑,混在一起查只會愈查愈亂。第一種是付款方式消失,後台的金流設定頁面裡,那個付款方式明明還顯示為啟用中,切到結帳頁卻完全找不到它,客戶只看得到另外幾個選項。這種狀況通常代表金流外掛只完成了「後端」的註冊,也就是用 PHP 把自己登記成一個可用的付款閘道,卻沒有補上「前端」的 JS 註冊,讓Checkout Block知道要把它畫進畫面裡。

第二種是自訂欄位消失:外掛原本在結帳頁多加的欄位,例如統一編號欄位、到貨備註欄位,整組不見了,即使短碼版本本來看得到,換成區塊之後就像沒發生過一樣。這種狀況多半是外掛還停留在只有短碼結帳才會觸發的舊版掛勾,例如過去常見的woocommerce_after_order_noteswoocommerce_checkout_fields這類函式,在區塊結帳的渲染流程裡完全不會被呼叫到,欄位自然畫不出來。

分清楚自己遇到的是哪一種,後面的排查方向才不會走錯:付款方式不見,要往金流外掛的前後端整合狀態去查;自訂欄位不見,則要往外掛有沒有改用官方新的欄位註冊方式去查。

外掛的相容性宣告,分成相容、不相容與未宣告三種

要判斷一支外掛跟不跟區塊結帳合得來,官方其實留了一個明確的機制,不必自己憑感覺猜。外掛開發者只要在主檔案裡,透過before_woocommerce_init這個動作掛勾呼叫FeaturesUtil::declare_compatibility(),就能明白宣告自己相不相容區塊結帳這項功能:

add_action( 'before_woocommerce_init', function() {
    if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, true );
    }
} );Code language: PHP (php)

把最後一個參數從true改成false,就是宣告不相容,做法一樣簡單,差別只在於開發者對這件事給出的是哪個答案。不過官方只會對有標明WC tested up to版本的外掛做這項相容性檢查,沒寫這個標頭的外掛,多半跟 WooCommerce 結帳本來就沒什麼關係,也就不會被列入檢查範圍。這也是為什麼有些外掛看起來完全沒動靜,卻也沒被標成不相容,因為它根本不在被檢查的名單裡。

三種狀態各自代表不同的意思,不能混為一談。宣告相容,代表開發者已經測過、確認能在區塊結帳正常運作;宣告不相容,代表開發者已經確認架構上做不到,短期內不會有解法;完全沒有宣告,則是最模糊的一種,可能外掛實際上已經能正常運作,只是開發者沒補上這段宣告的程式碼,也可能真的還沒有人測試過。

外掛相容性宣告分成宣告相容、宣告不相容、完全未宣告三種狀態,各自對應不同的處理方式
三種宣告狀態意思不同:相容可切換、不相容改找替代方案、未宣告要主動聯絡開發者確認。

相容性宣告的三個查詢管道

不用讀外掛原始碼,也有三個管道能直接查到這個宣告的實際狀態。第一個管道在區塊編輯器裡,選取Checkout區塊本身、或其中的Payment Options內嵌區塊,如果偵測到有已宣告不相容的外掛,設定側邊欄會直接跳出警示文字,還附一個能一鍵切換回傳統結帳的按鈕。

第二個管道在後台外掛列表頁,網址加上?plugin_status=incompatible_with_feature&feature_id=all這串參數,就能篩選出所有跟目前啟用功能不相容的外掛,WooCommerce 核心也會直接在外掛名稱下方標示相容性警語,不用一個個點開設定去確認。這背後對應的是 WooCommerce 官方 GitHub 原始碼庫裡的FeaturesController機制,把外掛分成compatibleincompatibleuncertain三組,get_compatible_features_for_plugin()這個函式回傳的陣列結構就是照這三組分類。

第三個管道則是市集本身,如果外掛是在 WooCommerce.com 上購買的,該外掛的商品頁面就會直接標出Compatibility欄位,寫明有沒有支援Cart and Checkout Blocks,買之前就能先確認,不必等裝上去才發現不合用。

外掛宣告相容不代表金流一定會出現在結帳頁

查到外掛整體宣告了cart_checkout_blocks相容,不代表這支外掛底下的金流閘道一定會出現在付款選項裡,這是最容易被誤解的一點。官方文件講得很直白,如果外掛本身是金流外掛,外掛整體的相容性宣告,跟金流閘道本身的相容性,是分開判定的兩件事。宣告相容仍然是必要的第一步,但在金流閘道真的完成與Cart and Checkout Blocks的整合之前,不相容的提示還是會持續出現。

官方判定一個金流閘道相不相容的方式,說穿了就是比對兩份清單:一份是伺服器端註冊的閘道清單,一份是前端(也就是Checkout Block實際會讀取)註冊的閘道清單。只要某個閘道出現在伺服器端清單,卻沒有出現在前端清單,系統就會判定它還沒完成與區塊結帳的整合,不管外掛整體的相容性標籤寫的是什麼。

換句話說,前面查到的外掛相容性宣告只是第一關過了,金流外掛還得另外做「付款方式整合」的工程,才會真正被判定為可用。如果照著相容性宣告去查,某個外掛明明顯示相容,結帳頁卻還是看不到它旗下的某個付款方式,原因通常就出在這裡,不是查錯了地方,而是這兩層判定本來就是分開的。

自訂欄位改用官方的欄位註冊介面才能被區塊結帳讀到

自訂欄位要能在區塊結帳正常顯示,唯一支援的做法是改用官方提供的woocommerce_register_additional_checkout_field()函式,這個函式取代了短碼時代五花八門的各種掛勾寫法。註冊的時機也有講究,官方文件明白寫著,欄位要在woocommerce_init這個動作或更晚才註冊,太早註冊反而會遇到初始化與翻譯字串沒準備好的問題。

欄位可以放的位置分成三種,各自的資料會存到不同地方,這點在規劃欄位時要先想清楚。放進「聯絡資訊」(contact)的欄位,資料會存進顧客帳號,之後在帳號詳情頁還能看得到、也能編輯;放進「地址」(address)的欄位,資料會同時存進顧客資料與訂單,而且會同時出現在收件地址與帳單地址,沒辦法只讓它出現在其中一邊;放進「訂單資訊」(order)的欄位,資料只會存進這一張訂單,不會存進顧客帳號,也不會預先帶入下一次的訂單。目前支援的欄位型別則有三種:text(文字)、select(下拉選單)、checkbox(核取方塊)。

如果某個欄位只有在特定情況下才該出現或才該必填,例如客戶選了自取才需要填聯絡電話,官方支援用 JSON Schema 寫條件式邏輯,透過requiredhidden這兩個屬性各自帶一段判斷式來達成。這段邏輯不只在瀏覽器端即時運算、決定要不要顯示欄位,送出訂單時後端也會照同一套規則再驗證一次,避免有人繞過前端限制硬送資料。

如果這個欄位是從短碼結帳的舊版自訂欄位搬過來的,官方也準備了銜接舊資料的做法,不必讓老客戶被迫重填一次早就留過的資料。woocommerce_set_additional_field_value這個動作,可以在新欄位被儲存的同時,同步把值寫回舊版外掛原本使用的 meta key;woocommerce_get_default_value_for_{key}這個過濾器,則能讓新欄位讀取舊的 meta 值當成預設值。兩個掛勾搭配起來,新舊兩套系統可以並存過渡,不必一次全部砍掉重練。

切回傳統短碼結帳,官方視為合理的過渡做法

等外掛更新期間,不想讓結帳頁一直缺東缺西,官方教學裡本來就準備了退回傳統結帳的正式做法,這不是什麼偏方,而是官方認可的過渡選項。第一種做法在區塊編輯器裡完成:進入外觀的編輯器、找到購物車或結帳頁面,開啟清單檢視選取CartCheckout區塊,點工具列最左邊的「轉換」按鈕,選擇「傳統短碼」,該區塊就會變成一個短碼佔位區塊,存檔即完成。

第二種做法更直接,也適用於沒有用區塊主題的網站:找到並編輯購物車或結帳頁,在清單檢視裡選取並刪除CartCheckout區塊,在原本的位置新增一個 Shortcode 區塊,手動輸入[woocommerce_cart][woocommerce_checkout],存檔即可。這種做法等於直接把區塊換回舊版短碼,效果跟第一種方法相同,只是操作路徑不一樣。

有一點要特別留意,購物車與結帳這兩個區塊是搭配運作的一組,官方也提醒,如果決定把其中一個退回傳統版,通常另一個也要跟著換,只切一邊容易讓兩個頁面的介面銜接不一致,客戶從購物車跳到結帳時體驗會怪怪的。如果問題只出在單一個付款方式不相容,其實不必整頁重建,直接在Payment Options內嵌區塊的設定側邊欄按下一鍵切換回傳統結帳的按鈕就夠了,範圍更小、影響也更可控。

用區塊的轉換按鈕或改用 Shortcode 區塊,兩種官方做法都能把區塊結帳切回傳統短碼結帳過渡
過渡期可用「轉換」按鈕,或改放 Shortcode 區塊切回傳統短碼結帳,兩種都是官方認可的做法。

宣告不相容與完全未宣告需要兩種不同的因應方式

查到的結果是「宣告不相容」,代表開發者已經確認過,這支外掛在架構上做不到跟區塊結帳搭配運作,通常不會是短期內就會修好的問題。遇到這種情況,與其一直等更新,更務實的做法是考慮換一個已經宣告相容的替代方案,或是先長期留在短碼結帳,等外掛真的重新宣告相容再回頭切換,不必反覆嘗試。

查到的結果是完全「未宣告」,狀況反而更需要主動確認,而不是被動等待。未宣告可能代表這支外掛實際上已經能正常運作,只是開發者還沒補上宣告相容性的那段程式碼;也可能代表它真的還沒被測試過,換上區塊結帳會有各種預期外的狀況。官方在文件裡建議的做法是主動聯絡外掛開發者,讓對方知道有使用者想要用新版的區塊結帳,同時附上官方公開的「宣告相容性」文件連結,引導開發者去補上這段宣告,這樣才不必自己反覆猜測,也能讓開發者更快知道市場上確實有這個需求。

所有關鍵外掛都宣告相容才是正式切換的時機

官方的立場其實很清楚,只有在 2023 年 11 月 WooCommerce 8.3 之後才新建立的商店,區塊結帳才是預設體驗;在那之前就已經存在的商店,就算後來把 WooCommerce 核心升級到 8.3 以後的版本,購物車與結帳頁也不會被自動換掉,仍然維持原本在用的版本,除非有人主動到頁面編輯器裡把短碼換成區塊,或反過來操作。換句話說,舊商店不會被強迫升級,決定權一直握在自己手上。

判斷現在算不算正式切換的時機,具體做法是把金流外掛,以及任何會動到結帳欄位或結帳流程的外掛都列出來,用前面提到的三個查詢管道逐一確認相容性宣告。全部都宣告相容,才是正式把商店切到區塊結帳的時機;只要其中有一個宣告不相容、或未宣告卻是網站少不了的功能,就先維持短碼結帳,或用一鍵按鈕切回去,等外掛更新、重新宣告之後再盤點一次。這個盤點不是一次性的,外掛版本會更新,相容性狀態也會跟著變動,定期回頭確認,才不會在某次外掛升級後又冷不防掉了一塊。

換版面從來不是把舊外掛原封不動搬過去就好,WooCommerce 區塊結帳背後的整套擴充邏輯,從伺服器端的 PHP 掛勾換成了前端的 JS 註冊,對每一支外掛來說都是要重新做的工程,不是版本升級能自動解決的事。搞懂相容性宣告在查什麼、金流整合跟外掛整體宣告是兩層判定、自訂欄位要靠新的註冊介面才讀得到,遇到結帳頁忽然缺東西,就不會慌著以為網站壞了,而是照著這幾條線索,一步步找出問題真正出在哪個環節。

常見問答

本區問答由 AI 依文章內容自動整理,僅供快速參考,正式內容仍以全文為準。

為什麼換成區塊結帳後外掛功能會消失?

短碼結帳由伺服器端 PHP 組出整頁,外掛靠 action、filter 掛勾加功能;區塊結帳改成瀏覽器端用 React 即時渲染,原本寫在伺服器端的掛勾很多根本不會被觸發到,功能因此像被抽掉一塊,並不是外掛真的壞掉了。

付款方式在後台啟用,前台卻看不到為什麼?

這通常代表金流外掛只完成後端註冊,用 PHP 把自己登記成可用的付款閘道,卻沒有補上讓區塊結帳知道要畫進畫面的前端 JS 註冊,所以後台顯示啟用中,結帳頁卻看不到這個付款選項。

怎麼查一支外掛跟區塊結帳相不相容?

可以從三個管道查:在區塊編輯器選取相關區塊看有沒有跳出不相容警示;到後台外掛列表頁用篩選參數看相容性標示;如果是在 WooCommerce.com 購買的外掛,商品頁也會直接標出相容欄位。

外掛宣告相容,付款方式就一定會出現嗎?

不一定,外掛整體宣告相容跟金流閘道本身相不相容是分開判定的兩件事;官方會比對伺服器端註冊的閘道清單和前端實際讀取的閘道清單,只要某個閘道沒出現在前端清單,這個付款方式就不會顯示出來。

想暫時切回傳統結帳頁面,該怎麼做?

官方提供兩種做法:一種是在區塊編輯器裡選取 Cart 或 Checkout 區塊,點工具列的轉換按鈕改成傳統短碼;另一種是直接刪除區塊,改用 Shortcode 區塊手動輸入舊版短碼,兩種效果相同。

資料來源
  1. Getting started with Cart and Checkout extensibility — WooCommerce
  2. FAQ: Cart and Checkout Blocks by Default — WooCommerce
  3. Cart and Checkout Blocks: Becoming the Default Experience — WooCommerce
  4. Additional checkout fields — WooCommerce
  5. Customizing the Cart and Checkout Pages — WooCommerce