摘要
承接 #110 修完 LINE Pay confirm 階段的 HPOS bug 後,掃了一遍整個 woomp 找其他類似的「對 WooCommerce 核心欄位用 WC_Order::update_meta_data() 寫入」的地方,總共找到 2 處真正會在 HPOS 下出錯的位置,其他被 version_compare(WC_VERSION, '5.6.0', '<') 守護的 dead-code branch 不在本 issue 範圍。
問題模式跟 #110 同類型:核心欄位(如 _transaction_id、_shipping_address_1)在 HPOS 下是 wc_orders / wc_order_addresses 的欄位,不是 meta。update_meta_data() 寫入會在 save() 階段被 internal_meta_keys 過濾掉、靜默丟棄(不會 throw、log 也不會記),必須改用對應 setter。
影響
1. PayNow 付款:訂單沒有 transaction_id
位置:includes/paynow-payment/includes/gateways/class-paynow-payment-response.php:206
$order->update_meta_data( '_paynow_tran_id', $buysafe_no );
$order->update_meta_data( '_paynow_tran_status', $tran_status );
$order->update_meta_data( '_transaction_id', $buysafe_no ); // ← HPOS 下被丟掉
PayNow 付款 IPN 回來時把收款編號寫入 _transaction_id,但 HPOS 下這行 silent-fail。
結果:
- 訂單看起來付款完成、但
wc_orders.transaction_id 為空
$order->get_transaction_id() 拿不到值
- 後續退款 / 對帳 / 任何用 transaction_id 查詢的流程都會壞
- 客戶從訂單頁面看「交易編號」也是空的
#110 的 LINE Pay 是讀取端誤判,這個是寫入端 silent drop,受害方式略有不同但同樣是 HPOS 遷移漏網。
2. RY 物流 CVS 取貨點地址寫不進 shipping address
位置:includes/ry-woocommerce-tools/woocommerce/shipping/ry-base.php:181
// HPOS 相容:使用物件方法操作 meta ← 註解寫了 HPOS 相容
$shipping_address = $order->get_address( 'shipping' );
$order->update_meta_data( '_shipping_address_1', ... ); // ← 但這行不相容
$order->update_meta_data( '_shipping_address_index', ... );
$order->save();
註解說「HPOS 相容」,但 _shipping_address_1 還是用 update_meta_data 寫,HPOS 下被丟掉。客人選好超商取貨點後,取貨點地址不會回寫進訂單的 shipping address,只剩 _shipping_cvs_store_* 那幾個 custom meta。
不在本 issue 範圍
掃描還命中 5 處對核心欄位的 update_meta_data,但全都被 version_compare(WC_VERSION, '5.6.0', '<') 守護。woomp 3.5.0 已把 WC 最低版本拉到 7.1+,這些 branch 是 dead code、不會被執行:
paynow-shipping/.../class-paynow-shipping.php:498 — _shipping_phone
ry-base.php:166 — _shipping_phone
ecpay-shipping.php:376 — _shipping_phone
smilepay-shipping.php:196 — _shipping_phone
newebpay-gateway-response.php:139 — _shipping_phone(else branch)
這些建議後續另外清掉以減少誤導讀者,但不是 bug。
修法
對應 PR:見下面連結。最小變動:
-$order->update_meta_data( '_transaction_id', $buysafe_no );
+$order->set_transaction_id( $buysafe_no );
-$order->update_meta_data( '_shipping_address_1', ... );
+$order->set_shipping_address_1( ... );
掃描方法(給 maintainer 後續用)
# 對核心欄位的 get_meta(讀取)
grep -rn -E "get_meta\s*\(\s*['\"]_(order_total|order_currency|order_key|payment_method|payment_method_title|transaction_id|customer_user|order_tax|order_shipping)['\"]|get_meta\s*\(\s*['\"]_(billing|shipping)_(first_name|last_name|email|phone|company|address_1|address_2|city|state|postcode|country)['\"]" --include='*.php' .
# 對核心欄位的 update_meta_data(寫入)
grep -rn -E "update_meta_data\s*\(.*['\"]_(order_total|order_currency|order_key|payment_method|payment_method_title|transaction_id|customer_user|order_tax|order_shipping)['\"]|update_meta_data\s*\(.*['\"]_(billing|shipping)_(first_name|last_name|email|phone|company|address_1|address_2|city|state|postcode|country)['\"]" --include='*.php' .
排除 dead-code branch 後,HEAD 上 master 真正會跑到的就是上述 2 處(在 #110 修完之後)。
摘要
承接 #110 修完 LINE Pay confirm 階段的 HPOS bug 後,掃了一遍整個 woomp 找其他類似的「對 WooCommerce 核心欄位用
WC_Order::update_meta_data()寫入」的地方,總共找到 2 處真正會在 HPOS 下出錯的位置,其他被version_compare(WC_VERSION, '5.6.0', '<')守護的 dead-code branch 不在本 issue 範圍。問題模式跟 #110 同類型:核心欄位(如
_transaction_id、_shipping_address_1)在 HPOS 下是wc_orders/wc_order_addresses的欄位,不是 meta。update_meta_data()寫入會在save()階段被internal_meta_keys過濾掉、靜默丟棄(不會 throw、log 也不會記),必須改用對應 setter。影響
1. PayNow 付款:訂單沒有 transaction_id
位置:
includes/paynow-payment/includes/gateways/class-paynow-payment-response.php:206PayNow 付款 IPN 回來時把收款編號寫入
_transaction_id,但 HPOS 下這行 silent-fail。結果:
wc_orders.transaction_id為空$order->get_transaction_id()拿不到值#110 的 LINE Pay 是讀取端誤判,這個是寫入端 silent drop,受害方式略有不同但同樣是 HPOS 遷移漏網。
2. RY 物流 CVS 取貨點地址寫不進 shipping address
位置:
includes/ry-woocommerce-tools/woocommerce/shipping/ry-base.php:181註解說「HPOS 相容」,但
_shipping_address_1還是用update_meta_data寫,HPOS 下被丟掉。客人選好超商取貨點後,取貨點地址不會回寫進訂單的 shipping address,只剩_shipping_cvs_store_*那幾個 custom meta。不在本 issue 範圍
掃描還命中 5 處對核心欄位的
update_meta_data,但全都被version_compare(WC_VERSION, '5.6.0', '<')守護。woomp 3.5.0 已把 WC 最低版本拉到 7.1+,這些 branch 是 dead code、不會被執行:paynow-shipping/.../class-paynow-shipping.php:498—_shipping_phonery-base.php:166—_shipping_phoneecpay-shipping.php:376—_shipping_phonesmilepay-shipping.php:196—_shipping_phonenewebpay-gateway-response.php:139—_shipping_phone(elsebranch)這些建議後續另外清掉以減少誤導讀者,但不是 bug。
修法
對應 PR:見下面連結。最小變動:
掃描方法(給 maintainer 後續用)
排除 dead-code branch 後,HEAD 上
master真正會跑到的就是上述 2 處(在 #110 修完之後)。