-
-
Save mikejolley/7ced4986b0b9c4b1fffedbe3e6bb6860 to your computer and use it in GitHub Desktop.
<?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 ); |
I have the same questions, I want to keep the Local Pickup option if only free shipping is available. "Local Pickup" (Instance ID: 5)
@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
@Sjouw You are an absolute king! Really saved me a headache as I had to still show "Local Pickup" with free shipping. Also to confirm, I used the label instead 'My custom shipping option name' === $rate->label
and it worked perfectly. Thank you very much.
Thank you Sjouw, yours is the 1st version I've found that allows me to hide only one specific shipping method in Woocommerce when free shipping is implemented instead of all other shipping methods. Thank you for sharing!
@Sjouw
I have Local Pickup, Free Shipping and USPS as options for Local Shipping Zone.
To get Free Shipping, the customer has to spend at least $50.
I added the following code but it still doesn't show an option for Local Pickup, what am I doing wrong?
/**
* 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;
$free_shipping = true;
}
if ( $free_shipping == true && 'My custom shipping option name' === $rate->label ) {
$free[ $rate_id ] = $rate;
}
}
return ! empty( $free ) ? $free : $rates;
}
add_filter( 'woocommerce_package_rates', 'my_hide_shipping_when_free_is_available', 100 );
@EBonar try this
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 this dose not work.
I use two shipping Zone with different Minimum amount to get free shipping.
the Name of one shipping Zone is national and the other germany.
When a customer will order 49 euro in shipping Zone national it will be free shipping but when a customer in Germany must order 100 euro to get free shipping.
How can I solve this Problem.
kindly regards
I noticed that it will work automaticle. I forgot to add a free shipping in the Germany Zone.
Hi I have a situation below:
- Customers get "Free Shipping" on orders above $100 but No 'Free Shipping' if 10% cart discount coupon code is used.
- "Flat Shipping" is $9.95 and "Express Shipping" is $13.95 but
a) if Free Shipping applies Express Shipping should show $4.00 ($13.95 - $9.95)
b) if coupon code of 10% cart discount is used no free shipping or no discount on Express shipping applies. i.e (Flat Shipping $9.95 and Express Shipping $13.95 applies if coupon code is used)
How can I do this.
I tried setting up the Shipping Zone
a) Free Shipping "A Minimum order amount or a coupon" - Minimum order $100
b) Flat Shipping - $9.95
c) Local Pickup - I customized this to "Express Shipping" with cost $13.95
Using the function
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;
$free_shipping = true;
}
if ( $free_shipping == true && 'my_custom_shipping_method' === $rate->method_id ) {
$free[ $rate_id ] = $rate;
}
}
return ! empty( $free ) ? $free : $rates;
}
add_filter( 'woocommerce_package_rates', 'my_hide_shipping_when_free_is_available', 100 );
following things doesn't happen.
-
If coupon code is not used
a) For orders above $100 the express shipping is not showing along with 'Free Shipping'.
Also the express shipping value should be (Flat Shipping $9.95 - Express Shipping $13.95) = $4 -
If coupon code is used
a) On using '10% cart discount - Coupon Code' on order $100 or more - Customers should only get 10% cart discount (coupon) and not get Free shipping or discount on express shipping. Therefore the shipping option should show Flat Shipping $9.95 and Express Shipping $13.95b) On using '10% cart discount - Coupon Code' on order under $100 - Customers should only get 10% cart discount (coupon). Therefore the shipping option should show Flat Shipping $9.95 and Express Shipping $13.95
How can I achieve this.
Please suggest.
Nidhi
@masjo works very great!!!! thanks a thousand time. what i now need that the free shipping the first option is selected by default (at the moment none of the shipping mehthods are seleced.
Don't work for me :/
Is for 1 local pickup, but how to change this function for keep 2 local pickup ?
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?
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;
}
}
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
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.
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.,
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?
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
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
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.
@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
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.
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/
You have saved me out of a 1-week headache, I am grateful
What code to use if you want the shipping price to appear only for class specific and not based on amount spent?
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
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!
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.
@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. :)
Is it possible to remove one of the shipping options and not all of them if free shipping is available?