Disable only specific flat rate shipping method when free shipping is available in WooCommerce Disable only specific flat rate shipping method when free shipping is available in WooCommerce wordpress wordpress

Disable only specific flat rate shipping method when free shipping is available in WooCommerce


If you inspect the shipping methods radio buttons on cart or in checkout you will see something like:

<input type="radio" name="shipping_method[0]" data-index="0" id="shipping_method_0_flat_rate20" value="flat_rate:20" class="shipping_method" checked="checked">

So in value="flat_rate:20" (which is the rate Id):

  • the method Id is flat_rate,
  • and instance ID is 20.

Note: The code could be really simplified…

But as you don't provide the free shipping and other flat rate rates IDs (or instances Ids), I Keep your code making some changes to it, this way:

function hide_shipping_when_free_is_available( $rates, $package ) {    $new_rates = array();    foreach ( $rates as $rate_id => $rate ) {        // Only modify rates if free_shipping is present.        if ( 'free_shipping' === $rate->method_id ) {            $new_rates[ $rate_id ] = $rate;            break;        }    }    if ( ! empty( $new_rates ) ) {        foreach ( $rates as $rate_id => $rate ) {            //Save local pickup if it's present.            if ('local_pickup' === $rate->method_id ) {                $new_rates[ $rate_id ] = $rate;            }            if ( 20 == $rate->instance_id )                $new_rates[ $rate_id ] = $rate;            }        }        return $new_rates;    }    return $rates;}add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );

It should work.


You can check if free shipping is available based on its id. If it is available, it removes the shipping rate flat_rate:20.

Replace free_shipping:2 with your free shipping id.

// if free shipping is available, disable a specific shipping rateadd_filter( 'woocommerce_package_rates', 'hide_specific_shipping_rate_if_shipping_free_is_available', 10, 2 );function hide_specific_shipping_rate_if_shipping_free_is_available( $rates, $package ) {    if ( isset( $rates['free_shipping:2'] ) ) {        unset( $rates['flat_rate:20'] );    }    return $rates;}

The code has been tested and works. Add it to your active theme's functions.php.