Skip to content

Instantly share code, notes, and snippets.

@mikejolley
Forked from claudiosanches/functions.php
Last active February 5, 2024 15:33
Show Gist options
  • Save mikejolley/7ced4986b0b9c4b1fffedbe3e6bb6860 to your computer and use it in GitHub Desktop.
Save mikejolley/7ced4986b0b9c4b1fffedbe3e6bb6860 to your computer and use it in GitHub Desktop.
WooCommerce - Hide shipping rates when free shipping is available.
<?php
/**
* Hide shipping rates when free shipping is available.
* Updated to support WooCommerce 2.6 Shipping Zones.
*
* @param array $rates Array of rates found for the package.
* @return array
*/
function my_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', 'my_hide_shipping_when_free_is_available', 100 );
@desupero
Copy link

How would I hide other non-relevant shipping methods please? So if shipping for 1-3 items is $7 and 4-8 is $10, how would I hide the shipping option for $7, if the buyer has chosen 4-8 products please?

@ToddNewent
Copy link

ToddNewent commented Mar 14, 2018

Hey, so if you want to hide everything but free shipping and local pickup then modify @mikejolley code and change the foreach loop as follows:

foreach ( $rates as $rate_id => $rate ) {
  if ( 'free_shipping' === $rate->method_id ) {
    $free[ $rate_id ] = $rate;
  }

  if ( 'local_pickup' === $rate->method_id ) {
    $free[ $rate_id ] = $rate;
  }
}

@neoseeyou
Copy link

neoseeyou commented Mar 16, 2018

Hello

I want to display free shipping only when cart price is above 100 euros or if current user has a specific active membership and hide others shipping methods if possible

wc_memberships_is_user_active_member( $user_id, 'premium' )

If you could help me that would be really nice of you

Thanks

Cheers

@CarlosJGonzalez
Copy link

I added a field to categories to store a date. Using this same code, I exclude Flat_Rate option when the date in the custom field is greater than the current date.

@ngothoai
Copy link

i used this code

add_filter( 'woocommerce_package_rates', 'businessbloomer_hide_free_shipping_for_shipping_class', 10, 2 );

function businessbloomer_hide_free_shipping_for_shipping_class( $rates, $package ) {
$in_cart = false;
foreach( WC()->cart->cart_contents as $key => $values ) {
if( $values[ 'data' ]->get_shipping_class_id() ) {
$in_cart = true;
break;
}
}
if( $in_cart ) {
unset( $rates['ba_table_rate:7'] ); // shipping method with ID (to find it, see screenshot below)
}
return $rates;
}

But after i need remove Clear customer sessions after that, then it work.,

@Evakos
Copy link

Evakos commented Feb 14, 2019

May I ask why it's not considered a given that other shipping methods would be hidden if free is available? What would the case be where you would want other shipping methods to choose from? I can only think it may to do with expedited delivery options. Is that correct?

@kdctechnologies
Copy link

Hello can any one help me on the below issue
i have a single shipping zone with local pick up, free shipping 1500 above and flat rate if order valie less than 1500

i want to hide flat rate when order eligible for fee shipping and only free shipping and Local pick up should show

Thanks

@bullscout
Copy link

Hi i am having problem with this. where exactly i can put this code. I did insert on function.php but its not working and got error on my admin panel. All i want is the shipping works by their geographical location. Base on the customer location and under my shipping zone it will only shows the shipping options with free shipping or flat rate

@Abbas-5253
Copy link

Kindly help me out how can I change Zone regions postal code to cities ? I just want that when customer purchase from my website they can directly place city and get shipping charges, No Postal code, no region.

@eduande
Copy link

eduande commented Jul 13, 2020

@jamiet @pasztig: I've expanded on the provided function to hide all shipping options, except a custom shipping option I've added through a plugin.
function v161_woocommerce_hide_shipping_method( $rates ) {
$free = array();
$free_shipping = false;

    foreach ( $rates as $rate_id => $rate ) {

        if ( 'free_shipping' === $rate->method_id ) {

            $free[ $rate_id ] = $rate;
            $free_shipping = true;

        }

        if ( $free_shipping == true && 'my_custom_shipping_method' === $rate->method_id ) {
            $free[ $rate_id ] = $rate;
        }

    }

    return ! empty( $free ) ? $free : $rates;
}

Ofcourse you should be able replace the part
'my_custom_shipping_method' === $rate->method_id
with
'flat_rate:5' === $rate->id
or
'My custom shipping option name' === $rate->label

I've not tested the last 2 suggestions, but it should at least set you on the right track

Hello, good afternoon, I need to know how the exact code would be to incorporate, since I have two free shipping limits that I need at the time to display one or the other, depending on the minimum amount of purchase. Thank you so much

@Domi-ml
Copy link

Domi-ml commented Dec 3, 2020

Hello,

I would like to use the original code to display free shipping when I don't need to show flat rate anymore : it doesn't work.
I've tried on my local site to remove every other things from my functions.php : it still does not work.

What could be wrong ? I've tried to write my own filter before finding this one, and I couldn't understand what could be wrong.

Still my site is running normally offline and online, with all the other functions and plugins.

@jvorld
Copy link

jvorld commented Sep 17, 2021

The code for free shipping + local pickup didn't work for me, but I found a solution in the WooCommerce docs. Might be helpful for some.

https://docs.woocommerce.com/document/hide-other-shipping-methods-when-free-shipping-is-available/

@bdonkor
Copy link

bdonkor commented Nov 8, 2021

You have saved me out of a 1-week headache, I am grateful

@Mona88888
Copy link

Mona88888 commented Mar 14, 2022

What code to use if you want the shipping price to appear only for class specific and not based on amount spent?

@Mona88888
Copy link

I used the php coding and this is what happen to my Wordpress account = Parse error: syntax error, unexpected '*', expecting end of file in /home/customer/www/nrgispower.com/public_html/wp-content/themes/flatsome-child/functions.php on line 3

Fatal error: Exception thrown without a stack frame in Unknown on line 0

I am unable to login or see my account or website. HELP HELP HELP

@KoolPal
Copy link

KoolPal commented Jul 29, 2022

add_filter('woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2);
function hide_shipping_when_free_is_available($rates, $package) {
$free_yn = 0;
$pickup_yn = 0;
foreach($rates as $key => $value) {
$key_part = explode(":", $key);
$method_title = $key_part[0];
if ('free_shipping' == $method_title) {
// check if free shipping rate exists
$free_yn = 1;
$free_shipping = $rates[$key];
$free_key = $key;
}
if ('local_pickup' == $method_title) {
// check if local pickup rate exists
$pickup_yn = 1;
$local_pickup = $rates[$key];
$pickup_key = $key;
}
}
if ($free_yn == 1) {
// Unset all rates.
$rates = array();
// Restore free shipping rate.
$rates[$free_key] = $free_shipping;
if ($pickup_yn == 1) {
// Restore local pickup rate.
$rates[$pickup_key] = $local_pickup;
}
return $rates;
}
return $rates;
}

@masjo Brilliant! Still works awesome in 2022! God bless you!

@pmlgil
Copy link

pmlgil commented May 18, 2023

Hello

I have an online store where anyone who makes purchases over €30 can benefit from the “Free Shipping” or “Local Pickup” service at one of the two existing stores.

I integrated the PHP code to hide the shipping fees when the “Free Shipping” service is available (for purchases over €30) and also the “Local Pickup” option is visible… Everything worked perfectly.

The PHP code that I integrated, was this:

/**

  • Hide shipping rates when free shipping is available, but keep "Local pickup"
  • Updated to support WooCommerce 2.6 Shipping Zones
    */

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;
			break;
		}
	}
	return $new_rates;
}

return $rates;

}

add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );

However, the “Free Shipping” option is visible, but only one of the two pick-up locations.

Apart from making the “Free Shipping” option visible, is there any possibility to make all pick-up locations visible and not just one? There are currently two physical stores where “Local Pickup” is possible

Thanks.

@ilohest
Copy link

ilohest commented Jan 30, 2024

@Sjouw Tank you very much! It really helped me as I had to show "Local Pickup" with free shipping. I used the 'My custom shipping option name' === $rate->label' and it worked perfectly. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment