WooCommerce: Shipping Rates by Order Amount

The new shipping zone management that was introduced with Woo 2.6 gives us the chance to add flat rate, free shipping and local pick-up methods by default.

But what if a client requires 3Β different rates depending on the order amount (tiered shipping)? For example:Β “For orders up to $100, shipping = $5; for orders up to $250, shipping = $2; for orders above $500, shipping = free”.

Is this possible without using a plugin? Well, the answer, as usual, is absolutely yes! Enjoy!

1. Tiered Shipping – Shipping Zone Setup

Go to WooCommerce > Settings > Shipping and create your shipping zone. In the example, I will target US customers and add 3 shipping methods to it: Flat Rate, Flat Rate and Free Shipping.

Shipping Zone Setup for Tiered Shipping
Shipping Zone Setup for Tiered Shipping

2. Tiered Shipping – Shipping Methods Setup

Open each one of the shipping methods previously added to the zone and rename them / set them up like this:

  1. Flat Rate #1 > rename to “Orders Below $100” and assign cost = $5
  2. Flat Rate #2 > rename to “Orders Below $250” and assign cost = $2
  3. Free Shipping > select “Requires a minimum order amount” = $500

Here’s one of the method’s setup:

Shipping Method Setup for Tiered Shipping
Shipping Method Setup for Tiered Shipping

3. Tiered Shipping – PHP Snippet

Now we need to “tell” WooCommerce that, based on the order amount, a Flat Rate should be used instead of the other. Only in this way we can show the correct shipping method to the end user.

First, take a note of the unique ID of the two flat rates. They should look look something like “flat_rate:9“. For more info on how to find it, check the “How to Find Shipping Class ID” paragraph here: https://businessbloomer.com/woocommerce-disable-free-shipping-if-cart-has-shipping-class

Second, let’s code! We’ll need to “unset” flat rate #2 if we are under $100, otherwise we’ll require to “unset” flat rate #1.

/**
* @snippet       Tiered Shipping Rates | WooCommerce
* @how-to        Get CustomizeWoo.com FREE
* @author        Rodolfo Melogli
* @testedwith    WooCommerce 5.0
* @community     https://businessbloomer.com/club/
*/

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

function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
   $threshold = 100;
   if ( WC()->cart->subtotal < $threshold ) {
      unset( $rates['flat_rate:1'] );
   } else {
      unset( $rates['flat_rate:2'] );
   }
   return $rates;
}

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

  • WooCommerce: Remaining $$$ to Get Free Shipping Notification @ Cart
    This is a very cool snippet that many of you should use to increase your average order value. Ecommerce customers who are near the “free shipping” threshold will try to add more products to the cart in order to qualify for free shipping. It’s pure psychology. So, here’s how we show a simple message on […]
  • WooCommerce: Weight-Based Shipping Methods
    With WooCommerce you get 3 default shipping methods: Flat Rate, Free Shipping, Local Pickup. For each one you can define a cost, however there is no way to set up some “weight” restrictions. So, what if you want to display a rate for orders below 10 kg, and another shipping rate for orders above that […]
  • WooCommerce: Hide Shipping Method If Shipping Class Is In The Cart
    Our goal is to check if a Product with a specific Shipping Class is in the Cart, and consequently disabling a shipping rate such as Free Shipping if this is true. This is super useful when there are multiple items in the cart and you don’t want to give free shipping for certain orders for […]
  • WooCommerce: Hide Shipping Rates if Free Shipping Available
    If Free Shipping is available, you possibly don’t want to show the other premium 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. Thankfully, the “woocommerce_package_rates” filter allows us to manipulate the shipping rates before they are returned […]
  • WooCommerce: Hide Shipping If Local Pickup Is Selected
    Let’s talk about checkout UX: if a user is willing to pick up the item in store, why should there be a shipping form on the checkout? Well, let’s see how we can hide this dynamically with a bit of PHP and JS!

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent 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. Follow @rmelogli

94 thoughts on “WooCommerce: Shipping Rates by Order Amount

  1. Hi there,

    Added this code, changing the amount to 30 (Β£30) but when the threshhold is below 30 it only shows the option for flat_rate:6.

    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 10, 2 );
     
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
       $threshold = 30;
       if ( WC()->cart->subtotal < $threshold ) {
          unset( $rates['flat_rate:1'] );
       } else {
          unset( $rates['flat_rate:6'] );
       }
       return $rates;
    }
    

    It's not showing any errors so not sure what I'm doing wrong.

    1. Your code hides Flat Rate 1 below 30 (so the only remaining is Flat Rate 6)

  2. Is there a way to have it just change UPS Ground to $5.00 to override the UPS LIVE RATES calculated?

    I don’t know of a command to have it update the price.

    1. If UPS uses the “WooCommerce way” of returning rates, and it’s therefore possible to override them, then yes

  3. Code isn’t working for me, not sure if it’s outdated or not compatible with our theme. Using eStore theme.

     /* Restrict shipping methods by cart total */
    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 10, 2 );
     
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
       $threshold = 100;
       if ( WC()->cart->subtotal < $threshold ) {
          unset( $rates['flat_rate:1'] );
       } else {
          unset( $rates['flat_rate:5'] );
       }
       return $rates;
    }
    

    Only 2 shipping methods:
    flat_rate:1 is over $100
    flat_rate:5 is under $100

    <input type="radio" name="shipping_method[0]" data-index="0" id="shipping_method_0_flat_rate1" value="flat_rate:1" class="shipping_method" checked="checked">
    
    <input type="radio" name="shipping_method[0]" data-index="0" id="shipping_method_0_flat_rate5" value="flat_rate:5" class="shipping_method">
    

    Thanks for any thoughts!

    1. Hi Joe! Have you tried emptying the cart before testing the shipping conditional?

  4. Did exactly what I needed and saved me from installing yet another plugin. Thank you!

  5. Hi,

    Thank you for this code, works beautifully! Is it possible to calculate the cart total after discounts and replace shipping methods based on that?

    Thanks!

    1. Hey Devi! Sure, that sounds possible. Check the other cart totals functions here and you should find the solution: https://www.businessbloomer.com/woocommerce-get-cart-info-total-items-etc-from-cart-object/

      1. Cart total seems to be optimal way of doing it.

        How to change it? im not developer, so that guide you link to did not help

        1. For example, you can sub “WC()->cart->subtotal” with “WC()->cart->total”. Let me know if it works

  6. Hi,

    I am trying to replace a flat rate shipping method with another with a threshold of $250, using this code, but gives the error –
    syntax error, unexpected ‘function’ (T_FUNCTION)

    The code I used is

    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 10, 2 );
    Β 
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
    Β Β Β $threshold = 250;
    Β Β Β if ( WC()-&gt;cart-&gt;subtotal &lt; $threshold ) {
    Β Β Β Β Β Β unset( $rates[&#039;flat_rate:87] );
    Β Β Β } else {
    Β Β Β Β Β Β unset( $rates[&#039;flat_rate:94] );
    Β Β Β }
    Β Β Β return $rates;
    }
    
    1. Could be a problem with your single quote symbols – you need to use -> ‘ and not “backticks”. Otherwise the problem is not related to my snippet

  7. HI
    Thank you for the code.

    How can I add a notice to the customer?
    I need the customer to know that there has to a minimum amount, to be able to choose shipping?

    I have only 2 options available for customer:
    1. Local pickup
    2. Shipping if amount in cart is minimum 400

    1. Hi Helle thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  8. Hello,

    I have a $15 shipping cost for orders less than $150 and free shipping for over than that. I write this code and tried it several times but it’s not working.
    Would you please tell me where the problem is?

    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 10, 2 );
     
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
       $threshold = 150;
       if ( WC()-&gt;cart-&gt;subtotal &lt; $threshold ) {
          unset( $rates[&#039;flat_rate:9&#039;] );
       } else {
          unset( $rates[&#039;free_shipping:10&#039;] );
       }
     
       return $rates;
    }
    
    1. You’re unsetting the opposite thing

  9. Hello,

    I am just trying to create a $5 charge on a bill amount of less than $150. Free shipping above $150. Should I remove the Else condition?

    I am new to this and trying to learn things. This is my first demo project. This might sound naΓ―ve πŸ™‚

    ;

    1. No prob at all. You can do that from the Woo settings!

  10. Hi! Great post! How can I limit it to certain categories?

    1. I suggest you take a look at “conditional logic”: https://businessbloomer.com/woocommerce-conditional-logic-ultimate-php-guide/. Enjoy πŸ™‚

  11. Woah thank you so much for this!

    What about if I want a flat rate of Β£7 for the first item in the cart and then an additional Β£4 for each additional item thereafter? Is this possible using similar code to this?

    Thank you

    1. Hello Charlotte, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  12. Thanks so much for all of your help. These tutorials are a life saver! I can always find just what I’m looking for and I appreciate that so much!

    1. Thank you!

  13. Bonjour,
    Merci pour ce code! Comment conserver l’option Point de vente quand mΓͺme?
    Guylaine

    1. Guylaine, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  14. Hello, I use this usefull code ans it works prefectly on my website ! So thanks a lot Rodolfo ! I try now to add a new condition with the cart amount, especialy when it’s higher than 80€. This is the last part of the code beloow but it doesn’t work… I’m sure there is an issue but I’m not able to fix it. Could you take a look on it ? Sorry for my english, I’m French… πŸ™‚

    Here is the long code :

    cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;250 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;500 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;750 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;1000 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;2000 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;3000 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;4000 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;5000 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;6000 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;7000 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;8000 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;9000 &amp;&amp; WC()-&gt;cart-&gt;get_cart_contents_weight() cart-&gt;get_cart_contents_weight() &gt;10000 ) {
           
             if ( isset( $rates['service_point_shipping_method:88'], $rates['flat_rate:89'] ) )
    		 unset ($rates['service_point_shipping_method:56'],
    			    $rates['service_point_shipping_method:57'],
    			    $rates['service_point_shipping_method:58'],
    			    $rates['service_point_shipping_method:59'],
    				$rates['service_point_shipping_method:60'],
    			    $rates['service_point_shipping_method:61'],				
    			    $rates['service_point_shipping_method:62'],
    				$rates['service_point_shipping_method:63'],
    				$rates['service_point_shipping_method:64'],
    				$rates['service_point_shipping_method:65'],
    			    $rates['service_point_shipping_method:66'],
    			    $rates['service_point_shipping_method:67'],
    				$rates['service_point_shipping_method:68'],
    			    $rates['flat_rate:75'],
    			    $rates['flat_rate:76'],
    			    $rates['flat_rate:77'],
    			    $rates['flat_rate:78'],
    			    $rates['flat_rate:79'],
                    $rates['flat_rate:80'],
    			    $rates['flat_rate:81'],
    				$rates['flat_rate:82'],
    			    $rates['flat_rate:83'],
    			    $rates['flat_rate:84'],
    			    $rates['flat_rate:85'],
    			    $rates['flat_rate:86'],
    				$rates['flat_rate:87'] );
         }
    		
    		/* au dela de 80euros de commande */
    		
    		elseif ( WC()-&gt;cart-&gt;subtotal &gt;= $threshold ) {
           
             if ( isset( $rates['service_point_shipping_method:89'], $rates['flat_rate:88'] ) )
    		 unset ($rates['service_point_shipping_method:56'],
    				$rates['service_point_shipping_method:57'],
    			    $rates['service_point_shipping_method:58'],
    			    $rates['service_point_shipping_method:59'],
    			    $rates['service_point_shipping_method:60'],
    				$rates['service_point_shipping_method:61'],
    			    $rates['service_point_shipping_method:62'],				
    			    $rates['service_point_shipping_method:63'],
    				$rates['service_point_shipping_method:64'],
    				$rates['service_point_shipping_method:65'],
    				$rates['service_point_shipping_method:66'],
    			    $rates['service_point_shipping_method:67'],
    			    $rates['service_point_shipping_method:68'],
    			    $rates['flat_rate:75'],
    				$rates['flat_rate:76'],
    			    $rates['flat_rate:77'],
    			    $rates['flat_rate:78'],
    			    $rates['flat_rate:79'],
    			    $rates['flat_rate:80'],
                    $rates['flat_rate:81'],
    			    $rates['flat_rate:82'],
    				$rates['flat_rate:83'],
    			    $rates['flat_rate:84'],
    			    $rates['flat_rate:85'],
    			    $rates['flat_rate:86'],
    			    $rates['flat_rate:87'] );
         }
    	
    	
         return $rates;
        
    }
    
    1. Hey Philippe, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  15. Hello, thank you for this code. Really useful. Is it possible to make it taxable?

    Thank you in ahead!

    1. You can do that from the shipping rate settings I believe

  16. Hello, thank you for the amazing code! It’s working well for me with three shipping options, however, if the customer updates the quantity (and therefore moves to the next threshold) directly on the “cart” page, it displays all shipping options. Any idea why this would be happening? Thanks so much!

    1. Hello Kyle, I just tested this again with Storefront theme and it works perfectly. Maybe your theme (or another plugin) is messing/conflicting with my snippet?

      To troubleshoot, disable all plugins but WooCommerce and also switch temporarily to “Twentyseventeen” theme (load the snippet there in functions.php) – does it work? If yes, you have a problem with your current theme or one of the plugins.

      Hope this helps!

      R

  17. LOL – I am not adding any value here, but I was impressed by the fact that you responded to everyone who left a message! That is excellent customer interaction!

    1. Ah, thank you!

  18. Hi Rodolfo,

    My product prices are priced offering Free shipping from zones 1-4. When a customer buys a product and the postcode recognises this as Zone 5 or above the product price needs to increase by Β£15 per shipment if the customer orders more than 1. Is there a way where I can charge per shipment? I have tried applying “Flat Rate” but the shopping cart only recognizes this as one chargeable item. Is there something you can suggest that will do that for my customers or a plugin?

    Currently I’m working on my woocommerce website so it’s not live yet.

    1. Hello Jay, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  19. Hi Rodolfo and thank you so much in advance for your suggestion.
    I would like to set up extra fee only for Cash Payment past package received when order is up to 25 €.
    Can you help me ?

    thanks

    1. Hello Roberto, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  20. Hi this snippet works perfectly on the cart page but for some reason not calculating correctly on the checkout page, any ideas?

    1. Hello Jon, thanks so much for your comment! I just retested this on the latest version of WooCommerce and it still works. Unfortunately this looks like custom troubleshooting work and I cannot help here via the blog comments. Thanks a lot for your understanding! ~

  21. Great article. I tried this out but it still shows all the choices instead of just the one for the correct range. Does this work with other extensions also installed like the UPS and USPS ones from WooCommerce?

        $threshold1 = 24.99;
        $threshold2 = 34.99;
        $threshold3 = 49.99;
        $threshold4 = 79.99;
         
        if ( WC()->cart->subtotal <= $threshold1 ) {
            unset( $rates['flat_rate:19'], $rates['flat_rate:20'], $rates['flat_rate:21'], $rates['flat_rate:22'] );
        } elseif ( WC()->cart->subtotal <= $threshold2 ) {
            unset( $rates['flat_rate:18'], $rates['flat_rate:20'], $rates['flat_rate:21'], $rates['flat_rate:22'] );
        } elseif ( WC()->cart->subtotal <= $threshold3 ) {
            unset( $rates['flat_rate:18'], $rates['flat_rate:19'], $rates['flat_rate:21'], $rates['flat_rate:22'] );
        } elseif ( WC()->cart->subtotal <= $threshold4 ) {
            unset( $rates['flat_rate:18'], $rates['flat_rate:19'], $rates['flat_rate:20'], $rates['flat_rate:22'] );
        } else {
            unset( $rates['flat_rate:18'], $rates['flat_rate:19'], $rates['flat_rate:20'], $rates['flat_rate:21'] );		
        }
       
        return $rates;
    
    1. Hey Patrick! Did you empty the Cart before re-testing? Also, it depends on how UPS / USPS are coded, I don’t think they’re shipping rates are called “flat_rate:18” – they’re possibly something else.

    2. I have similar code with the same problem – but only on the 3rd shipping rate.

      function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
        $threshold = 50;
        $threshold2 = 150;
        $threshold3 = 250;
      	
      	if ( WC()->cart->subtotal <= $threshold ) { 
              if ( isset( $rates['flat_rate:2'] ) ) unset( $rates['flat_rate:3'], $rates['flat_rate:2'] );
          }
          elseif ( WC()->cart->subtotal <= $threshold2  ){
              if ( isset( $rates['flat_rate:2'] ) ) unset( $rates['flat_rate:3'], $rates['flat_rate:1'] );
          }
          elseif ( WC()->cart->subtotal <= $threshold3  ){
              if ( isset( $rates['flat_rate:3'] ) ) unset( $rates['flat_rate:1'], $rates['flat_rate:2'] );
          } else {
              if ( isset( $rates['free_shipping:4'] ) ) unset( $rates['flat_rate:1'], $rates['flat_rate:2'] );   
          }
        return $rates;
      }
      
      1. Hello Jessica, thanks for your comment! I think you have an issue in the first IF πŸ™‚

  22. How Can I Write this in code? I tried but it show wrongly.

    I have THREE
    $65 Above – FREE SHIPPING
    33 Above – $8
    0 to 32 – $15

    1. Hello Vir, 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

  23. I’m struggling with shipping fees right now. I already have states and cities enabled, the problem now is: how to add cities into the calculation. I mean, if a customer is buying from city X (state A) fee is going to be $5, but if he purchases from city Y ( State A), fee would be $9. Do you have any idea on how to do it?

    1. Hello Yara, 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

  24. Here is the code I added for three different shipping options based on quantity in the cart:

    
    // Change shipping based on quantity purchased.
    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 10, 2 );
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
    $threshold1 = 2; 
    $threshold2 = 3;
    if ( WC()->cart->get_cart_contents_count() < $threshold1 ) {
    unset( $rates['flat_rate:6'], $rates['flat_rate:8'] );
    } elseif ( WC()->cart->get_cart_contents_count() < $threshold2 ){
    unset( $rates['flat_rate:1'], $rates['flat_rate:8'] ); 
    } else {
    unset( $rates['flat_rate:1'], $rates['flat_rate:6'] );
    } 
    return $rates; 
    }
    
    

    I made this tutorial: https://www.easywebdesigntutorials.com/adjust-shipping-price-when-quantity-changes/

    1. Excellent, thanks Paal!

  25. Hi there, When I post the php code for this the latest version of WordPress rejects it with multiple ‘Unexpected Token’ errors. Ive double checked all the ‘ and , punctuation and it seems fine.
    Can anyone suggest anything that may be causing this please?

    Here is a screengrab of the errors: https://www.dropbox.com/s/el65759iea14zqh/Unexpected%20Token%20errors.png?dl=0

    Thanks in advance! πŸ™‚

    1. Sorry, I was putting the code into the css, I’ve tried it in the functions and now I get:

      Your PHP code changes were rolled back due to an error on line 28 of file wp-content/themes/uk-cbd-oil/functions.php. Please fix and try saving again.
      syntax error, unexpected ‘add_filter’ (T_STRING)

      Here is a screengrab again πŸ™‚
      https://www.dropbox.com/s/fc5ihk2x9qidugw/string_error.png?dl=0

      1. Hey Brian, that’s the weirdest PHP error I’ve ever seen πŸ™‚ Do you have this at the beginning of the file:

        <?php
        
  26. Rodolfo,
    Very helpful snippet and I almost have it working. I have two levels; less than $100, less than $200 then anything over $200 is free shipping. Shipping costs display properly until I exceed $200 in my cart total then both the Free Shipping option and Less than $200 option appears. How do I get rid of the Less than $200 option?
    Thank you.

  27. I’m trying to do something a bit more advanced because my client has three different flat rate tiers as well as two free shipping tiers. Idea is when you hit $100, the free shipping should trigger but also so should a flat rate tier for expedited shipping and the first two flat rate tiers go away. This isn’t working for me, but am I at least in the right ballpark?

    /**
    * @snippet Tiered Shipping Rates | WooCommerce
    * @how-to Get CustomizeWoo.com FREE
    * @sourcecode https://businessbloomer.com/?p=21425
    * @author Rodolfo Melogli
    * @testedwith WooCommerce 2.6.8, WordPress 4.7
    */
     
    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 5, 2 );
       
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
      $threshold = 100;
        if ( WC()->cart->subtotal < $threshold ) { 
            if ( isset( $rates['flat_rate:1'] ) ) unset( $rates['flat_rate:3'], $rates['free_shipping:1'], $rates['free_shipping:2'] );  
        } else {
            if ( isset( $rates['flat_rate:3'] ) ) unset( $rates['flat_rate:1'], $rates['flat_rate:2'] );   
        }
      return $rates;
    }
    1. Hey Adam, thanks so much for your comment! I don’t see anything wrong with this, try emptying the Cart before testing again πŸ™‚

  28. Sorry i posted on the wrong post. This code works great on woocomerce 3.2.6 and WordPress 4.9.1. Also in theme-functions.php file. i had to add some custom code of mine also but it works like a charm.
    Thank you guys, i really appreciate

  29. I was wondering if there is a way to charge 2.50 if an order is over $300 for the signature required but have customers be able to waive the signature and 2.50 charge if they don’t want to sign for it. is this possible?

    1. Hello Connor, 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

  30. Hi is there anyway to simply change the free shipping trigger to occur based on the subtotal (i.e. not effected by he use of coupons) rather than the order total?

    Thanks
    Z

    1. Zed, thanks for your comment! Yes, sure, you can do that. You just need to find the correct order total function: https://docs.woocommerce.com/wc-apidocs/class-WC_Order.html

  31. Is it possible to assign both the country and total suborder based shipping cost in this php code. Please help me

    1. Hey Gopinathan, 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

  32. Hi Rodolfo, how much would you charge for implementing this for me?

    1. Wesley, thanks so much for your comment! If you’d like to get a quote, feel free to contact me here. Take care πŸ™‚

    2. Done, thank you sir.

  33. Thank you, this was super handy! Worked absolutely perfectly!

  34. Hi Rodolfo,
    I am new to php and I’m looking to create different “thresholds” to different shipping zones. For example, shipping zone A needs a minimum spend of 100 in order to get free shipping; and shipping zone B needs to spend 200 for free shipping. How would I implement this into the code you provided? Is it even possible lol. Thank you so much!

    1. Hey Thy, thanks for your comment! Yes, of course this is possible, but I’m afraid it’s custom work and I can’t help via the blog comments. Thank you πŸ™‚

  35. Sorry, I didn’t wrap the php

    $threshold1 = 200;
    $threshold2 = 400;
    $threshold3 = 800;
    
     
    if ( WC()->cart->subtotal < $threshold1 ) {
     
    unset( $rates['flat_rate:2'], $rates['flat_rate:6'], $rates['flat_rate:7'], );
     
    } elseif ( WC()->cart->subtotal < $threshold2 ) { 
     
    unset( $rates['flat_rate:1'], $rates['flat_rate:6'], $rates['flat_rate:7'], );
     
    } elseif ( WC()->cart->subtotal < $threshold3 ) { 
     
    unset( $rates['flat_rate:1'], $rates['flat_rate:2'], $rates['flat_rate:7'], );  
     
    }
     
    return $rates;
    
    1. Hey Jamie, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom troubleshooting work and I cannot provide a complementary solution here on the blog. Thanks a lot for your understanding! ~R

    2. I understand. Thank you πŸ™‚

  36. Hello,

    Great article! Really helpful. I’m looking to implement tiered shipping options like this:

    up to Β£200.00 Β£ 10.00
    Β£200.00-Β£400.00 Β£ 20.00
    Β£400.00-Β£800.00 Β£ 30.00
    Β£800.00 and Over Β£ 60.00

    I’ve written the following, but it’s not working. Any glaring errors that you can see?

    $threshold1 = 200;
    $threshold2 = 400;
    $threshold3 = 800;

    if ( WC()->cart->subtotal cart->subtotal cart->subtotal < $threshold3 ) {

    unset( $rates['flat_rate:1'], $rates['flat_rate:2'], $rates['flat_rate:7'], );

    }

    return $rates;

    Thank you,

    Jamie

  37. Hi there,

    This code looks great to use but I was wondering what to do if I only have one flat rate meaning orders up until 250 euros require shipping costs and above it’s free.

    Thanks!

    1. Hey Delana, thanks for your comment πŸ™‚ You need no snippet for that! Just create 2 shipping methods, and set up the Free Shipping with a minimum threshold πŸ™‚

  38. I have 5 rates, ranging from $0 to > $100, do I repeat this block 5 times and just change the amount?
    [php]
    $threshold = 100;

    if ( WC()->cart->subtotal < $threshold ) {

    if ( isset( $rates['flat_rate:1'] ) ) unset( $rates['flat_rate:2'] );

    } else {

    if ( isset( $rates['flat_rate:2'] ) ) unset( $rates['flat_rate:1'] );

    }

    return $rates;
    {/php]

    1. Hey Liz! No, you’d do something like this:

      $threshold1 = 20;
      $threshold2 = 40;
      // etc..
      
      if ( WC()->cart->subtotal < $threshold1 ) {
      
      unset( $rates['flat_rate:2'], $rates['flat_rate:3'], $rates['flat_rate:4'], etc... );
      
      } elseif ( WC()->cart->subtotal < $threshold2 ) { 
      
      unset( $rates['flat_rate:1'], $rates['flat_rate:3'], $rates['flat_rate:4'], etc... );
      
      } elseif ( etc... ) { 
      
      }
      
      return $rates;
      
    2. Hi Rodolfo,
      I didn’t see your response here til today when I got back to working on this. Thank you for the model of what to use!!! How do you indicate a threshold for everything above a dollar amount? Threshold 6 is for everything above $100. The other thresholds (have no idea what happened to #2) all calculate properly in the cart but once I have over $100 of products, it displays all of the price points. Site is still in progress ..

      	$threshold1 = 25;
        	$threshold3 = 50;
      	$threshold4 = 70;
      	$threshold5 = 100;
      	$threshold6 = 10000;
      // etc..
       
      if ( WC()->cart->subtotal < $threshold1 ) {
       
      unset( $rates['flat_rate:3'], $rates['flat_rate:4'], $rates['flat_rate:5'], $rates['flat_rate:6'] );
       
      } elseif ( WC()->cart->subtotal < $threshold3 ) { 
       
      unset( $rates['flat_rate:1'], $rates['flat_rate:4'], $rates['flat_rate:5'], $rates['flat_rate:6'] ); 
       
      } elseif ( WC()->cart->subtotal < $threshold4 ) { 
       
      unset( $rates['flat_rate:1'], $rates['flat_rate:3'], $rates['flat_rate:5'], $rates['flat_rate:6'] ); 
       
      } elseif ( WC()->cart->subtotal < $threshold5 ) { 
       
      unset( $rates['flat_rate:1'], $rates['flat_rate:3'], $rates['flat_rate:4'], $rates['flat_rate:6'] ); 
       
      } elseif ( WC()->cart->subtotal < $threshold6 ) { 
       
      unset( $rates['flat_rate:1'], $rates['flat_rate:3'], $rates['flat_rate:4'], $rates['flat_rate:5'] ); 
       
      }
       
      return $rates;
      
      1. Liz, in that code you have a big problem πŸ™‚

        When you check:

        if ( WC()->cart->subtotal < $threshold1 )
        

        this also triggers when:

        WC()->cart->subtotal < $threshold3
        

        So, you have to work with those ranges and make sure every elseif does not override the previous one.

        Hope this helps

  39. This is exactly the solution I was looking for but in my case I have three flat rates (No free shipping):
    Orders up to $50 in value = $10 for shipping
    Orders from $51-$100 in value = $20 for shipping
    Order above $100 in value = $30 for shipping

    Do I have to define three different threshold variables? Any guidance would be greatly appreciated.

    1. Stella, thanks for your comment and corect, you’ll need to define a second threshold and do some more work with the if>else in PHP. Good luck πŸ™‚

      1. Hi there,

        Currently I’ve got 2 Shipping Zones, one Zone for specific Post Code areas and I’ve followed the tutorial and got it working just fine.

        However, in the second Zone for everywhere else I’ve got the same shipping methods setup (but with different prices) but just not sure how to apply them to the snippet?

        1. Darren, thanks for your comment! I’m afraid it’s not 100% clear what you’re trying to achieve. Can you link to a screenshot of your settings and explain your objective again? Thank you πŸ™‚

  40. Precisely what I’ve been looking for for ages, thanks!

    Expanding on this method I was also able to unset other superfluous delivery options that had free versions of themselves over a certain amount.

    1. Brilliant, thanks for your feedback Andrew!

    2. Hi Rodolfo,

      So sorry I missed your reply back in March.

      So basically we’ve got two Shipping Zones – one for Local – Tiered Shipping which we’ve used the code you provided and that works fine – https://pasteboard.co/g432wor4e.png as you can see the shipping option shows based on price (plus a local collection option which is fine).

      We’ve got a second Shipping Zone – Rest of UK – Tiered Pricing and want to use the same code or adapt the code. At the moment this is what the checkout page looks like – https://pasteboard.co/g3WO1BxAF.png

      So you can see the customer select their shipping price, we would like the shipping to be based on their Subtotal.

      So we’d like to be able to adapt the code so that it can be used for both Shipping Zones – Local – Tiered Shipping and Rest of UK – Tiered Pricing.

      Hope that makes sense? Darren

      1. Darren, thanks so much for your comment! Yes, it makes sense and it is possible – but unfortunately this is custom work and I cannot provide a complementary solution here on the blog. Thanks a lot for your understanding! ~R

Questions? Feedback? Customization? Leave your comment now!
_____

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining the Business Bloomer Club to get quick WooCommerce support. Thank you!

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