Search code examples
phpwordpresswoocommercecartshipping-method

Hide other shipping options when Free shipping is available for one zone only in Woocommerce


I need a way to achieve the following: If Free Shipping is available, AND the order is being shipped to a specific zone, hide all other shipping methods.

I found this snippet:

function hide_shipping_when_free_is_available( $rates ) {
    $free = array();
    foreach ( $rates as $rate_id => $rate ) {
        if ( 'free_shipping' === $rate->method_id ) {
            $free[ $rate_id ] = $rate;
            break;
        }
    }
    return ! empty( $free ) ? $free : $rates;
}
add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 100 );

How would I add a conditional into it to only apply it to orders going to one zone?


Solution

  • The following code will hide all other shipping methods when free shipping is available for a specific Zone (you will define in the function the targeted zone ID or Zone name):

    add_filter( 'woocommerce_package_rates', 'free_shipping_hide_others_by_zone', 100, 2 );
    function free_shipping_hide_others_by_zone( $rates, $package ) {
        
        // HERE define your shipping zone ID OR the shipping zone name
        $defined_zone_id   = '';
        $defined_zone_name = 'Europe';
    
        // Get The current WC_Shipping_Zone Object
        $zone      = wc_get_shipping_zone( $package );
        $zone_id   = $zone->get_id(); // The zone ID
        $zone_name = $zone->get_zone_name(); // The zone name
    
        $free      = array(); // Initializing
    
        // Loop through shipping rates
        foreach ( $rates as $rate_id => $rate ) {
            if ( 'free_shipping' === $rate->method_id && ( $zone_id == $defined_zone_id || $zone_name == $defined_zone_name ) ) {
                $free[ $rate_id ] = $rate;
                break;
            }
        }
        return ! empty( $free ) ? $free : $rates;
    }
    

    Code goes in function.php file of the active child theme (or active theme). Tested and work.