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

WooCommerce单品页通过AJAX实时加载阶梯折扣价格方案咨询

实现WooCommerce可变产品数量变化时AJAX自动更新阶梯折扣价格

问题背景

搭建WooCommerce网店时,为可变产品设置了基于购买数量的阶梯折扣(例:0-10件单价20欧元,11-20件单价19欧元),已通过woocommerce_product_variation_get_price过滤器实现折扣,页面刷新后生效,但希望在单品页修改购买数量时,前端价格能通过AJAX自动更新,无需刷新页面。

原价格修改代码:

add_filter('woocommerce_product_variation_get_price', 'ga_change_product_price', 10, 2);

function ga_change_product_price($price, $product)
{
    $current_user_id = get_current_user_id();
    $current_user_customer_group = get_user_meta($current_user_id, 'customer_group')[0];
    $current_variation_id = $product->get_id();
    $parent_id = $product->get_parent_id();
    $cart = WC()->cart->get_cart();

    // Iterate over the custom price rows
    if (have_rows('custom_prices', $parent_id)) :

        while (have_rows('custom_prices', $parent_id)) : the_row();

            $variation_id = get_sub_field('variation_id');
            $customer_id = get_sub_field('customer_id');
            $customer_group = get_sub_field('customer_group');
            $min_qty = get_sub_field('min_qty');
            $max_qty = get_sub_field('max_qty');

            // If customer discount && graduated discount
            if ($variation_id == $current_variation_id && $customer_id == $current_user_id && !empty($min_qty) && !empty($max_qty)) {

                $cart_qty = 0;

                // Check the number of items in the cart of this specific variation id
                foreach ($cart as $cart_item) {
                    $cart_item_variation_id = $cart_item['variation_id'];

                    if ($cart_item_variation_id == $variation_id) {
                        $cart_qty = $cart_item['quantity'];
                    }
                }

                if ($cart_qty >= $min_qty && $cart_qty <= $max_qty) {
                    $price = get_sub_field('price');
                }
            }

            // If customer discount && no graduated discount
            else if ($variation_id == $current_variation_id && $customer_id == $current_user_id) {
                $price = get_sub_field('price');
            }

            // If group discount && graduated discount
            else if ($variation_id == $current_variation_id && $customer_group == $current_user_customer_group && !empty($min_qty) && !empty($max_qty)) {

                $cart_qty = 0;

                // Check the number of items in the cart of this specific variation id
                foreach ($cart as $cart_item) {
                    $cart_item_variation_id = $cart_item['variation_id'];

                    if ($cart_item_variation_id == $variation_id) {
                        $cart_qty = $cart_item['quantity'];
                    }
                }

                if ($cart_qty >= $min_qty && $cart_qty <= $max_qty) {
                    $price = get_sub_field('price');
                }
            }

            // If group discount && no graduated discount
            else if ($variation_id == $current_variation_id && $customer_group == $current_user_customer_group) {
                $price = get_sub_field('price');
            }

        endwhile;

    endif;

    return $price;
}

解决方案

1. 调整价格计算逻辑,支持传入自定义数量

原代码依赖购物车中的数量,但单品页修改数量时还未加入购物车,因此修改函数逻辑,允许传入外部数量参数,同时兼容原有过滤器调用:

// 保留原过滤器,兼容购物车等原有场景
add_filter('woocommerce_product_variation_get_price', 'ga_change_product_price', 10, 2);

// 新增独立计算函数,供AJAX调用
function ga_calculate_variation_price($variation_id, $qty = 1) {
    $product = wc_get_product($variation_id);
    if (!$product || !$product->is_type('variation')) {
        return false;
    }

    $current_user_id = get_current_user_id();
    $current_user_customer_group = get_user_meta($current_user_id, 'customer_group')[0];
    $parent_id = $product->get_parent_id();
    $price = $product->get_regular_price(); // 默认取产品原价

    // 复用原折扣规则,替换购物车数量为传入的自定义数量
    if (have_rows('custom_prices', $parent_id)) :
        while (have_rows('custom_prices', $parent_id)) : the_row();
            $variation_id_field = get_sub_field('variation_id');
            $customer_id = get_sub_field('customer_id');
            $customer_group = get_sub_field('customer_group');
            $min_qty = get_sub_field('min_qty');
            $max_qty = get_sub_field('max_qty');

            // 客户专属阶梯折扣
            if ($variation_id_field == $variation_id && $customer_id == $current_user_id && !empty($min_qty) && !empty($max_qty)) {
                if ($qty >= $min_qty && $qty <= $max_qty) {
                    $price = get_sub_field('price');
                }
            }
            // 客户专属无阶梯折扣
            else if ($variation_id_field == $variation_id && $customer_id == $current_user_id) {
                $price = get_sub_field('price');
            }
            // 客户组阶梯折扣
            else if ($variation_id_field == $variation_id && $customer_group == $current_user_customer_group && !empty($min_qty) && !empty($max_qty)) {
                if ($qty >= $min_qty && $qty <= $max_qty) {
                    $price = get_sub_field('price');
                }
            }
            // 客户组无阶梯折扣
            else if ($variation_id_field == $variation_id && $customer_group == $current_user_customer_group) {
                $price = get_sub_field('price');
            }
        endwhile;
    endif;

    return wc_price($price); // 返回带货币格式的价格
}

// 原过滤器函数调用新增的计算逻辑,兼容购物车场景
function ga_change_product_price($price, $product) {
    $cart_qty = 0;
    $variation_id = $product->get_id();
    $cart = WC()->cart->get_cart();

    // 获取购物车中该变体的数量
    foreach ($cart as $cart_item) {
        if ($cart_item['variation_id'] == $variation_id) {
            $cart_qty = $cart_item['quantity'];
            break;
        }
    }

    // 调用计算函数,购物车无该商品时默认传1
    $calculated_price = ga_calculate_variation_price($variation_id, $cart_qty ?: 1);
    return $calculated_price ? strip_tags($calculated_price) : $price;
}

2. 注册AJAX端点

添加WooCommerce AJAX接口,供前端请求计算价格:

add_action('wp_ajax_get_variation_discounted_price', 'ga_ajax_get_variation_price');
add_action('wp_ajax_nopriv_get_variation_discounted_price', 'ga_ajax_get_variation_price');

function ga_ajax_get_variation_price() {
    // 验证请求参数
    if (!isset($_POST['variation_id']) || !isset($_POST['qty'])) {
        wp_send_json_error('参数缺失');
    }

    $variation_id = intval($_POST['variation_id']);
    $qty = intval($_POST['qty']);

    $price = ga_calculate_variation_price($variation_id, $qty);
    if ($price) {
        wp_send_json_success(array('price' => $price));
    } else {
        wp_send_json_error('无法计算价格');
    }
}

3. 前端JS监听数量变化,触发AJAX更新

在单品页添加JavaScript,监听数量输入框变化,请求AJAX更新价格:

jQuery(document).ready(function($) {
    // 变体选中后初始化价格监听
    $('.variations_form').on('show_variation', function(event, variation) {
        updatePriceOnQtyChange(variation.variation_id);
    });

    // 绑定数量变化事件
    function updatePriceOnQtyChange(variationId) {
        $('.quantity input.qty').off('change keyup').on('change keyup', function() {
            var qty = $(this).val();
            if (qty < 1) qty = 1;

            $.ajax({
                url: wc_add_to_cart_params.ajax_url,
                type: 'POST',
                data: {
                    action: 'get_variation_discounted_price',
                    variation_id: variationId,
                    qty: qty
                },
                beforeSend: function() {
                    $('.woocommerce-variation-price').addClass('loading');
                },
                success: function(response) {
                    if (response.success) {
                        $('.woocommerce-variation-price').html(response.data.price).removeClass('loading');
                    }
                },
                error: function() {
                    $('.woocommerce-variation-price').removeClass('loading');
                }
            });
        });
    }
});

注意事项

  • 将代码添加到主题的functions.php文件或自定义插件中
  • 测试前清空缓存,避免旧代码干扰
  • 若使用自定义主题,需确认价格元素选择器(.woocommerce-variation-price)与主题匹配,不匹配则修改JS中的选择器

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:50:33