WooCommerce: Hide Shipping Rates if Free Shipping Available

If Free Shipping is available, you possibly don’t want to show the other paid shipping options. WooCommerce shows by default all shipping rates that match a given shipping zone, so it’s not possible to achieve this from the settings alone.

You need PHP for that. In this example, we will disable all shipping methods but “Free Shipping” so that free shipping remains the only possible choice. And here’s the code to add to your functions.php ๐Ÿ™‚

Remove a given Flat Rate when Free Shipping is available @ WooCommerce Cart / Checkout

PHP Snippet #1: Unset Specific Shipping Rate When Free Shipping rate is available

To find the new “shipping method names” e.g. “free_shipping:8“, please see the screenshot at the bottom of this other tutorial: https://businessbloomer.com/woocommerce-disable-free-shipping-if-cart-has-shipping-class/
/**
 * @snippet       Hide one shipping option in one zone when Free Shipping is available
 * @how-to        Watch tutorial @ https://businessbloomer.com/?p=19055
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 3.6.3
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */
 
add_filter( 'woocommerce_package_rates', 'bbloomer_unset_shipping_when_free_is_available_in_zone', 10, 2 );
  
function bbloomer_unset_shipping_when_free_is_available_in_zone( $rates, $package ) {
     
// Only unset rates if free_shipping is available
if ( isset( $rates['free_shipping:8'] ) ) {
     unset( $rates['flat_rate:1'] );
}     
    
return $rates;
 
}

PHP Snippet #2: Unset ALL Shipping Rates in ALL Zones when ANY Free Shipping Rate is Available

/**
 * @snippet       Hide ALL shipping rates in ALL zones when Free Shipping is available
 * @how-to        Watch tutorial @ https://businessbloomer.com/?p=19055
 * @sourcecode    https://businessbloomer.com/?p=260
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 3.6.3
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */
 
add_filter( 'woocommerce_package_rates', 'bbloomer_unset_shipping_when_free_is_available_all_zones', 10, 2 );
  
function bbloomer_unset_shipping_when_free_is_available_all_zones( $rates, $package ) {
     
$all_free_rates = array();
    
foreach ( $rates as $rate_id => $rate ) {
      if ( 'free_shipping' === $rate->method_id ) {
         $all_free_rates[ $rate_id ] = $rate;
         break;
      }
}
    
if ( empty( $all_free_rates )) {
        return $rates;
} else {
        return $all_free_rates;
} 

}

Shipping Rates Not Working After Implementing this PHP?

You probably need to:

a) empty the Cart and start testing again

b) clear customer sessions:

Clear Customer Sessions – WooCommerce System Status Tools

Where to add this code?

You can place PHP snippets at the bottom of your child theme functions.php file (before "?>" if you have it). CSS, on the other hand, goes in your child theme style.css file. Make sure you know what you are doing when editing such delicate files - if you need more guidance, please take a look at my free WooCommerce Customization video tutorial.

Does this snippet still work?

Please let me know in the comments if everything worked as expected. I would be happy to revise the snippet if you report otherwise (please provide screenshots). I have tested this code with Storefront theme, the WooCommerce version listed above and a WordPress-friendly hosting on PHP 7.

If you think this code saved you time & money, please join other Business Bloomer supporters and avail of 365 days of WooCommerce benefits. Thank you in advance :)

Need Help with WooCommerce?

Check out these free videos, tutorials and tips!

  • how-to-edit-woocommerce-with-php-snippets
  • woocommerce-hooks-add_action-list-visual
  • woocommerce-customize-single-product-page-PHP
  • woocommerce-customize-shop-page-PHP
  • woocommerce-advanced-customization
  • how-to-edit-woocommerce-cart
  • woocommerce-customize-checkout-page-PHP
  • woocommerce-email-customization
  • woocommerce-conditional-logic

Rodolfo Melogli

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as a WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza.

85 thoughts on “WooCommerce: Hide Shipping Rates if Free Shipping Available

  1. Hi Rodolpho,

    How can I set woo when I have free shipping over 15$ and 1 product (free+ shipping) who doesn’t be include in the free shipping.

    For example for Free shipping over 15$:
    – product A = 10$ + 5$ shipping and product B = 0โ‚ฌ (promotion) + 5$ shipping
    – Cart = A*2 and B*3
    I would like the shipping cost is 15$ (A*2 >15$ = free shipping and B*3 = 5$*3 = 15$ shipping)

    Usually, I have two shipping option in the cart: 25$ (5 qty) or Free. In this cas a customer can take 2 product A and 20+ product B…

    Thank you very much Rodolpho,

    1. Hi Stan, thanks so much for your comment! Yes, this is possible – unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  2. Such a helpful post! Bravo!

    I managed to conditionally hide my Standard Shipping rates when free was available but leave the Express Shipping option always on (even for multiple shipping zones). Couldn’t do it with other plugins and I did it with your nice little code.

    Thank you for your kind contribution to the WooCommerce ecosystem ๐Ÿ™‚

  3. Hi Rodolfo,

    It works great for 1 country. But I ship to all EU countries (each country seperate zone) so all the shipping methods got another number as ID. How can I catch them all? Could you update your code so that it loops through all ID’s of the Flat Rate and Free Shippings in all zones?

    Thank you in advanced,
    Frank

    1. Hello Frank, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  4. Great job! Still working. Thanks!

  5. Not is working on 3.1.1. Can you help me?

    1. Hi Herbamedica, I just tested my snippet on default Storefront and WooCommerce 3.1.1 and it works fine.

      Go to WP Dashboard > WooCommerce > System Status: what errors do you see in red font?

      Also, take a look at this tutorial to see how to troubleshoot: https://businessbloomer.com/woocommerce-troubleshooting-mistakes-to-avoid/

      Hope this helps!

      R

  6. Thank you very much for sharing the code, but he does not work at 3.0.x.
    have any Update?

    1. Thanks for your feedback Tung. Can you try with the latest 3.0.5 please?

    2. Hi!

      After update to 3.0.7 not work ๐Ÿ™

      Please help.
      Thanks.

    3. Hey Bela ๐Ÿ™‚ Are you sure?

  7. Hi Radolfo
    I really enjoy your videos thank you so much for sharing.
    Please I need help I am trying to tackle an issue.
    I need to hard code the shipping rate per (specific) products in my woo commerce site and hide the other shipping rate values displayed in the checkout page? Please how will I go about this
    Quick overview
    I am running a special where customer get the product for free but have to pay shipping and handling rate of $7.99.
    I do not want them to see the other shipping rates available.

    1. Sophia, thanks for your comment! I can’t specifically help here via the blog, but maybe this might help https://businessbloomer.com/woocommerce-disable-free-shipping-if-cart-has-shipping-class/?

  8. Hi Rodolfo,

    I’ve tried using both snippets above, but I can’t seem to get this to work. When an order amount totals over $50, it should show only free shipping and local pickup (if their zipcode matches the predefined in local settings) and unset the flat_rate. If the amount totals under $50, it should not show free delivery. I have everything working properly with this code:

     
    add_filter( 'woocommerce_package_rates', 'bbloomer_unset_shipping_when_free_is_available_in_zone', 10, 2 );
      
    function bbloomer_unset_shipping_when_free_is_available_in_zone( $rates, $package ) {
         
        // Only unset rates if free_shipping is available
        if ( isset( $rates['free_shipping:8'] ) ) {
        unset( $rates['flat_rate:1'] );
    }   
         
    return $rates;
     
    }
    

    EXCEPT that it does not unset the flat rate. I’m pulling my hair out. Please help!

    1. I was able to get it fixed. Thank you so much for these snippets and tutorials!

    2. Awesome to hear that Chris! What was the problem?

    3. I had two different zones set up in Woocommerce and didn’t realize how they were being affected by the code. Once I was able to sort that out, I had a script run for both sets of zones and it fixed my problem.

    4. Excellent Chris, thank you for the follow up!

  9. Hi,

    Thanks for the great codes! I have the following situation. I use the following code to hide the flat-rate (:1) for zone 1 when free shipping (:2) is available:

    /**
     * @snippet       Hide one shipping option in one zone when Free Shipping is available
     * @how-to        Watch tutorial @ https://businessbloomer.com/?p=19055
     * @sourcecode    https://businessbloomer.com/?p=260
     * @author        Rodolfo Melogli
     * @compatible    WooCommerce 2.6.1
     */
     
    add_filter( 'woocommerce_package_rates', 'bbloomer_unset_shipping_when_free_is_available_in_zone', 10, 2 );
      
    function bbloomer_unset_shipping_when_free_is_available_in_zone( $rates, $package ) {
         
        // Only unset rates if free_shipping is available
        if ( isset( $rates['free_shipping:2']  ) ) {
        unset( $rates['flat_rate:1'] );
    }   
         
    return $rates;
     
    }

    However, I have a second zone (zone 1 = Netherlands / zone= Belgium) that uses different id’s for the flat rate (:5) and free shipping (:4). How can I make sure it also hides the flat rate for Belgium (:5) when free shipping (:4) is available there?

    Kind regards,
    Lars

    1. Hello Lars, thanks so much for your comment! You can simply add another “if isset… unset” line to the function, and in this way target multiple shipping methods. Let me know!

  10. Hello Rodolfo,

    I have a multilingual website based on WP 4.5.3 + WC 2.6.4 + the latest WPML

    I want to disable all the shipping rates on all the zones when the free shipping applies (cart over 200 pln, the Polish currency, or over 200 euros), so I pasted at the bottom of functions.php the snippet

    /**
     * @snippet       Hide ALL shipping rates in ALL zones when Free Shipping is available
     * @how-to        Watch tutorial @ https://businessbloomer.com/?p=19055
     * @sourcecode    https://businessbloomer.com/?p=260
     * @author        Rodolfo Melogli
     * @compatible    WooCommerce 2.6.1
     */
     
    add_filter( 'woocommerce_package_rates', 'bbloomer_unset_shipping_when_free_is_available_all_zones', 10, 2 );
      
    function bbloomer_unset_shipping_when_free_is_available_all_zones( $rates, $package ) {
         
        $all_free_rates = array();
         
            foreach ( $rates as $rate_id => $rate ) {
            if ( 'free_shipping' === $rate->method_id ) {
                $all_free_rates[ $rate_id ] = $rate;
                break;
            }
        }
         
        if ( empty( $all_free_rates )) {
            return $rates;
            } else {
            return $all_free_rates;
            } 
    }
    

    the same way I did previously with many other snippets on WordPress. I erased all the WC caches and so on but I just can’t have the result I am looking for

    What could it be the issue?

    Thank you so much for your help!

    1. Hello there, and thanks SO MUCH for your comment! I’m afraid I don’t provide custom work or WooCommerce support to free subscribers, I hope this is understandable. I hope you find a working snippet, best of luck ๐Ÿ™‚

  11. I tried using your code and it doesn’t work unfortunately, it is still showing the flat rate shipping fee and defaulting to it in woo commerce. Am I doing something wrong

    1. Hey Peter, thanks for your comment! It’s difficult to say as I have no idea about your shipping settings and if you correctly identified the shipping zone codes ๐Ÿ™‚ If you want to share your checkout link and explain what you’re trying to hide, that might allow me to troubleshoot your problem! Cheers, R

  12. Hi Rodolfo,
    For WC 2.6+ how would I unset 1 rate in each zone?. Your first snippet worked great for my Local Delivery Shipping Zone but I also need to do the same for my UK Shipping Zone, so how would I add multiple instance IDs to your code?

    Any help would be greatly appreciated.

    Thanks,
    Andy

    1. Hey Andy, thanks for your comment! If I understood well, I guess you just need to add another “unset” line:

      unset( $rates['flat_rate:1'] );
      unset( $rates['free_shipping:6'] );
      // etc.
      
  13. Thank you so much for the snippet, it works!

    1. Brilliant – thanks a lot for your feedback Stray!

  14. Hi Rodolfo!

    First I need to greet you for your great website and all your woocommerce tips! They’re very very useful!!

    And I’d like to show you a snippet that I’m trying to implement in my woocommerce website.

    Basically, I’m trying to hide free shipping option when the order total is under the minimum amount. It happens that it’s not working properly (I get the message “No available shipping methods”), so if you get a time to have a look, I appreciate! Thank you

    1. Hey Taysa, thanks so much for your comment! FYI, you can set up the “minimum free shipping threshold” in the WooCommerce settings, no need to use PHP ๐Ÿ™‚ Go to WooCommerce > Settings > Shipping > Free Shipping > Minimum Order Amount ๐Ÿ™‚

    2. Hi Rodolfo, thanks for your reply!
      I explain the reason that I’m trying to do that. The woocommerce default shipping calculation is applied to the subtotal, but I’m using a plugin that applies a discount (what is not bein consideratred by woocommerce shipping calculation). So in the snippet I tried to set the free shipping based on “cart_contents_total” and not to “subtotal”. So I thought that if I could hide free shipping ih the cases that the discount decrease the total order amount under the minimum amount it would solve my problem. Could you give me a hint?

    3. P.S. I can’t find any plugin which can do that :-/

    4. Gotcha ๐Ÿ™‚

      I took a look at your snippet, it looks perfect apart from the position of “return $rates”. This should be placed OUTSIDE the if statement ๐Ÿ™‚ Let me know if that works for you.

      R

    5. Hi Rodolfo!

      I put โ€œreturn $ratesโ€ outside the if statement as you said. Now it’s not giving me the error anymore, but Free shipping is still being showed even that total is under the minimum amount. Do you know if there’s another variable apart from “subtotal” and “cart_contents_total” that is used by woocommerce in the checkout calculation? Thanks again ๐Ÿ™‚

    6. Yes Taysa, there are many more variables – check https://docs.woothemes.com/wc-apidocs/class-WC_Cart.html and scroll down until you find get_total( ) – all the other variables will be underneath it. Hope this helps!

  15. Well I appreciate your help , but that code

    
    add_filter( 'woocommerce_package_rates', 'wcsupport_no_usps_us', 10, 2 );
      
    function wcsupport_no_usps_us( $rates, $package )) {
      
      if ( WC()->shippingclass->shipping_class ==(469) {
        foreach( $rates as $key => $rate ) {
          if (strpos($key,'usps') !== false) {
            unset( $rates[$key] );
          }
        }
      }
     return $rates;
     
    }
    
    

    breaks my store too. Not sure why I canโ€™t figure this out, must be something to do with the shipping classes that Iโ€™m not entering correctly. I have taken up too much of your time already and canโ€™t keep breaking the site trying to change and guess what Iโ€™m doing wrong every few minutes, so I guess I will just have to skip adding that function.

    Any chance this is closer to the right code I need to make this work or am I way off?

    
    add_filter( โ€˜woocommerce_package_ratesโ€™, โ€˜wcsupport_no_usps_usโ€™, 10, 2 );
    function wcsupport_no_usps_us( $rates, $package ) {
    
    if ( WC()->customer->shipping_country == โ€˜USโ€™ ) {
    // shipping class IDs that need the method removed
    $shipping_classes = array(469,468);
    
    foreach( WC()->cart->cart_contents as $key => $values )
    if( in_array( $values[ โ€˜dataโ€™ ]->get_shipping_class_id(), $shipping_classes ) )
    $if_exists = true;
    
    foreach( $rates as $key => $rate ) {
    if (strpos($key,โ€™uspsโ€™) !== false) {
    unset( $rates[$key] );
    }
    }
    }
    
    return $rates;
    
    }
    
    

    Thanks again for your time!

    1. Hey Courtney, I just checked your second code on my dev site and it works like a charm ๐Ÿ™‚ Send me your WP and FTP details via the contact page and I’ll get this done for you ๐Ÿ™‚

    2. Thank you for checking it out and for all of your help! I was able to add it to store and it is working. I now just have one problem with it.(that hopefully is an easy fix)

      When an item from the shipping class that removes USPS rates gets added (for example shipping class “Watch”) to the cart everything works great and the USPS rates are removed. However if an item from a different class (shipping class “Tshirt” gets added to the cart with the “Watch” item then the USPS rates do not show back up they stay hidden.

      I need the USPS rates to show up if any item other than just shipping class “watch” is in the cart.

      It’s only when only shipping class “watch” is in the cart that I need USPS rates gone.

      Cart contains “Watch” or “Watch” + “Watch” = No USPS

      Cart contains “Watch” + “Tshirt”= USPS rates visible

      Hope this makes sense.

      Code I have implemented on site is this one

      
      add_filter( 'woocommerce_package_rates', 'wcsupport_no_usps_us', 10, 2 );
      function wcsupport_no_usps_us( $rates, $package ) {
      
      
           // shipping class IDs that need the method removed
          $shipping_classes = array(469,468);
      
          foreach( WC()->cart->cart_contents as $key => $values )
              if( in_array( $values[ 'data' ]->get_shipping_class_id(), $shipping_classes ) )
                  $if_exists = true;
      
          foreach( $rates as $key => $rate ) {
            if (strpos($key,'usps') !== false) {
              unset( $rates[$key] );
            }
          }
        
        return $rates;
      
      }
      
      
    3. Hey Courtney ๐Ÿ™‚

      I think you have a couple of missing checks there. First, you’re not really using “$if_exists” – only if that is true you want to remove USPS. Second, you should add a PHP counter that counts how many shipping classes you have while you do the foreach – if this is greater than 1 then you have multiple classes and you don’t want to run the “unset”.

      Hope this helps ๐Ÿ™‚

  16. I have a unique situation I hope you could help offer code for my site.

    I want to be able to show only one shipping method when products of a certain shipping class are in the cart, but if a product from another shipping class gets added to the cart I need all the methods to show up again.

    1. Hey Courtney, thanks so much for your comment! I think you can find the solution here: http://bolderelements.net/support/knowledgebase/hide-shipping-method-when-cart-contains-shipping-class. Hope this helps ๐Ÿ™‚

    2. Rodolfo thank you I did try to use the shipping class method but it doesn’t seem to produce and results. This is the code I used:

       add_filter( 'woocommerce_package_rates', 'hide_shipping_when_class_is_in_cart', 10, 2 );
       
      function hide_shipping_when_class_is_in_cart( $rates, $package ) {
          // shipping class IDs that need the method removed
          $shipping_classes = array(469);
          $if_exists = false;
       
          foreach( WC()->cart->cart_contents as $key => $values )
              if( in_array( $values[ 'data' ]->get_shipping_class_id(), $shipping_classes ) )
                  $if_exists = true;
       
          if( $if_exists ) unset( $rates['usps'] );
       
          return $rates;
      }
    3. It looks good, however the USPS $rates work slightly different from the default WooCommerce ones. You have to add some more lines of PHP instead of just:

      unset( $rates['usps'] )
      

      This article will help you figure what you need: https://docs.woothemes.com/document/usps-shipping/#section-10

      Hope this helps ๐Ÿ™‚

    4. Thank you I’m pretty new to trying to edit my on website code, so I appreciate your time and help. I tried a few variations, but each one broke my site, so not sure what I’m still doing wrong. I used this code now

       add_filter( 'woocommerce_package_rates', 'wcsupport_no_usps_us', 10, 2 );
      function wcsupport_no_usps_us( $rates, $package ) {
      
        if ( WC()->shippingclass->shipping_class ==(469) {
          foreach( $rates as $key => $rate ) {
            if (strpos($key,'usps') !== false) {
              unset( $rates[$key] );
            }
          }
        }
      
    5. Hey Courtney! You have a couple of syntax errors (missing parenthesis):

       
      
      add_filter( 'woocommerce_package_rates', 'wcsupport_no_usps_us', 10, 2 );
      
      function wcsupport_no_usps_us( $rates, $package )) {
      
        if ( WC()->shippingclass->shipping_class ==(469) {
          foreach( $rates as $key => $rate ) {
            if (strpos($key,'usps') !== false) {
              unset( $rates[$key] );
            }
          }
        }
      }
      
      
  17. Worked for me!

    Thank you so much, you rock!

    1. Awesome, thanks for your feedback Fred! ๐Ÿ™‚

  18. Hi,

    I’ve used this code snippet now to hide flat rate when free shipping is available (above 50โ‚ฌ). But for some reasons it’s now always hidden. I want to use flat rate under 50โ‚ฌ (and hide free shipping), while using free shipping above 50โ‚ฌ (and hide flat rate).

    /**
    * woocommerce_package_rates is a 2.1+ hook
    */
    add_filter( ‘woocommerce_package_rates’, ‘hide_shipping_when_free_is_available’, 10, 2 );

    /**
    * Hide shipping rates when free shipping is available
    *
    * @param array $rates Array of rates found for the package
    * @param array $package The package array/object being shipped
    * @return array of modified rates
    */
    function hide_shipping_when_free_is_available( $rates, $package ) {

    // Only modify rates if free_shipping is present
    if ( isset( $rates[‘free_shipping’] ) ) {

    // To unset a single rate/method, do the following. This example unsets flat_rate shipping
    unset( $rates[‘flat_rate’] );

    }

    return $rates;
    }

    Hope you could help me out. Thanks!

    1. Hey Neal thanks for your message. The snippet should work, so I fear you didn’t set up the “Free Shipping” method properly. If you go to WooCommerce/Settings/Shipping/FreeShipping, do you see “50” in the Minimum Order Amount and do you see “A minimum order amount…” in the “Free Shipping Requires…” dropdown?

    2. Hmm that was a stupid mistake of me. Exactly forgot to select ‘a minimum order amount’ in the dropdown. Thanks for helping me out!

    3. Ahaha, excellent ๐Ÿ™‚ Glad you sorted it out!

  19. Hello,

    Thanks for the tip, really helpful.. I have added the code to my functions.php file and it does work but only on the checkout page. Any ideas for the cart page?
    Thanks

    1. Thanks for your feedback Nikolas! woocommerce_package_rates should work on both Cart and Checkout page, so this is strange! Did you get this sorted?

  20. Hi Rodolfo,

    Not sure what good i did these few days to find your amazing site. This is like a gold mine for Woo website owners. Thank you so much for sharing!

    I’m trying to implement something similar, would appreciate if you can show me the snippet for this.

    We have 2 delivery options. 1. delivery cost (via flat rate) 2. office pickup

    Now we have 4 payment options at checkout. 1. cards 2. bank 3. COD 4. pay at office

    If a customer selects “office pickup” at checkout page, we want payment option 3. COD to hide.

    How can we achieve this?

    Thank you again!
    Ran

    1. i got this done. Found the solution at wordpress.com ๐Ÿ™‚

  21. Hi Rodolfo,

    The shipping methods I’m using on my site are – Flat Rate (Only to Australia) and Australia Post (International). Is there any way I can hide the Australian Post when Flat Rate is available?

    Your help would be much appreciated.

    Many thanks

    1. Hello Rod! Yes of course. Just go to Woocommerce > Settings > shipping and identify your Shipping ID (see image). Then, use the same rule. R

  22. Thanks Rodolfo, helped a lot

  23. Thank you very much for this snippet!!
    I’ve tried so many that did not work, until yours did!
    Best regards,
    Ofer

  24. Hi Rodolfo,

    I’ve tried to add the code without results – I’m trying to hide the local_delivery.

    Any idea?

    Thanks!

    1. Isa, try this:

      add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );
      function hide_shipping_when_free_is_available( $rates, $package ) {
          if ( isset( $rates['free_shipping'] ) ) {
              unset( $rates['local_delivery'] );
          }  
          return $rates;
      }
      
    2. It works perfectly now!
      I just see the free shipping when it’s available. But I have some different options for shipping and I want to leave free_shipping and local_delivery as well. How can I add local_delivery here?

      $free_shipping = $rates[‘free_shipping’];
      $rates = array();
      $rates[‘free_shipping’] = $free_shipping;

      Thanks Rodolfo!

    3. Awesome Isa! If you want to unset all rates but free shipping and local delivery you will have to use the other code:

      ...
      ...
      if ( isset( $rates['free_shipping'] ) ) {
         unset( $rates['flat_rate'] );
         unset( $rates['second_rate'] );
         unset( $rates['third_rate'] );
      	}
      ...
      ...
      
    4. I have now this code:

      add_filter( ‘woocommerce_package_rates’, ‘hide_shipping_when_free_is_available’, 10, 2 );

      function hide_shipping_when_free_is_available( $rates, $package ) {
      if ( isset( $rates[‘free_shipping’] ) ) {
      unset( $rates[‘local_delivery’] );
      unset( $rates[‘WC_Weight_Based_Shipping_main’] );
      unset( $rates[‘WC_Weight_Based_Shipping_1432200267’] );
      unset( $rates[‘WC_Weight_Based_Shipping_1429291395’] );
      unset( $rates[‘WC_Weight_Based_Shipping_1432200691’] );
      unset( $rates[‘WC_Weight_Based_Shipping_1432200297’] );
      unset( $rates[‘WC_Weight_Based_Shipping_1432200225’] );
      unset( $rates[‘WC_Weight_Based_Shipping_1432205333’] );
      unset( $rates[‘WC_Weight_Based_Shipping_1432205375’] );
      unset( $rates[‘WC_Weight_Based_Shipping_1432205184’] );
      unset( $rates[‘WC_Weight_Based_Shipping_1432205425’] );
      unset( $rates[‘WC_Weight_Based_Shipping_1432205456’] );
      unset( $rates[‘WC_Weight_Based_Shipping_1432205508’] );
      }
      return $rates;
      }

      And I have local_pickup as well, which I want to show with free_shipping when this is available, but still now I see just free_shipping. Any idea?

      Isa

    5. Remove this line: unset( $rates[‘local_delivery’] );

    6. Actually it’s a different shipping local_delivery (we send the package cheaper because it’s local) than local_pickup (user can come to the shop and pick up the package). But anyway, even removing this line
      unset( $rates[โ€˜local_deliveryโ€™] );

      The only shipping method available is free shipping.

    7. Weird ๐Ÿ™‚

      Try this (if this does not work, then there is some advanced customization that needs to be done due to your template or specific functionalities I’m afraid):



      if ( isset( $rates[‘free_shipping’] ) ) {
      // basically put all the unset rates in one line of code
      unset( $rates[‘flat_rate’], $rates[‘second_rate’], $rates[‘third_rate’] );
      }

    8. Rodolfo,

      It doesn’t work, probably it’s my template as you said. We have tried but the result is still just the free_shipping option.

      Thanks for your help Rodolfo!

    9. No problem Isa, thanks for letting me know ๐Ÿ™‚ What template are you using?

  25. Worked perfectly. Thank You.

    1. Thanks for the feedback Raj!

  26. Nice code snippet. Worked fine but there is a little customization that I want. I also want to display express delivery option that I am managing with Woo commerce Table Rate Shipping plugin. Any idea how to display that express delivery rate too ?

    1. Thanks for your comment Bilal ๐Ÿ™‚

      Table rates plugin creates multiple sub-rates called “table_rate-1”, “table_rate-2” etc. You can find the exact IDs under Shipping Zones / your_zone. If you want to target them all, you can use the following:

      
      foreach ( $rates as $key => $value ) {
                  if ( false !== strpos( $key, "table_rate" ) ) {
                      unset( $rates[$key] );
                  }
              }
      
      

      Hope this helps!

    2. Thanks..it worked..

  27. Hey
    Actually i have setup my shipping options for free shipping (Above 500) and flat rate (Below 500).

    Now the problem is that when an item qualifies for free shipping(ie order above 500), the flat rate charges still keep showing up as an option on cart and checkout page.

    Please help, Thanks

    1. Are you using this function?

      
      function hide_shipping_when_free_is_available( $rates, $package ) {
           
          // Only modify rates if free_shipping is present
          if ( isset( $rates['free_shipping'] ) ) {
           
              // To unset a single rate/method, do the following. This example unsets flat_rate shipping
              unset( $rates['flat_rate'] );
               
              }
           
          return $rates;
      }
      
      
  28. Hi! Many thanks for your post! I was searching right for this snippet!
    I have 3 shipping methods. If free shipping is available, I’d like to show two of them.
    It was simply to unset the flat rate! Genius!
    Thanks, regards.

    1. Thank you, really appreciate your feedback ๐Ÿ™‚

Questions? Feedback? Support? Leave your Comment Now!
_____

If you are writing code, please wrap it between: [php]code_here[/php]. Failure to complying with this (as well as going off topic) will result in comment deletion. You should expect a reply in about a week - this is a popular blog but I need to get paid work done first. Please consider joining #BloomerArmada to ask me 1-to-1 WooCommerce questions. Thank you :)

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.