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

WooCommerce中基于单选按钮的商品阶梯折扣总计错误问题

WooCommerce阶梯折扣结账总计错误修复方案

问题根源

你的代码存在几个关键问题导致结账总计计算错误:

  • AJAX改价范围错误:遍历整个购物车修改所有商品价格,而非仅针对含"Hydrogel"的目标商品
  • 价格修改方式不可靠:直接调用set_price()修改商品对象价格,WooCommerce结账时重新计算总计会覆盖这个临时修改
  • HTML语法错误:单选按钮的data-price属性缺少闭合引号,可能导致JS读取价格失败
  • AJAX未传递商品标识:无法精准定位需要修改价格的购物车项

修复后的完整代码

function display_quantity_discount_message() {
    global $product;

    // 仅针对名称含"Hydrogel"的商品
    if (strpos($product->get_name(), 'Hydrogel') !== false) {
        $discounts = array(
            2 => 60, // 2件总价60 Lei
            3 => 85, // 3件总价85 Lei
        );

        echo '<div class="quantity-discount-message">';
        echo '<p>Reducere:</p>';
        echo '<ul>';

        foreach ($discounts as $quantity => $total_price) {
            $original_total = $quantity * $product->get_price();
            // 修复HTML引号闭合问题
            echo '<li>';
            echo '<input type="radio" name="quantity_discount" value="' . esc_attr($quantity) . '" data-total="' . esc_attr($total_price) . '"> ';
            echo 'Cumpără <span style="color:green; font-weight:bold;">' . $quantity . '</span> pentru doar <span style="text-decoration: line-through; color:red; font-weight:bold;">' . $original_total . '</span> <span style="color:red; font-weight:bold;">' . $total_price . ' Lei</span>';
            echo '</li>';
        }

        echo '</ul>';
        echo '</div>';

        wc_enqueue_js('
            jQuery(document).ready(function($) {
                $("input[name=\'quantity_discount\']").change(function() {
                    var selectedQty = parseInt($(this).val());
                    var selectedTotal = parseInt($(this).data("total"));
                    $("input[name=\'quantity\']").val(selectedQty);
                    $(" .single_add_to_cart_button").html("Adaugă în coș - " + selectedTotal + " Lei");

                    // 传递商品ID到AJAX,确保只修改目标商品
                    $.post(wc_cart_params.ajax_url, {
                        action: "update_hydrogel_discount",
                        product_id: ' . $product->get_id() . ',
                        total_price: selectedTotal,
                        quantity: selectedQty
                    }, function(response) {
                        $("body").trigger("update_checkout");
                    });
                });
            });
        ');
    }
}
add_action('woocommerce_before_add_to_cart_button', 'display_quantity_discount_message');

// AJAX处理函数:存储折扣元数据到购物车项
add_action('wp_ajax_update_hydrogel_discount', 'update_hydrogel_discount');
add_action('wp_ajax_nopriv_update_hydrogel_discount', 'update_hydrogel_discount');

function update_hydrogel_discount() {
    if (isset($_POST['product_id'], $_POST['total_price'], $_POST['quantity']) && !empty(WC()->cart)) {
        $product_id = intval($_POST['product_id']);
        $total_price = floatval($_POST['total_price']);
        $quantity = intval($_POST['quantity']);

        // 遍历购物车,找到目标商品并更新
        foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
            if ($cart_item['product_id'] == $product_id) {
                // 存储折扣总价和数量元数据
                $cart_item['data']->add_meta_data('_hydrogel_discount_total', $total_price, true);
                // 更新购物车项数量
                WC()->cart->set_quantity($cart_item_key, $quantity);
                break;
            }
        }

        WC()->cart->calculate_totals();
        echo json_encode(['success' => true]);
    }
    wp_die();
}

// 动态调整价格钩子:确保结账时正确计算总计
add_action('woocommerce_before_calculate_totals', 'apply_hydrogel_discount_to_cart');

function apply_hydrogel_discount_to_cart($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    if (did_action('woocommerce_before_calculate_totals') >= 2) return;

    foreach ($cart->get_cart() as $cart_item) {
        // 检查商品名称和折扣元数据
        if (strpos($cart_item['data']->get_name(), 'Hydrogel') !== false && $cart_item['data']->get_meta('_hydrogel_discount_total')) {
            $discount_total = floatval($cart_item['data']->get_meta('_hydrogel_discount_total'));
            // 计算单件折扣价(适配WooCommerce按单件计算总计的逻辑)
            $unit_price = $discount_total / $cart_item['quantity'];
            $cart_item['data']->set_price($unit_price);
        }
    }
}

关键修复点说明

  1. 精准定位商品:AJAX请求传递商品ID,只修改目标Hydrogel商品的购物车项
  2. 持久化折扣数据:用add_meta_data存储折扣总价,避免结账时被原始价格覆盖
  3. 动态价格计算:使用woocommerce_before_calculate_totals钩子,在每次购物车计算总计时自动应用折扣价,确保结账页显示正确
  4. 修复HTML语法:补全单选按钮属性的闭合引号,避免JS读取数据异常
  5. 适配WooCommerce逻辑:将阶梯折扣的总价转换为单件价格,匹配平台按单件计算总计的规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:10:54