前言
在 WooCommerce 訂單後台管理時,常會需要額外新增自訂欄位以收集特定資訊,例如客戶的聯絡電話。這段程式碼示範如何在訂單編輯頁面保存自訂欄位資料,確保資料能正確存入訂單元資料中。適合已熟悉 WooCommerce 且想擴充後台訂單欄位功能的工程師或自學者。
為什麼需要自訂欄位儲存機制
WooCommerce 預設訂單資料結構無法涵蓋所有業務需求,因此經常會透過自訂欄位來擴充。這些欄位必須在後台訂單編輯時能夠被正確讀取與保存,否則資料會遺失。
使用 woocommerce_process_shop_order_meta 鉤子
這個 action 鉤子會在 WooCommerce 處理訂單後台編輯表單時觸發,適合用來攔截並保存自訂欄位資料。
add_action('woocommerce_process_shop_order_meta', function ($order_id) {
// 權限檢查,避免非授權使用者修改訂單
if (!current_user_can('edit_shop_order', $order_id))
return;
$key = '_shipping_phone'; // 自訂欄位名稱
// 確認表單有送出該欄位
if (!isset($_POST[$key]))
return;
// 清理輸入資料,避免 XSS 或其他注入風險
$value = wc_clean(wp_unslash($_POST[$key]));
// 取得訂單物件
$order = wc_get_order($order_id);
if (!$order)
return;
// 使用 WC_Order API 更新訂單元資料
$order->update_meta_data($key, $value);
$order->save(); // 必須呼叫 save() 才會寫入資料庫
}, 50);
關鍵說明
current_user_can用來確保只有有編輯訂單權限的使用者能執行更新。wc_clean和wp_unslash是 WordPress 與 WooCommerce 提供的安全函式,確保輸入資料安全。- 使用
update_meta_data與save是 WooCommerce 推薦的寫入方式,兼容新版 HPOS(高效訂單存儲系統)與舊版 postmeta。
實務應用與延伸
此方法可擴充至任何自訂欄位,只要對應修改 $key 與表單名稱即可。實務中,還可搭配後台欄位輸入介面(如使用 woocommerce_admin_order_data_after_billing_address 鉤子)來完整實作自訂欄位的讀寫。
常見問題與注意事項
- 忘記呼叫
$order->save()將導致資料無法寫入。 - 欄位名稱建議加底線開頭避免與 WooCommerce 原生欄位衝突。
- 權限檢查不可省略,避免安全問題。
完整程式碼
<?php
add_action('woocommerce_process_shop_order_meta', function ($order_id) {
if (!current_user_can('edit_shop_order', $order_id))
return;
$key = '_shipping_phone';
if (!isset($_POST[$key]))
return;
$value = wc_clean(wp_unslash($_POST[$key]));
$order = wc_get_order($order_id);
if (!$order)
return;
$order->update_meta_data($key, $value);
$order->save();
}, 50);