You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce结账时按支付方式设置商品价格问题排查

问题描述

在WooCommerce结账页面,选择支付方式invoice时,需要将商品ID为338991、353754的价格设为0。现有代码能修改商品价格并计算小计,但税费与总计计算错误,WooCommerce未识别到价格变动。

原代码如下:

function update_product_prices_and_totals($cart_object) {
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }

    if (is_checkout() && isset($_POST['payment_method']) && $_POST['payment_method'] === 'invoice') {
        // Set subtotal, tax, and total to 0
        $subtotal = 0;
        $total = 0;
        $included_products = array(338991, 353754); // Array of product IDs to include

        // Loop through the products in the cart
        foreach ($cart_object->get_cart() as $cart_item_key => $cart_item) {
            $product_id = $cart_item['product_id'];

            // Check the product IDs
            if (in_array($product_id, $included_products)) {
                // Set the price to 0
                $cart_item['data']->set_price(0);

                // Calculate taxes for this product and subtract from the subtotal
                $taxes = array_sum($cart_item['line_tax_data']['subtotal']);
                $subtotal -= $taxes;

                continue; // Skip the iteration for included products
            }

            // Update the subtotal
            $subtotal += $cart_item['line_subtotal'];
        }

        // Update the total
        $total = $subtotal + $cart_object->get_cart_contents_tax();

        // Set the updated subtotal and total
        $cart_object->subtotal = $subtotal;
        $cart_object->total = $total;
    }
}
add_action('woocommerce_cart_calculate_fees', 'update_product_prices_and_totals', 10, 1);
代码问题分析
  1. 钩子选择错误:woocommerce_cart_calculate_fees用于添加/调整购物车费用,不是修改商品价格和重新计算购物车核心数据的合适钩子,直接修改$cart_object的subtotal和total不会触发WooCommerce的税费重算逻辑。
  2. 支付方式获取不可靠:结账页面切换支付方式是AJAX请求,$_POST['payment_method']无法稳定获取当前选中的支付方式,应该通过WooCommerce会话存储来读取。
  3. 未更新购物车项核心数据:修改商品价格后,没有同步更新购物车项的line_subtotal、line_total以及对应的税费数据,这些是WooCommerce计算总计和税费的基础,直接跳过会导致数据不一致。
修正后的代码
// 存储选中的支付方式到会话
function save_selected_payment_method_to_session() {
    if (is_checkout() && isset($_POST['payment_method'])) {
        WC()->session->set('selected_payment_method', sanitize_text_field($_POST['payment_method']));
    }
}
add_action('wp_ajax_update_order_review', 'save_selected_payment_method_to_session');
add_action('wp_ajax_nopriv_update_order_review', 'save_selected_payment_method_to_session');

// 修改指定商品价格并重新计算购物车
function adjust_product_prices_based_on_payment_method($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    if (empty($cart->get_cart())) return;

    // 从会话获取当前选中的支付方式
    $selected_payment_method = WC()->session->get('selected_payment_method');
    if ($selected_payment_method !== 'invoice') return;

    $target_product_ids = array(338991, 353754);

    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $product_id = $cart_item['product_id'];
        if (!in_array($product_id, $target_product_ids)) continue;

        // 设置商品价格为0
        $cart_item['data']->set_price(0);

        // 强制更新购物车项的小计、总计及税费
        $cart_item['line_subtotal'] = 0;
        $cart_item['line_total'] = 0;
        $cart_item['line_subtotal_tax'] = 0;
        $cart_item['line_tax'] = 0;
        $cart_item['line_tax_data'] = array('subtotal' => array(), 'total' => array());
    }

    // 触发购物车重新计算(包括税费)
    $cart->calculate_totals();
}
add_action('woocommerce_before_calculate_totals', 'adjust_product_prices_based_on_payment_method', 20);
修正说明
  1. 会话存储支付方式:通过wp_ajax_update_order_review钩子捕获支付方式切换的AJAX请求,将选中的支付方式存入WooCommerce会话,确保在购物车计算时能稳定获取。
  2. 使用正确钩子:woocommerce_before_calculate_totals是WooCommerce计算购物车总计前的核心钩子,在这里修改商品价格会自动触发后续的税费和总计重算。
  3. 同步更新购物车项数据:不仅设置商品价格为0,还手动重置购物车项的小计、总计及税费数据,确保WooCommerce计算时使用正确的数值。
  4. 强制重算总计:最后调用$cart->calculate_totals(),确保所有数据重新计算,包括税费和最终总计。

内容的提问来源于stack exchange,提问作者Aykut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:37:36