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

基于商品分类的WooCommerce购物车商品阶梯折扣定价问题

解决特定分类商品阶梯折扣同步购物车小计及订单的问题

问题根源

原代码使用woocommerce_cart_calculate_fees钩子修改商品价格,这个钩子的执行时机是购物车总计计算完成后,仅修改商品显示价格不会触发小计重新计算,导致购物车总价不更新。同时未处理钩子重复触发的问题,可能造成价格被多次错误扣减。

解决方案

改用woocommerce_before_calculate_totals钩子(该钩子在购物车计算总价前触发),同时添加原始价格缓存逻辑避免重复折扣,确保折扣价同步到购物车小计和最终订单。

修改后的代码

add_action( 'woocommerce_before_calculate_totals', 'custom_bulk_discount', 20, 1 );
function custom_bulk_discount( $cart ) {
    // 后台非AJAX请求直接返回
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // 防止重复触发导致价格多次修改
    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    $target_category = 'ferns';
    $total_qty = 0;

    // 第一步:计算目标分类商品的总数量
    foreach ( $cart->get_cart() as $cart_item ) {
        if ( has_term( $target_category, 'product_cat', $cart_item['product_id'] ) ) {
            $total_qty += $cart_item['quantity'];
        }
    }

    // 第二步:根据阶梯数量设置折扣价
    if ( $total_qty >= 100 ) {
        $discount_amount = $total_qty >= 200 ? 1.5 : 1;

        foreach ( $cart->get_cart() as $cart_item ) {
            if ( has_term( $target_category, 'product_cat', $cart_item['product_id'] ) ) {
                $product = $cart_item['data'];
                
                // 保存原始价格到临时属性,避免重复折扣
                if ( ! $product->get_meta( '_original_price', true ) ) {
                    $original_price = version_compare( WC_VERSION, '3.0', '<' ) ? $product->price : $product->get_price();
                    $product->add_meta_data( '_original_price', $original_price, true );
                }

                // 基于原始价格计算折扣价
                $original_price = $product->get_meta( '_original_price', true );
                $discounted_price = $original_price - $discount_amount;

                // 设置折扣价(兼容WC3.0+版本)
                if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
                    $product->price = $discounted_price;
                } else {
                    $product->set_price( $discounted_price );
                }
            }
        }
    } else {
        // 数量未达阶梯,恢复原始价格
        foreach ( $cart->get_cart() as $cart_item ) {
            if ( has_term( $target_category, 'product_cat', $cart_item['product_id'] ) ) {
                $product = $cart_item['data'];
                $original_price = $product->get_meta( '_original_price', true );
                
                if ( $original_price ) {
                    if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
                        $product->price = $original_price;
                    } else {
                        $product->set_price( $original_price );
                    }
                    $product->delete_meta_data( '_original_price' );
                }
            }
        }
    }
}

关键说明

  • 钩子选择:woocommerce_before_calculate_totals确保在购物车计算总价前修改价格,小计会自动同步更新。
  • 原始价格缓存:通过商品临时元数据保存原始价格,避免钩子重复触发时多次扣减价格。
  • 订单同步:修改后的商品价格会直接传递到订单,开票时会使用折扣后的单价,满足开票需求。
  • 版本兼容:保留了WC3.0前后的价格获取/设置逻辑,适配不同版本的WooCommerce。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 15:01:07