Unset Specific Shipping Rate When Free Shipping Rate is Available for 2 Shipping zones

42 Views Asked by At

I found this code:

/**
 * @snippet       Hide one shipping rate when Free Shipping is available
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 6
 * @community     https://businessbloomer.com/club/
 */
  
add_filter( 'woocommerce_package_rates', 'bbloomer_unset_shipping_when_free_is_available_in_zone', 9999, 2 );
   
function bbloomer_unset_shipping_when_free_is_available_in_zone( $rates, $package ) {
   // Only unset rates if free_shipping is available
   if ( isset( $rates['free_shipping:8'] ) ) {
      unset( $rates['flat_rate:1'] );
   }     
   return $rates;
}

I can only use this to add one free shipping and one flat rate, I want to use this code for 2 free shipping and 2 flat rates because I have 2 Shipping zones. How can it be done?

I used that code and it worked for one shipping zone, but I need it to work for .

2

There are 2 best solutions below

1
LoicTheAztec On BEST ANSWER

To make your code work for multiple shipping zones, first you need to get all involved shipping rates IDs for each shipping zone, then set them in the array below:

add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 9999, 2 );
function filter_woocommerce_package_rates( $rates, $package ) {
    // Here below define the related shipping methods rate IDs for each shipping zone
    $shipping_data = array(
        array('free' => 'free_shipping:8',  'flat' => 'flat_rate:1'), // first zone
        array('free' => 'free_shipping:10', 'flat' => 'flat_rate:5'), // other zone
    );

    // Loop through shipping data array
    foreach ( $shipping_data as $data_zone ) {
        if ( isset($rates[$data_zone['free']],$rates[$data_zone['flat']]) ) {
            unset($rates[$data_zone['flat']]);
        }
    }
    return $rates;
}

Code goes in functions.php file of your child theme (or in a plugin). It should work.

Important: You will have to empty your cart to refresh shipping methods cache.

0
WPX On

You can adjust the function to loop through each shipping zone and check if free shipping is available in that zone:

add_filter( 'woocommerce_package_rates', 'bbloomer_unset_shipping_when_free_is_available_in_zones', 9999, 2 );

function bbloomer_unset_shipping_when_free_is_available_in_zones( $rates, $package ) {
    // Get all shipping zones
    $zones = WC_Shipping_Zones::get_zones();

    foreach ( $zones as $zone ) {
        // Get the zone ID
        $zone_id = $zone['zone_id'];

        // Check if free shipping is available in the current zone
        if ( isset( $rates["free_shipping:$zone_id"] ) ) {
            // Unset flat rates for the current zone
            unset( $rates["flat_rate:$zone_id"] );
        }
    }

    return $rates;
}

This code will loop through all shipping zones and unset the flat rate for each zone where free shipping is available.