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

基于可配送商品最低小计的免运费设置及进度条实现问题

WooCommerce购物车免运费提示与商品类型过滤优化方案

需求梳理

需要实现以下逻辑判断:

  • 仅含**预约(APPOINTMENT)**或虚拟商品时,显示感谢语
  • 购物车仅含实体商品且小计≤50欧元:不显示免运费差额进度条
  • 购物车包含实体商品+预约/虚拟商品,且小计<50欧元:显示免运费差额进度条
  • 购物车有普通商品(可变/简单类型)且小计≥50欧元:显示“免运费可用”

优化后的代码实现

// 判断购物车是否仅含预约/虚拟商品
function has_only_virtual_or_appointment() {
    $has_physical = false;
    foreach ( WC()->cart->get_cart() as $item ) {
        // 检查商品是否为实体商品(可配送)
        if ( $item['data']->is_shipping_required() ) {
            $has_physical = true;
            break;
        }
    }
    return !$has_physical;
}

// 判断购物车是否仅含实体商品
function has_only_physical_products() {
    $has_virtual_or_appointment = false;
    foreach ( WC()->cart->get_cart() as $item ) {
        // 检查商品是否为虚拟/预约类型(不可配送)
        if ( !$item['data']->is_shipping_required() ) {
            $has_virtual_or_appointment = true;
            break;
        }
    }
    return !$has_virtual_or_appointment;
}

// 判断购物车是否混合了实体与虚拟/预约商品
function has_mixed_products() {
    $has_physical = false;
    $has_virtual = false;
    foreach ( WC()->cart->get_cart() as $item ) {
        if ( $item['data']->is_shipping_required() ) {
            $has_physical = true;
        } else {
            $has_virtual = true;
        }
        // 两种类型都找到就提前终止循环
        if ( $has_physical && $has_virtual ) break;
    }
    return $has_physical && $has_virtual;
}

// 过滤配送方式
add_filter( 'woocommerce_package_rates', 'ecommercehints_free_shipping_for_specific_products', 10, 2 );
function ecommercehints_free_shipping_for_specific_products( $rates, $package ) {
    // 仅含虚拟/预约商品时,保留原有配送方式
    if( has_only_virtual_or_appointment() ){
        return $rates;
    }
    
    // 实体商品小计不足50时,移除指定免运费方式
    if ( WC()->cart->get_subtotal() < 50 ) {
        unset( $rates['free_shipping:21'] ); // 替换为你的免运费方式ID
    }
    return $rates;
}

// 结账页显示免运费提示/进度条
add_action( 'woocommerce_checkout_before_order_review', 'ecommercehints_checkout_page_progress_bar', 10 );
function ecommercehints_checkout_page_progress_bar() {
    $subtotal = WC()->cart->get_subtotal();

    // 仅含虚拟/预约商品:显示感谢语
    if( has_only_virtual_or_appointment() ){
        echo __("感谢您的订单", "woocommerce");
    } 
    // 小计≥50:显示免运费可用
    elseif ( $subtotal >= 50 ) {
        echo __("免运费可用", "woocommerce");
    }  
    // 小计<50的情况:判断是否混合商品,是则显示进度条;仅实体则不显示
    elseif ( $subtotal < 50 ) {
        if ( has_mixed_products() ) {
            printf( __('再消费 %s 即可享受免运费!', 'woocommerce'), wc_price( 50 - $subtotal ) );
            printf('<br><progress id="freeshippingprogress" max="50" value="%d"></progress>', intval($subtotal) );
        }
        // 仅实体商品时,此处什么都不输出
    }    
}

代码说明

  1. 商品类型判断函数:通过is_shipping_required()来区分实体/非实体商品,比直接判断商品类型更通用,兼容预约、虚拟等各类无需配送的商品
  2. 配送方式过滤:仅当存在实体商品且小计不足50时,移除免运费选项
  3. 结账页提示逻辑:严格按照需求分支判断,确保每种场景的输出符合预期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:58:20