Skip to content

[Bug] HPOS 下 PayNow 付款的 transaction_id 與 RY 物流 shipping_address_1 寫入靜默失敗 #112

@lukehsuhao

Description

@lukehsuhao

摘要

承接 #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_phoneelse 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 修完之後)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions