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

WooCommerce按用户角色分级折扣排除指定分类失效问题

修复WooCommerce分类排除失效的分级折扣代码

问题根源

原代码的分类排除功能失效,主要因为以下两点:

  • 处理产品变体时,错误使用了变体ID而非父产品ID获取分类信息
  • 未对分类术语的获取结果做有效性检查,可能因无分类或错误导致逻辑中断

修正后的完整代码

add_action( 'woocommerce_cart_calculate_fees', 'custom_discount_based_on_cart_total', 10, 1 );
function custom_discount_based_on_cart_total( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // 排除的分类slug
    $excluded_categories = array( 'redshirt1', 'redshirt2', 'redshirt3', 'redshirt4' );
    $discounted_total = 0;

    foreach ( $cart->get_cart() as $cart_item ) {
        // 使用父产品ID(兼容变体商品)
        $product_id = $cart_item['product_id'];
        $terms = get_the_terms( $product_id, 'product_cat' );

        // 跳过无分类或获取分类失败的情况
        if ( ! $terms || is_wp_error( $terms ) ) {
            $discounted_total += $cart_item['line_subtotal'];
            continue;
        }

        $exclude = false;
        foreach ( $terms as $term ) {
            if ( in_array( $term->slug, $excluded_categories ) ) {
                $exclude = true;
                break;
            }
        }

        if ( ! $exclude ) {
            $discounted_total += $cart_item['line_subtotal'];
        }
    }

    $discount = 0;
    $discount_text = "";

    // 判断是否为VIP用户
    $user = wp_get_current_user();
    $is_vip = in_array( 'vip', (array) $user->roles );

    if ( $discounted_total >= 2000 && $discounted_total < 4000 ) {
        $discount = $discounted_total * ($is_vip ? 0.03 : 0.02);
        $discount_text = '折扣 ' . ($is_vip ? '3%' : '2%');
    } else if ( $discounted_total >= 4000 && $discounted_total < 6000 ) {
        $discount = $discounted_total * ($is_vip ? 0.05 : 0.04);
        $discount_text = '折扣 ' . ($is_vip ? '5%' : '4%');
    } else if ( $discounted_total >= 6000 ) {
        $discount = $discounted_total * ($is_vip ? 0.07 : 0.06);
        $discount_text = '折扣 ' . ($is_vip ? '7%' : '6%');
    }

    if ( $discount > 0 ) {
        $cart->add_fee( __( $discount_text, 'woocommerce' ), -$discount );
    }
}

add_action( 'woocommerce_before_cart', 'show_discount_message' );
function show_discount_message() {
    $cart = WC()->cart;
    $excluded_categories = array( 'redshirt1', 'redshirt2', 'redshirt3', 'redshirt4' );
    $discounted_total = 0;

    // 统一使用与折扣计算相同的逻辑计算符合条件的金额
    foreach ( $cart->get_cart() as $cart_item ) {
        $product_id = $cart_item['product_id'];
        $product_cats = wp_get_post_terms( $product_id, 'product_cat' );

        if ( ! $product_cats || is_wp_error( $product_cats ) ) {
            $discounted_total += $cart_item['line_subtotal'];
            continue;
        }

        $exclude = false;
        foreach ( $product_cats as $product_cat ) {
            if ( in_array( $product_cat->slug, $excluded_categories ) ) {
                $exclude = true;
                break;
            }
        }

        if ( ! $exclude ) {
            $discounted_total += $cart_item['line_subtotal'];
        }
    }

    $user = wp_get_current_user();
    $is_vip = in_array( 'vip', (array) $user->roles );
    $return_to = wc_get_page_permalink( 'shop' );

    if ( $discounted_total < 2000 ) {
        $difference = 2000 - $discounted_total;
        $added_text = '再消费 ' . wc_price( $difference ) . ' 即可享受' . ($is_vip ? '3%' : '2%') . '折扣!';
        $notice = sprintf( '<a href="%s" class="button wc-forward">%s</a> %s', esc_url( $return_to ), '继续购物', $added_text );
        wc_print_notice( $notice, 'notice' );
    } else if ( $discounted_total >= 2000 && $discounted_total < 4000 ) {
        $difference = 4000 - $discounted_total;
        $added_text = '再消费 ' . wc_price( $difference ) . ' 即可升级至' . ($is_vip ? '5%' : '4%') . '折扣!';
        $notice = sprintf( '<a href="%s" class="button wc-forward">%s</a> %s', esc_url( $return_to ), '继续购物', $added_text );
        wc_print_notice( $notice, 'notice' );
    } else if ( $discounted_total >= 4000 && $discounted_total < 6000 ) {
        $difference = 6000 - $discounted_total;
        $added_text = '再消费 ' . wc_price( $difference ) . ' 即可升级至' . ($is_vip ? '7%' : '6%') . '折扣!';
        $notice = sprintf( '<a href="%s" class="button wc-forward">%s</a> %s', esc_url( $return_to ), '继续购物', $added_text );
        wc_print_notice( $notice, 'notice' );
    }
}

核心修复说明

  1. 兼容产品变体:使用$cart_item['product_id']替代$product->get_id(),确保始终获取父产品的分类信息
  2. 增加有效性检查:对get_the_terms和wp_get_post_terms的返回值做判断,避免因无分类或错误导致的逻辑异常
  3. 逻辑一致性:统一折扣计算和提示信息中的金额统计逻辑,避免两个功能出现数据不一致的情况
  4. 变量命名优化:将$is_customer改为$is_vip,更贴合业务语义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:23:12