skip to Main Content

I have two flat rates on my WooCommerce site and I want to disable one of them, when free shipping is enabled. I have a function which is working for all flat rates only.

How do I check for an instance id on a shipping rate? Can anyone help me understand how to check for the instance id?

I Was trying to echo shipping data out to make sense of what values were available but no echo was showing on the front end either so a tip on why would be great.

Here is my code attempt:

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 ) ) {
        //Save local pickup if it's present.
        foreach ( $rates as $rate_id => $rate ) {
            if ('local_pickup' === $rate->method_id ) {
                $new_rates[ $rate_id ] = $rate;
            }
            if ( 'flat_rate: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 );

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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 rate
    add_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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search