Woocommerce:如何在结账下单或订单支付页触发自定义函数?
问题分析与解决方案
核心问题
你的代码存在三个关键问题,导致手动创建的订单在支付页点击「支付订单」按钮时无法触发元数据更新:
- 钩子参数不匹配:
woocommerce_receipt_order_pay传递的是订单ID,而非WC_Order对象,直接调用$order->get_payment_method()会报错中断执行 - 钩子时机错误:
woocommerce_receipt_order_pay仅在加载支付收据页面时触发,并非用户点击「支付订单」按钮的动作触发点 - 原钩子参数声明丢失:修改时移除了
woocommerce_checkout_create_order的参数数量声明(原10, 2),可能引发兼容性问题
修正后的代码
// 结账创建订单时添加元数据 add_action( 'woocommerce_checkout_create_order', 'add_custom_order_meta', 10, 2 ); // 订单支付方式变更时更新元数据(覆盖order_pay页面提交支付场景) add_action( 'woocommerce_payment_method_changed', 'update_custom_order_meta_on_payment_change', 10, 2 ); // 后台手动修改订单后更新元数据 add_action( 'woocommerce_admin_order_save_after', 'update_custom_order_meta_on_payment_change' ); /** * 结账创建订单时的元数据处理 */ function add_custom_order_meta( $order, $data ) { process_converted_total_meta( $order ); } /** * 支付方式变更/后台保存订单时的元数据处理 */ function update_custom_order_meta_on_payment_change( $order_id ) { $order = wc_get_order( $order_id ); if ( ! $order ) return; process_converted_total_meta( $order ); // 强制保存订单,确保元数据写入数据库 $order->save(); } /** * 统一处理转换总额元数据的核心逻辑 */ function process_converted_total_meta( $order ) { $payment_method = $order->get_payment_method(); // 仅针对指定支付方式处理 if ( ! in_array( $payment_method, array( 'bacs', 'cheque' ) ) ) return; $order_total = $order->get_total(); $currency_to = ( $payment_method === 'bacs' ) ? 'hkd' : 'thb'; // 调用转换函数 $converted_total_gptlove = get_conversion( 'number=' . $order_total . '&from=usd&to=' . $currency_to . '&dp=2' ); $currency_symbol = ( $payment_method === 'bacs' ) ? '$' : '฿'; $currency_code = ( $payment_method === 'bacs' ) ? 'HKD' : 'THB'; // 更新元数据 $order->update_meta_data( 'converted_total_gptlove', $currency_symbol . $converted_total_gptlove . ' ' . $currency_code ); } // 订单详情中显示转换总额 add_filter( 'woocommerce_get_order_item_totals', 'add_custom_order_item_totals', 10, 3 ); function add_custom_order_item_totals( $total_rows, $order, $tax_display ) { // 用WC_Order内置方法读取元数据,符合官方最佳实践 $converted_total_gptlove = $order->get_meta( 'converted_total_gptlove' ); if ( ! empty( $converted_total_gptlove ) ) { $total_rows['converted_total_gptlove'] = array( 'label' => __( '转换后总额:', 'woocommerce' ), 'value' => $converted_total_gptlove, ); } return $total_rows; }
关键修正点说明
- 逻辑拆分:把转换总额的核心逻辑抽成独立函数,避免重复代码,便于后续维护
- 钩子精准选择:
woocommerce_payment_method_changed:在订单支付方式变更时触发,完美覆盖order_pay页面提交支付的场景woocommerce_admin_order_save_after:处理后台手动修改订单支付方式的情况
- 参数兼容处理:针对不同钩子传递的订单ID/对象,统一转换为
WC_Order对象进行处理 - 元数据操作优化:用
$order->get_meta()替代get_post_meta(),符合WooCommerce官方开发规范 - 强制保存订单:在支付方式变更时调用
$order->save(),确保元数据成功写入数据库
内容的提问来源于stack exchange,提问作者Karl
相关产品推荐
相关产品推荐

