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

WooCommerce中购物车全为指定配送类商品时取消配送费率

Fix: Only Remove Shipping Rates When ALL Cart Items Are in the Targeted Shipping Class

Let me walk you through fixing this WooCommerce shipping rate logic issue.

The Problem

Your original requirement was: Only remove specific shipping rates if EVERY item in the cart belongs to the targeted shipping class. But the initial code was removing those rates as long as any item in the cart matched the class — which didn't align with what you needed.

Original (Incorrect) Code

Here's the code that wasn't working as intended:

//ROYAL MAIL ONLY FOR SPECIFIC PRODUCTS
add_filter( 'woocommerce_package_rates', 'hide_table_shipping_for_shipping_class', 10, 2 );
function hide_table_shipping_for_shipping_class( $rates, $package ) {
    $shipping_class_target = 137;
    $in_cart = false;
    foreach( WC()->cart->cart_contents as $key => $values ) {
        if( $values[ 'data' ]->get_shipping_class_id() === $shipping_class_target ) {
            $in_cart = true;
            break;
        }
    }
    if( $in_cart ) {
        unset( $rates['mh_wc_table_rate_plus_85'] );
        unset( $rates['mh_wc_table_rate_plus_1' ] );
        // 省略其余与原代码一致的unset语句
        unset( $rates['mh_wc_table_rate_plus_77' ] );
    }
    return $rates;
}

The issue here is that it stops checking as soon as it finds one item with the target class, then removes the rates — which is the opposite of your requirement.

Fixed Code (Using LoicTheAztec's Solution)

After testing different approaches, this revised code gets the logic right:

add_filter( 'woocommerce_package_rates', 'hide_table_shipping_for_shipping_class', 10, 2 );
function hide_table_shipping_for_shipping_class( $rates, $package ) {
    $targeted_class = 137; // <== Your targetted shipping class
    // Loop through cart items to check if any item doesn't have the targetted shipping class
    foreach( WC()->cart->cart_contents as $key => $values ) {
        // If we find even one item without the target class
        if( $values[ 'data' ]->get_shipping_class_id() != $targeted_class ) {
            // Keep all original rates (we don't remove anything here)
            return $rates; // <== Exit early, return full rate list
        }
    }
    // All shipping instance IDs to be removed (fill in your full list)
    $instance_ids = array( '1', '2', ..., '103' ); 
    foreach( $instance_ids as $instance_id )
        unset( $rates["mh_wc_table_rate_plus_$instance_id"] );
    return $rates;
}

How This Fixed Logic Works

  1. Check for non-target items first: We loop through every cart item. If we find any item that doesn't belong to the target shipping class, we immediately return the full set of shipping rates (no changes made).
  2. Only remove rates if all items qualify: If the loop completes without finding any non-target items, that means every item is in the target class. We then iterate through our list of rate IDs to remove and unset them all at once.

This way, the shipping rates are only removed when your cart meets the "all items in target class" condition — exactly what you needed.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:28:26