如何在WooCommerce后台订单编辑页显示交易手续费明细
WooCommerce后台订单添加交易手续费明细解决方案
需求说明
希望在WooCommerce后台订单详情的总额区域,展示交易手续费明细,预期格式如下:
- 商品小计:£375.00
- 运费:£0.00
- VAT:£75.00
- 订单总额:£450.00
- 已支付:£450.00
- 交易手续费:£7.00
- 扣除手续费后总额:£443.00
目标位置如图所示(当前显示异常),已在主题functions.php中编写以下代码,但未实现预期效果:
// Calculate and save transaction fee after order is created/paid add_action('woocommerce_order_status_changed', 'add_transaction_fee_to_order_meta', 10, 3); function add_transaction_fee_to_order_meta($order_id, $old_status, $new_status) { if ($new_status == 'processing' || $new_status == 'completed') { $order = wc_get_order($order_id); if (get_post_meta($order_id, '_transaction_fee', true) == '') { $order_total = $order->get_total(); $transaction_fee = ($order_total * 0.015) + 0.25; update_post_meta($order_id, '_transaction_fee', $transaction_fee); } } } // Display transaction fee in admin order details *after* "Paid" line add_action('woocommerce_admin_order_totals_after_total', 'display_transaction_fee_in_admin_order_details', 10, 2); function display_transaction_fee_in_admin_order_details($order_id, $order) { $transaction_fee = get_post_meta($order_id, '_transaction_fee', true); if ($transaction_fee) { if (is_object($order) && is_a($order, 'WC_Order')) { ?> <tr> <td class="label">Transaction Fee:</td> <td width="1%"></td> <td class="total"> <?php echo wc_price($transaction_fee); ?> </td> </tr> <tr> <td class="label">Total (after fee):</td> <td width="1%"></td> <td class="total"> <?php echo wc_price($order->get_total() - $transaction_fee); ?> </td> </tr> <?php } else { error_log("WC_Order object not available in display_transaction_fee_in_admin_order_details for order ID: " . $order_id); } } }
问题分析
原代码核心问题有两个:
- 钩子参数错误:
woocommerce_admin_order_totals_after_total钩子仅传递$order对象作为参数,原代码却接收$order_id, $order,导致变量错位,无法正确获取订单数据。 - 钩子位置不符:原钩子是在「订单总额」之后显示,但需求是在「已支付」行之后,位置不符合预期。
修复后的代码
将以下代码替换原代码,添加到主题或子主题的functions.php文件中:
// 计算并保存交易手续费(订单支付完成后) add_action('woocommerce_order_status_changed', 'add_transaction_fee_to_order_meta', 10, 3); function add_transaction_fee_to_order_meta($order_id, $old_status, $new_status) { // 仅当订单状态变为处理中或已完成时执行 if (!in_array($new_status, ['processing', 'completed'])) { return; } $order = wc_get_order($order_id); if (!$order) return; // 避免重复计算手续费 if (get_post_meta($order_id, '_transaction_fee', true)) { return; } // 使用实际支付金额计算,更准确 $paid_amount = $order->get_total_paid(); $transaction_fee = ($paid_amount * 0.015) + 0.25; // 保存手续费到订单元数据 update_post_meta($order_id, '_transaction_fee', $transaction_fee); } // 在后台订单详情的「已支付」行之后显示手续费明细 add_action('woocommerce_admin_order_totals_after_payment', 'display_transaction_fee_in_admin_order_details'); function display_transaction_fee_in_admin_order_details($order) { $transaction_fee = get_post_meta($order->get_id(), '_transaction_fee', true); if (!$transaction_fee) return; // 计算扣除手续费后的净额 $net_total = $order->get_total_paid() - $transaction_fee; ?> <tr> <td class="label">交易手续费:</td> <td width="1%"></td> <td class="total"> <?php echo wc_price($transaction_fee, ['currency' => $order->get_currency()]); ?> </td> </tr> <tr> <td class="label">扣除手续费后总额:</td> <td width="1%"></td> <td class="total"> <?php echo wc_price($net_total, ['currency' => $order->get_currency()]); ?> </td> </tr> <?php }
优化说明
- 参数修正:修复钩子参数接收逻辑,确保正确获取订单对象。
- 位置调整:改用
woocommerce_admin_order_totals_after_payment钩子,让手续费明细显示在「已支付」行之后,完全匹配需求格式。 - 金额准确性:用
get_total_paid()替代get_total(),避免订单存在退款、优惠券等情况时计算偏差。 - 稳定性提升:增加订单对象校验、重复计算拦截,减少错误日志产生。
- 币种适配:调用
wc_price()时指定订单币种,确保金额显示对应币种符号。
内容的提问来源于stack exchange,提问作者A.Copland
相关产品推荐
相关产品推荐

