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 weight?

Well, you can use simple PHP to accomplish lots of “advanced” shipping rules, such as shipping by weight.

As long as all your products have their weight information filled in, you can create some simple rules to conditionally hide/show certain shipping methods based on cart weight. Enjoy!

1. Shipping by Weight – Requirements

If you or your client requires shipping by weight, then you first have to make sure ALL simple products and/or single variations have a weight > 0. Pretty simple, but sometimes people ask “Why shipping by weight doesn’t work?”, and the most common mistake is that products have 0 weight!

Also, under WooCommerce > Settings > Products make sure to select the correct “Weight Unit“, another typical error people make (defaults to Kg I believe).

2. Shipping by Weight – Shipping Methods Setup

You can add unlimited Flat Rates to each Shipping Zone. Also, you can rename each flat rate to something like “Orders Below 1kg”, “Orders Above 10kg”, etc to make the checkout label a little more user-friendly.

In our example, we will setup 3 weight tiers:

  • $10 shipping for orders up to 1kg
  • $20 shipping for orders up to 5kg
  • $30 shipping for orders above 5kg

And here is how to set the WooCommerce shipping methods:

  1. Flat Rate #1 > rename to “Orders Below 1kg” and assign cost = $10
  2. Flat Rate #2 > rename to “Orders Below 5kg” and assign cost = $20
  3. Flat Rate #3 > rename to “Orders Above 5kg” and assign cost = $30

Your final result for the specific zone (I called it “USA – Shipping by Weight”) will look like this:

WooCommerce Shipping by Weight (Shipping Zone Setup)
WooCommerce Shipping by Weight (Shipping Zone Setup)

3. Shipping by Weight – PHP Snippet

Now we need to “tell” WooCommerce that, based on the cart weight, a Flat Rate should be used instead of another. Only in this way we can show the correct flat rate to the end user.

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

In my example above, I have the following rate IDs:

  1. Flat Rate #1 > flat_rate:5
  2. Flat Rate #2 > flat_rate:6
  3. Flat Rate #3 > flat_rate:8

Second, let’s code! We’ll need to “unset” rates based on the total weight, so in total we’ll need 3 conditions: when weight is below 1 (kg), below 5 (kg) and above 5.

/**
 * @snippet       Shipping by Weight | WooCommerce
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 8
 * @community     https://businessbloomer.com/club/
 */
 
add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 9999, 2 );
   
function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
    
     if ( WC()->cart->get_cart_contents_weight() < 1 ) {
      
         if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:6'], $rates['flat_rate:8'] );
      
     } elseif ( WC()->cart->get_cart_contents_weight() < 5 ) {
      
         if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:5'], $rates['flat_rate:8'] );
      
     } else {
      
         if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:5'], $rates['flat_rate:6'] );
      
     }
   
     return $rates;
   
}

And here is the proof:

WooCommerce: Shipping by Weight Demonstration
WooCommerce: Shipping by Weight Demonstration

Mini-Plugin: Business Bloomer WooCommerce Shipping by Weight

You don’t feel confident with coding? You don’t want to purchase yet another bloated, expensive plugin? Great!

Business Bloomer WooCommerce Shipping by Weight Mini-Plugin comes without the usual WordPress plugin hassles. One feature. Lifetime license. No annoying subscriptions. 1 plugin file. A few lines of code. No banners. No up-sells. No WordPress notifications. Use it on as many websites as you like. Lifetime support. 1-page documentation. Super simple settings.

Speaking of which, here are the settings:


As you can see the plugin is straight forward. Install it, set up weight restrictions for each/all shipping methods, and conditionally show shipping rates based on the total cart weight. Simple!

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: How to Fix the “Cart is Empty” Issue
    For some reason, sometimes you add products to cart but the cart page stays empty (even if you can clearly see the cart widget has products in it for example). But don’t worry – it may just be a simple cache issue (and if you don’t know what cache is that’s no problem either) or […]
  • WooCommerce: “You Only Need $$$ to Get Free Shipping!” @ 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. Here’s how we show a simple message on the […]
  • WooCommerce: Cart and Checkout on the Same Page
    This is your ultimate guide – complete with shortcodes, snippets and workarounds – to completely skip the Cart page and have both cart table and checkout form on the same (Checkout) page. But first… why’d you want to do this? Well, if you sell high ticket products (i.e. on average, you sell no more than […]
  • 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: Display Total Discount / Savings @ Cart & Checkout
    If you love Ecommerce as much as I do, and are passionate about Sales Conversion Rate and reducing Shopping Cart Abandonment, today’s snippet will come in handy. Besides, this is officially the first guest blog on Business Bloomer (have ideas? Send me your proposal here)… so let me officially introduce you to today’s author: Jamie […]

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

163 thoughts on “WooCommerce: Weight-Based Shipping Methods

  1. Thanks Rodolfo for the tutorial, it has helped me narrow down my challenge to a certain level.

    I’m now left with assigning a rate by location for range of products. Do you have any tutorial on this?

    Thanks

    1. Thank you! I don’t think so, sorry.

  2. Hello Boss!
    I have a snippets code that works pretty much fine
    The code is about adding extra fees according to the weight of the product

    add_action( 'woocommerce_cart_calculate_fees', 'new_price', 30, 1 );
    function new_price( $cart ) {
        $product_weight = $cart->get_cart_contents_weight();
        $fee = 0; // when the weight is <= 11 kg
    
        // Adding 50 for each extra 1kg when the weight is above 11kg 
        if( $product_weight > 11 ){
            for( $i = 11; $i < $product_weight; $i += 1 ){
                $fee += 50;
            }
        }
        // The Final price
        $cart->add_fee( __( "Extra fees" ), $fee, false );
    }
    

    My Problem is when a client chose a local pickup I don’t want this calculations I mean why does he need to pay extra fees! because this code is always running in all cases

    I spent 3 days in this problem (I’am a newbie BTW) Iam looking for something Like

    if (! local_pickup is selected) {
    // execute the above code
    }
    

    Thanks in Advance

    1. Hi Fahem 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!

  3. If I set up my shipping to go based off the weight, does that mean I need to remove the shipping class costs I had set up?

  4. Hello! Just wondering..is there a way to do this using shipping classes instead of shipping methods? When i initially started setting up my shipping I added 3 shipping zones (domestic, europe, and everywhere else) and multiple shipping classes depending on size/weight of item (like you did, i had for example “parcels up to 250g”, “parcels up to 1kg”, etc). To the shipping zones i added 2 shipping methods (for domestic i had “domestic shipping” and “local pickup”, for the other two i had “international shipping” and “shipping upgrade”, which is something I’d like to keep), and gave prices to the shipping classes in each shipping zone. It seemed like a good way to do it, because it saved me the time of adding multiple shipping rates manually for each shipping zone. Now I’m not sure if i should scrap all that and try your method, as obviously i’d like to charge by weight instead of per item. meh!

    1. Nevermind, the flexible shipping plugin works much easier for me as I’m a newbie 🙂

  5. Hi Rodolfo!

    Adding the code everything works fine except for the free shipping which is kind of overridden by the wieght based one, I tried to wrap everything in one if with the condition: if subtotal price it’s less than X then do weight based else unset the flat rates. Here’s the following code, could you tell what am I doing wrong?

    add_filter( 'woocommerce_package_rates', 'carmine_weight_based', 9999, 2 );
        
    function carmine_weight_based( $rates, $package ) {
    	$subtotal = WC()->cart->get_cart_subtotal();
      if( $subtotal < 99 ){
         
         if ( WC()->cart->get_cart_contents_weight() < 30 ) {
           
             if ( isset( $rates['flat_rate:1'] ) ){
    
              unset( $rates['flat_rate:5'], $rates['free_shipping:2'] );
             } 
           
         } elseif ( WC()->cart->get_cart_contents_weight() > 31 ) {
           
             if ( isset( $rates['flat_rate:5'] ) ) {
    
              unset( $rates['flat_rate:1'], $rates['free_shipping:2'] );
             } 
           
         }
      } else {
          unset( $rates['flat_rate:1'], $rates['flat_rate:5'] );
        }
         return $rates;  
    }
    
    1. I also tried this way and many others but I can’t figure it out

      add_filter( 'woocommerce_package_rates', 'carmine_weight_based', 9999, 2 );
          
      function carmine_weight_based( $rates, $package ) {
      	$subtotal = WC()->cart->get_cart_subtotal();
           
           if ( WC()->cart->get_cart_contents_weight() < 30 ) {
             
               if ( isset( $rates['flat_rate:1'] ) ){
      
                unset( $rates['flat_rate:5'], $rates['free_shipping:2'] );
               } 
             
           } elseif ( WC()->cart->get_cart_contents_weight() > 31 ) {
             
               if ( isset( $rates['flat_rate:5'] ) ) {
      
                unset( $rates['flat_rate:1'], $rates['free_shipping:2'] );
               } 
             
           } elseif( WC()->cart->get_cart_subtotal() > 99) {
      		 if ( isset( $rates['free_shipping:2'] ) ) {
      
                unset( $rates['flat_rate:1'], $rates['flat_rate:5'] );
               } 
      	 }
       
           return $rates;  
      }
      

      Grazie in anticipo! (anche per il servizio che offri con queto sito, veramente una manna!)

      1. Ciao Carmine, which part of the snippet doesn’t work?

  6. I got this working really well for one shipping zone but it’s not clear how I add code to allow for a second or even third shipping zone?

    What is it that identifies the rules for each addional zone?

    1. A different zone has different rate IDs. All you need is adding more if/else to the code

      1. Thanks for the code. I’ve got it working great for 5 different weight categories in one country but I have shipping rates for 3 other countries too. How do I get it to charge £10 postage for a 1k parcel in the UK, $15 for the same parcel shipping to the US and 12euro for France?

        Any pointers?

        1. Hello Tom 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!

  7. Hey, you know what? You are awesome, really, seriously! I looked out so much from your site and really helpful man, thanks a lot!

    But, just a bit confusing for this :

    Flat Rate #1 > rename to “Orders Below 1kg” and assign cost = $10
    Flat Rate #2 > rename to “Orders Below 5kg” and assign cost = $20
    Flat Rate #3 > rename to “Orders Above 5kg” and assign cost = $30

    Which one is your rate:5, rate:6, rate:8?
    When order below 1kg, which rate I need to show and which rate I need to hide?

    I’m trying to follow the example but blank which one for which.
    Maybe anyone can help me clear it out?

    Much appreciate it!
    Thanks!

    1. You’re right – I added a paragraph to section #3. Let me know

  8. Maybe I solved it

     if (( WC()->cart->get_cart_contents_weight() < 3) && ( WC()->cart->get_subtotal() < 70)) { 

    Thank you

    1. Cool

  9. Hi Rodolfo,
    I have a question for you.
    is possible insert free shipping for order >3kg or 70 euro?
    This is my code

    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 9999, 2 );
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
       if (( WC()->cart->get_cart_contents_weight() < 3) || ( WC()->cart->get_cart_total() < 70)) {
             if ( isset( $rates['flat_rate:16'] ) ) unset( $rates['flat_rate:19'] ) ; //shipping 11 euro
         } else {
             if ( isset( $rates['flat_rate:19'] ) ) unset( $rates['flat_rate:16'] ); // free shipping
           }
         return $rates;
       
    }
    

    Thank you!

  10. what is the problem in this code

    1. add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 9999, 2 );
          
      function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
      	$cart_weight = WC()-&gt;cart-&gt;cart_contents_weight;
           
      		if ( ($cart_weight  3) ) {
      			$rates['flat_rate:1']-&gt;cost = $rates['flat_rate:1']-&gt;cost + 5; 
      		 } elseif ( ($cart_weight  6) ) {
      			$rates['flat_rate:1']-&gt;cost = $rates['flat_rate:1']-&gt;cost + 14; 
      		 } elseif ( ($cart_weight  10) ) {
      			$rates['flat_rate:1']-&gt;cost = $rates['flat_rate:1']-&gt;cost + 20; 
      		 } elseif  ( $cart_weight cost = $rates['flat_rate:1']-&gt;cost + 29; 
      		 } else {
      			$rates['flat_rate:1']-&gt;cost = $rates['flat_rate:1']-&gt;cost + 0; 
      		 }
           return $rates;
      }
      
      1. This, and the following ones too:

        $cart_weight  3
  11. Hello Rodolfo,
    thank you for your code.
    Can you please specify IDs for your shipping methods in the example. You have IDs 5, 6 and 8, but I’m not sure to which method each one belongs.
    Thank you in advance.
    BR
    Ivana

    1. And I have one additional question, I have different shipping zones and shipping methods by weight in each one. Your code works for the first shipping zone, but for other ones it doesn’t work. Can you help me with that? How can I differentiate your code for shipping zones? Thank you very much.

      1. Ivana, 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. Hello Rodolfo, thanks for this it works. But I have a different scope… I have 4 different shipping cost for 2 different region and for 2 different weights as follow:

    Say I have mainland town and outskirt town
    Every Item that is below 5kg in “Mainland” is billed $2 for delivery while items above 5kg are billed $4. Items for “Outskirt” under 5kg are billed $4 while over 5kg is billed $6.
    Mainland 5 =$4
    Outskirt 5 =$6
    How best can I achieve this in way that “Each Item Is Billed Independently. So if there is 4 items of 4kg for mainland the shipping cost should be $8 and if there is are 2 items above 5kg and 2 items below 5kg we should have a shipping cost of $12.
    I appreciate your time.

    1. Hi Vincent, 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!

      1. HI Rodoflo! First of all amazing blog! Ii has been very helpful with a couple of codes for woocommerce. I use this code and has been working perfeclty but now i have to put a local pickup, and dont know if is something related to your code, but if i add local pickup option it doesnt show, but if i rearrange on woocommerce the order of the delivery zones, it only works the first one.

        1. Gerardo, 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!

  13. Thank you Rodolfo for the snippet. Great help. I tweaked it further to implement rate increments per 0.5kg. One newbie question though. Will the names “flat_rate:5”, “flat_rate:6”.. etc stay as they are even when WooCommerce updates their plugin?

    1. Yes, they’ll stay, they’re saved in the DB

      1. Thank You. 🙂

  14. Thanks a lot!
    Your code works great!

    Best of luck!

    1. Cheers!

  15. ???? what is the flat rate 5 and where does that come from and what do i need to change in the flat rates? not clearly explained at all! i can find the id for shipping rates and the code works no errors but code does not work because not clear what i need to change so as it stands all 3 shipping options show at checkout!

  16. It was a great help, working like a charm.
    However, I’d like to display 2 flat rates, like 1 is a flat rate and the other is based on the product weight (using this snippet) ?

    Thanks,

    1. Hi Azhar, 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!

  17. Hi,
    Thank you for the code. It works well but the issue is if 2 items are added it shows only one shipping cost while it should be adding shipping costs.
    For example,
    Item A =10kg
    Item B = 10kg
    Shipping cost for 10kg is €5
    Total Shipping cost should return €5+€5=€10 but shows only €5.

    Please help.

    Thank you.

    1. Sure both products have a weight entered in their settings?

  18. Hi, thank you Rodolfo. Works great. Thank you

    1. Great!

  19. Hi!
    I have a multivendor marketplace (DOKAN) and each store sets their own shipping costs. I have a couple of stores that wish to set their shipping costs based on weight while others stillw ant to set flat rates. Is it possible to use your code for weight and still be able to use the normal flat rate?

    1. Hi Pilar, 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 Rodolfo, me again! Somehow it didn’t work before but now it does aha! Thank you for all the wonderful resources 🙂

    1. Excellent!

  21. Hi Rodolfo, thank you so much for this code! I would like to ask: what should I change in the code so that it’s a weight range. Eg. 0g – 100g, 101g – 200g, 201g – 300g etc? Cause I tried the code and because >100g is also >200g and >300g. So in the end, the shipping options all show up. I would only like for 1 option based on weight tier. Thank you 🙂

  22. Hello.
    I just used your snippet in a WooCommerce e-shop (still in development) and worked smoothly.
    (A different one from what I inserted below…).

    Thanks a lot

    1. Brilliant!

  23. Hi,
    Thanks for your code snippet, I just use the code snippet in my site and it works.
    This code is working nicely for only 1 quantity of product. Whenever I increase the amount of product, all other shipping methods start showing up there.
    So my question is, how can I use this code to work with any number of product quantity out there?

    1. Not possible unless there is a bug in your site already. My snippet calculates the total weight of the cart, so if you increase the quantity the weight will increase too

  24. This is such a useful snippet and with a bit of PHP you can extend it to do all sorts of cool things and avoid all those nasty shipping plugins!

    Thank you !

    1. Awesome!

  25. Is it possible to alter shipping classes using weight instead of the rates themselves? I have had success using classes to identify the right flat rate based on size of box. So, for instance certain larger items have a shipping class that demands a larger box. This works often but if a customer has a large order (usually large enough would cross a weight threshhold), I’d like the total weight to dictate a new or greater shipping class to override the cart option. Is that at all similar enough to terms used in your coding for the weight example in this thread?

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

  26. It works perfectly even with the appropriate customizations based on own weight ranges. Great job, thanks!

    1. Excellent!

  27. Hi Rodolfo, great post how would you set up a scenario like this:

    I live in Mexico and I have a client that has his store in Mexico City but he wants to offer shipping to other states in mexico but he has heavy products so in my opinion the calculation for the shipping has to be based on the zip code + weight of product, how can I do something like this? thanks buddy

    1. Hola Jorge, 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!

  28. Is there a way to remove an distinct amount of weight from cart?
    I have a category has to have only shipping costs when it’s sum of weight is over 500, when it’s less I could just remove that exact amount from cart.

    1. Ace, 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!

  29. Struggling to add the below, nothing happens and ive checked all the KG stuff you mention, anything wrong with the code below?

    /**
     * @snippet       Shipping by Weight | WooCommerce
     * @how-to        Get CustomizeWoo.com FREE
     * @sourcecode    https://businessbloomer.com/?p=21432
     * @author        Rodolfo Melogli
     * @compatible    WooCommerce 3.5.4
     * @community     https://businessbloomer.com/club/
     */
     
    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 9999, 2 );
       
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
        
         if ( WC()->cart->cart_contents_weight < 0.99 ) {
          
             if ( isset( $rates['shipping_method_0_flat_rate18'] ) ) unset( $rates['shipping_method_0_flat_rate19'], $rates['shipping_method_0_flat_rate20'] );
          
       } elseif ( WC()->cart->cart_contents_weight < 1.99 ) {
          
          if ( isset( $rates['shipping_method_0_flat_rate17'] ) ) unset( $rates['shipping_method_0_flat_rate19'], $rates['shipping_method_0_flat_rate20'] );
    		 
    		 } elseif ( WC()->cart->cart_contents_weight < 2.99 ) {
          
          if ( isset( $rates['shipping_method_0_flat_rate17'] ) ) unset( $rates['shipping_method_0_flat_rate18'], $rates['shipping_method_0_flat_rate20'] );
          
       } else {
          
                if ( isset( $rates['shipping_method_0_flat_rate17'] ) ) unset( $rates['shipping_method_0_flat_rate18'], $rates['shipping_method_0_flat_rate19'] );
          
       }
       
      return $rates;
       
    }
    1. Hi KC, I think your “shipping_method_0_flat_rate18” look weird and maybe they’re all wrong. Look at my snippet again and try to fix that 🙂

  30. Thanks for the tutorial Rodolfo! It works perfectly. Just wondering whether this could work with the Woocommerce Free Shipping feature (Based on minimum spend or coupon code). At the moment, if a customer puts in a free shipping coupon code or spends over $100, two radio button options appear, one for free shipping and another for the weight based shipping price.

    Thanks so much!

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

  31. I have a question concerning this…
    if I have UPS configured for EVERYTHING in the shop – and its working – reaches out to UPS and gets the current rate, etc, etc.

    BUT… the limit to weight is UPS based! and the lowest they have is 2lbs I believe….

    anyway I have a product here that is .5OZ and the store uses UPS and the default – that amount to a $14 shipping fee for i item weighing .5oz (not good)

    can this be configured to handle two rates only:

     if ( WC()->cart->cart_contents_weight < 1 ) {
          
             if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:6'], $rates['flat_rate:UPS'] ); 

    Dont know the right syntax… sorry

    Am I as clear as mud… 🙁

    1. Roberta, 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!

  32. Hi Rodolfo, love it. Works perfectly for me.

    I’m not great at PHP and was wondering if there is a nicer way to do it for multiple shipping zones? I have created different functions for each but it seems like an inelegant solution.

    Thanks,
    Ben

    1. Hello Ben, thanks so much for your comment! Yes, this is definitely possible, but if it works for you… being elegant won’t make much difference 🙂

  33. Many thanks Rodolfo!
    Your invaluable snippets always save me so much time and stress.
    Kind regards

    1. Thanks!

  34. Thank you so much for your tutorials. I am sure I will be digging through the rest of your site to learn other tricks to keep my WP sites lean and solve things using code rather than plugins where possible.

    I may be over thinking this but I am unclear on adding new options as to what each of the steps in the line below is:
    if ( isset( $rates[‘flat_rate:5’] ) ) unset( $rates[‘flat_rate:6’], $rates[‘flat_rate:8’] );

    How do you determine what rate to check for isset?
    How does that affect the unset rate?
    Final option ($rates[‘flat_rate:8’] – is this the rate you WANT for the if clause?

    If there is another tutorial that defines this more I’d appreciate if you could point me in that direction?

    Thanks again! Great site and I will be looking more thoroughly through it.

    – Greg

    1. Hi Greg, isset rate looks at a rate present in the Cart. The unset part is the rates you want to hide (so you leave one available only). Hope this helps

  35. Hello Rudolfo
    Very interesting. What if i want to apply different shipping costs for each product? Let’s say one product cost 60$ for shipping and another cost 160$ ?

    1. Hi there – you’d use “shipping classes” e.g. https://businessbloomer.com/assign-free-shipping-single-woocommerce-product/

  36. Hi, your code works, but it still allows the customer to choose which shipping method is available. What I get on checkout is radio buttons with the 3 options: orders below 3kg, orders below 6kg and orders below 11kg. I don’t want them to choose which one they use

    1. Hello Stephanie 🙂 So, there must be something wrong in your code or in your products weight, as this is not happening on my end. Let me know!

  37. Hey Rodolfo,

    Thanks for the tutorial, I managed to set it up at my shop. Just wondering if there is anyway to make sure the “Shipping class costs” still works if there is only a specific item in the cart. For example, I have one item in my shop which I want to provide for free but costs $1 to post (with a limit of 2 or 3 items for the $1 postage cost). Thanks, Jen

    1. Hello Jen, 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. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R

    2. Thanks for your response. I will try something else, can you help if I want there to be three values one for less than 100g and then from under 1 kg and then 3kg and over.

      1. Jen:

        if ( WC()->cart->cart_contents_weight < 0.1 ) {
        // --
        } elseif ( WC()->cart->cart_contents_weight < 1 ) {
        // --
        } else {
        // --
        }
        
  38. Hello Rodolfo,

    First I want to say I really enjoy reading your tutorials. It has been much help to me many many times 🙂

    This post I also going to use but I got a question regarding this post.
    Is this also possible with the dimensions of a product? A friend of mine has a shop with banisters and the lenght of this product can vary from 1 meter to 4 meters. So when somebody orders a banister of 4 meters the shipping costs should be higher because they have to deliver it with a bigger truck.

    I tried to combine to tutorials of you. This one and
    https://businessbloomer.com/woocommerce-display-product-height-length-width-shop-page/

    but no luck so far. I tried it like this:

    /**
     * @snippet       Shipping by Weight | WooCommerce
     * @how-to        Get CustomizeWoo.com FREE
     * @sourcecode    https://businessbloomer.com/?p=21432
     * @author        Rodolfo Melogli
     * @compatible    WooCommerce 3.5.4
     * @community     https://businessbloomer.com/club/
     */
     
    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 9999, 2 );
       
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
    	global $product;
    	$dimensions = $product->get_dimensions();
    
         
        if ( $product->get_length() < 2000 ) {
          
            if ( isset( $rates['flat_rate:1'] ) ) unset( $rates['flat_rate:5'], $rates['flat_rate:6'] );
           
        } elseif ( $product->get_length() > 2000 ) {
           
            if ( isset( $rates['flat_rate:1'] ) ) unset( $rates['flat_rate:6'], $rates['flat_rate:5'] );
           
        } else {
           
            if ( isset( $rates['flat_rate:1'] ) ) unset( $rates['flat_rate:1'], $rates['flat_rate:1'] );
           
        }
       
      return $rates;
    	
       
    }
    

    Got an idea or is this not possible at all?

    Once again, love you work and looking forward to new tutorials:)

    Kind regards.

    1. Hey Joep, 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. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R

  39. Hi!

    Can it be combined with the WC built-in free shipping above a certain order total?
    First, I’d like the code to check if the order total is above like $50, then run this weight check.
    Could you please help with this?

    1. Hello Anna, 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. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R

  40. Thanks Rodolfo,
    WOW, Its work great for me, just tweak little more and Limitize my Shipment Charges with 3 catagories
    1. 150g to 500g, 2. 501g to 1Kg, 3. 1Kg to 3Kg+

    Really you are a amazing man, i am really grateful to you for this great help. i have completed my First WooCommerce project with the help of your Custom Code.
    Love you and Respectful to you.
    Kind Regards,
    Aqeel

    1. Thank you 🙂

  41. Thanks for sharing. Is there any way to show the weight of the product? You in the example have written in red Weight 34 Kilos.

    Is it possible to show the weight of each item?

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

  42. Hi Rodolfo,
    thank you for your plugin, is it still working? I have tried to use it in my website, but I cannot see any change on website, I can see there all 3 options, I put it at the end of functions.php

    Here is the code I adjusted to my site:

     
    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 10, 2 );
       
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
         
        if ( WC()->cart->cart_contents_weight < 1000 ) {
          
            if ( isset( $rates['flat_rate:11'] ) ) unset( $rates['flat_rate:7'], $rates['flat_rate:12'] );
           
        } elseif ( WC()->cart->cart_contents_weight < 100 ) {
           
            if ( isset( $rates['flat_rate:7'] ) ) unset( $rates['flat_rate:11'], $rates['flat_rate:12'] );
           
        } else {
           
            if ( isset( $rates['flat_rate:12'] ) ) unset( $rates['flat_rate:7'], $rates['flat_rate:11'] );
           
        }
       
      return $rates;
       
    }
    

    I am a WP beginner, so maybe I have done something wrong in some unexpected way:)

    Thank you

    1. Hey Petra, thanks for your comment! 100 is also < than 1000 so the first two statements will mess with each other - you need to edit those calls and make sure they target different weight ranges. Hope this helps 🙂

  43. Where is the mistake?

    add_filter( 'woocommerce_package_rates', 'tariffa_spedizione_a_peso', 10, 2 );
       
    function tariffa_spedizione_a_peso( $rates, $package ) {
         
        if ( WC()->cart->cart_contents_weight < 3 ) {
          
            if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:6'], $rates['flat_rate:7'] );
           
        } elseif ( WC()->cart->cart_contents_weight < 8 ) {
           
            if ( isset( $rates['flat_rate:6'] ) ) unset( $rates['flat_rate:5'], $rates['flat_rate:7'] );
           
        } else {
           
            if ( isset( $rates['flat_rate:7'] ) ) unset( $rates['flat_rate:5'], $rates['flat_rate:6'] );
           
        }
       
      return $rates;
       
    }
    
    1. Hey there 🙂 It’s in the “elseif”: “<8" can be also "<3" (first condition). You need to also add ">=3″. Hope this helps

  44. Hi,
    Great website you have here. I use it ALOT when developing custom functions 🙂
    Saves me huge amount of time.
    I was wondering if you could help me.
    Im trying to change shipping cost based on zip code “programmatically”.
    So I just have one rate called “flat_rate”
    And then I want to change it based on user input in the Zip code field.

    Ive been trying all sorts of functions from the web.
    This is what I have now that works but it does not get ZIP code input.

    add_filter( 'woocommerce_package_rates', 'custom_shipping_rate_cost_calculation', 10, 2 );
    function custom_shipping_rate_cost_calculation( $rates, $package ) {
    
    $postal_code = $package[ 'destination' ][ 'postcode' ]; // This does not work !
    
        foreach( $rates as $rate_key => $rate ) {
            if ( 'flat_rate' === $rate->method_id ){
    
                // Get rate cost and Custom cost
                $initial_cost = $rates[$rate_key]->cost;
                //$additional_cost = 10000;
    
                // Calculation
                $new_cost = $initial_cost + $postal_code;
    
                // Set Custom rate cost
                $rates[$rate_key]->cost = round($new_cost, 2);
    
                // Taxes rate cost (if enabled)
                $new_taxes = array();
                $has_taxes = false;
                foreach ( $rate->taxes as $key => $tax ){
                    if( $tax > 0 ){
                        // Calculating the tax rate unit
                        $tax_rate = $tax / $initial_cost;
                        // Calculating the new tax cost
                        $new_tax_cost = $tax_rate * $new_cost;
                        // Save the calculated new tax rate cost in the array
                        $new_taxes[$key] = round( $new_tax_cost, 2 );
                        $has_taxes = true;
                    }
                }
                // Set new tax rates cost (if enabled)
                if( $has_taxes )
                    $rate->taxes = $new_taxes;
            }
        }
    
        return $rates;
    }
    
    1. Aron, 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

  45. Thank you so much. It really helped me alot.

    1. Excellent 🙂

  46. I’m thinking about implementing this, but am also considering using the free plugin “WooCommerce Weight Based Shipping by weightbasedshipping.com”. Is your method above better because we can customize the code directly? Thanks!

    1. Hello Owen – thanks so much for your comment! My method is just “one of the methods”, so you should use the option you feel more comfortable with – there are pros and cons either way 🙂

  47. Hi,

    I am a beginner trying to set up weight based shipping fee on my website. I tried integrating some third party plugins but they were causing issues within the theme so I had to delete them. I came across your blog and have been following the steps mentioned to set up the weight based shipping fee on my website but I am encountering an issue getting the unique id. I am sharing the exact point from the blog here for your reference- “First, take a note of the unique ID of the three flat rates. They should look look something like “flat_rate:9“. For more info on how to find them, check here: https://businessbloomer.com/woocommerce-disable-free-shipping-if-cart-has-shipping-class/#woocommerce-how-to-find-shipping-method-id-woo-2-6-after-the-introduction-of-the-new-shipping-zones
    I need 3 shipping zones which I could create without any difficulty but when I am trying to inspect the check out page, I am able to get the unique id of only the first zone. How do I get the unique id of the second and third zones. Can you please help me figure this out. And in case there is a nice plugin that I could use, please share the name of that as well.

    1. Hey Mounika – thanks so much for your comment! You’re on the wrong page – you need to get the ID of the “shipping rate”, which is one of the rates that belong to a “shipping zone”. So, open the zone, and look for the IDs for each rate that belongs to that zone. Hope this helps!

  48. So I dug into it, successfully finished work on the before-mentioned mini plugin prototype for a client of mine, and while doing so, stumbled into something rather nasty: If you’re wondering why the displayed rate in the cart / checkout process might not change, NO MATTER WHAT YOU DO ..

    .. its thanks to something called “WooCommerce Shipping Rate Cache”.

    So for testing purposes, head over to the WooCommerce settings > “Checkout”, and activate the “Debug Mode”.

    But for your live site, that won’t suffice, so you might want to manually delete the transients in which the “Shipping Rate Cache” is being stored. Several articles point you towards the wp_options table, and tell you to search for ‘wc_ship*’. More correct, you have to search for ‘_transient_wc_ship* (in SQL Query terms: ‘… LIKE “%_transient_wc_ship%”). Now after finding these, you ought to delete em manually.

    A more workable solution is what a few tutorials point out: There is an option in the WooCommerce settings, located under Status > Tools, which lets you delete all or just specific transients. You’d have to always use them before doing changes to your code IF you want to see changes to the live site, but nevertheless, its easier than having to manually look up the transients and delete them in your database.

    cu, w0lf.

    1. Nice 🙂

  49. For those interested in turning this into something more complete, eg. a (very simple) plugin, that just handles the PHP part:

    The data we are using to test here is stored in the `woocommerce_shipping_zone_methods` table (instance_id = the instance). And the descriptions of the resp. shipping methods are stored in the options-table by the option_name scheme `woocommerce_flat_rate_{instance_id}_settings`. The value is a serialized associative array which might be auto-converted into an array when fetching the data using the get_option() function (if not, maybe_unserialize() should help).

    With this, one should be theoretically be able to build a semi-dynamic version of the PHP snippet, where you just have to decide for yourself what keywords / trigger words you are going to use to distinguish between lower, equal and higher weight values. The keywords themselves have to be taken from the description field, which is stored as ‘title’ in the aforementioned serialized array

    In the current example, this would be “Below ” and “Above”. So anything with “Below” in its title equals $x < $y, where $x is the current weight, and $y is our parsed-out weight value found in the description field, eg. "1kg".

    Of corpse you'd have to stick to a specific scheme when creating the shipping method descriptions, so that the later on happening parsing does work properly.

    cu, w0lf.

    1. Thanks Wolk 🙂

  50. I need different rates for different countries with shipping by weight.
    Shipping to UK has different shipping rates on weight from the shipping rate to USA.
    There is a way to do it?

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

  51. Hello,
    I’m getting the following message:
    “Unable to communicate back with site to check for fatal errors, so the PHP change was reverted. You will need to upload your PHP file change by some other means, such as by using SFTP.”

    This is the code I’m using:

    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 10, 2 );
       
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
         
        if ( WC()->cart->cart_contents_weight < 0.5 ) {
          
            if ( isset( $rates['flat_rate:7'] ) ) unset( $rates['flat_rate:9'], $rates['flat_rate:13'], $rates['flat_rate:10'] , $rates['flat_rate:11'], $rates['flat_rate:12']);
           
        } elseif ( WC()->cart->cart_contents_weight < 1 ) {
           
            if ( isset( $rates['flat_rate:9'] ) ) unset( $rates['flat_rate:7'], $rates['flat_rate:13'], $rates['flat_rate:10'] , $rates['flat_rate:11'], $rates['flat_rate:12']);
    		
    	} elseif ( WC()->cart->cart_contents_weight < 1.5 ) {
           
            if ( isset( $rates['flat_rate:13'] ) ) unset( $rates['flat_rate:7'], $rates['flat_rate:9'], $rates['flat_rate:10'] , $rates['flat_rate:11'], $rates['flat_rate:12']);
    		
    	} elseif ( WC()->cart->cart_contents_weight < 2 ) {
           
            if ( isset( $rates['flat_rate:10'] ) ) unset( $rates['flat_rate:7'], $rates['flat_rate:9'], $rates['flat_rate:13'] , $rates['flat_rate:11'], $rates['flat_rate:12']);
    		
    	} elseif ( WC()->cart->cart_contents_weight < 2.5 ) {
           
            if ( isset( $rates['flat_rate:11'] ) ) unset( $rates['flat_rate:7'], $rates['flat_rate:9'], $rates['flat_rate:13'] , $rates['flat_rate:10'], $rates['flat_rate:12']);
    	
    	} elseif ( WC()->cart->cart_contents_weight < 3 ) {
           
            if ( isset( $rates['flat_rate:12'] ) ) unset( $rates['flat_rate:7'], $rates['flat_rate:9'], $rates['flat_rate:13'] , $rates['flat_rate:10'], $rates['flat_rate:11']);
           
        } else {
           
            if ( isset( $rates['flat_rate:12'] ) ) unset( $rates['flat_rate:7'], $rates['flat_rate:9'], $rates['flat_rate:13'] , $rates['flat_rate:10'], $rates['flat_rate:11']);
           
        }
       
      return $rates;
       
    }
    

    Please help me out!

    1. Hey Gautham, thanks so much for your comment! I think the error has nothing to do with my snippet… try using FTP instead of the WordPress Editor to tweak PHP 🙂

  52. Rololfo,
    I have a shopping cart I need to do something like this for. We are in USA and ship everwhere. I need to be able to do this based on lbs (2-4lbs = $10 ship, 5-10lbs = $20 ship for USA, then 2-4lbs = $25 ship, 5-10lbs = $45 ship for Canada, 2-4lbs = $45 ship and 5-10lbs = $90 ship international etc….i will need more such as 5lbs for each as well) Is this a scenario I can use your suggestion? I did not want to try it unless you thought it is a good option for me as I need this site up within a week!

    1. Hey Tiffany, thanks so much for your comment! Yes, this is totally possible, however targeting the country on top of the weight thresholds might be a little too complex from a coding point of view. If you’re familiar with code, then it’s definitely easy to do 🙂

    2. Adding delivery country is simple, 2 extra lines of code: thanks, I started from zero and got this working first time using your snippet as a starter! I have 3 zones of which 2 (Europe, rest of World) have two rates based on a weight threshold.

      function mm_woocommerce_tiered_shipping( $rates, $package ) {
          
        $shipping_zone = WC_Shipping_Zones::get_zone_matching_package( $package );
        $zone=$shipping_zone-&gt;get_zone_name();
        $weight=WC()-&gt;cart-&gt;get_cart_contents_weight();
        
        if ($zone=='Europe') {
          if ( $weight &lt; 1 ) {
               
           if ( isset( $rates[&#039;flat_rate:5&#039;])) { 
               unset( $rates[&#039;flat_rate:5&#039;] );
           }
               
           } elseif ( $weight &lt; 5 ) {
             if ( isset( $rates[&#039;flat_rate:5&#039;])) { 
                 unset( $rates[&#039;flat_rate:5&#039;] );
             }
               
           } else {
             if ( isset( $rates[&#039;flat_rate:4&#039;])) { 
                 unset( $rates[&#039;flat_rate:4&#039;] );
             }
               
           }
             
        }   elseif ($zone==&#039;Rest of World&#039;) {
        
          if ( $weight &lt; 1 ) {
               
           if ( isset( $rates[&#039;flat_rate:7&#039;])) { 
               unset( $rates[&#039;flat_rate:7&#039;] );
           }
               
           } elseif ( $weight &lt; 5 ) {
             if ( isset( $rates[&#039;flat_rate:7&#039;])) { 
                 unset( $rates[&#039;flat_rate:7&#039;] );
             }
               
           } else {
             if ( isset( $rates[&#039;flat_rate:6&#039;])) { 
                 unset( $rates[&#039;flat_rate:6&#039;] );
             }
               
           }
             
        }       
        
        return $rates;
          
      }
      
      
  53. Thanks for this – neat and exactly what I was after (c:

    For others reading this that want to also do this by country you just have to repeat the code for each country in if tags according to each country, like this (I also had four shipping options):

    
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
        global $woocommerce;
        $shipping_zone = WC_Shipping_Zones::get_zone_matching_package( $package );
    
        $zone=$shipping_zone-&gt;get_zone_name();
        
        if ($zone == 'Europe') {
        
            if ( WC()-&gt;cart-&gt;cart_contents_weight cart-&gt;cart_contents_weight cart-&gt;cart_contents_weight cart-&gt;cart_contents_weight cart-&gt;cart_contents_weight cart-&gt;cart_contents_weight &lt; 5 ) {
           
                if ( isset( $rates[&#039;flat_rate:3&#039;] ) ) unset( $rates[&#039;flat_rate:4&#039;], $rates[&#039;flat_rate:3&#039;], $rates[&#039;flat_rate:6&#039;] );
            
            } else {
           
                if ( isset( $rates[&#039;flat_rate:3&#039;] ) ) unset( $rates[&#039;flat_rate:4&#039;], $rates[&#039;flat_rate:5&#039;], $rates[&#039;flat_rate:3&#039;] );
            }
        }
       
      return $rates;
       
    }
    
    
    1. Hi Shepira,

      could you please write it again since with all the special types (&gt, and others) it is not really clear to me?
      Thank you in advance

  54. Love what you did there. Sadly I’m one of the people who won’t be able to use this elegant solution. Like in so many such scenarios, the Americans sadly only cater for their own market. “Outside USA” doesn’t even come into play. The world is huge – which might come as a surprise. So for shipments that cross borders (and therefore cost more), it’s back to the drawing board.

  55. Working awesome without plugin. Thank you

  56. Works perfectly, thank you Rodolfo for your snippets!

  57. HI Rodolfo,

    How do i get other id for the flat_rate shipping like flat_rate:2. I got one and how do I understand what will be the others?

  58. I think there is a bug with the code.
    For example, if you set:
    1kg = $1
    2kg = $2
    3kg = $4

    If the item weighs 1kg and the customer sets the quantity to 2 then it should be 2kg and therefore = $2 but the code doesn’t do that?

    1. Hey Peter, thanks for your comment! I just tested this again on the latest version of Woo and it works perfectly, even after updating the quantity. There must be some other issue/conflict.

      To troubleshoot, 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/

      Finally, can you try switching temporarily to “Twentyseventeen” or “Storefront” theme and let me know if it works?

      Hope this helps!

      R

  59. Awesome!
    Thank you 🙂

  60. Thank you for this code snippet.
    But how can we use this code for shipping to different countries.

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

  61. Hey! Nice work! Thank you!

  62. I pasted your code exactly into the functions.php and it’s still breaking the site.
    What am I doing wrong? Can anybody help me with this?

    <?php
    //
    // Recommended way to include parent theme styles.
    //  (Please see https://codex.wordpress.org/Child_Themes#How_to_Create_a_Child_Theme)
    //  
    add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
    function theme_enqueue_styles() {
        wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
        wp_enqueue_style( 'child-style',
            get_stylesheet_directory_uri() . '/style.css',
            array('parent-style')
        );
    }
    //
    // Your code goes below
    //
    
     
    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 10, 2 );
       
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
         
        if ( WC()->cart->cart_contents_weight < 1 ) {
          
            if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:6'], $rates['flat_rate:8'] );
           
        } elseif ( WC()->cart->cart_contents_weight < 5 ) {
           
            if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:5'], $rates['flat_rate:8'] );
           
        } else {
           
            if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:5'], $rates['flat_rate:6'] );
           
        }
       
      return $rates;
       
    }
    
    1. Hey Chris, thanks so much for your comment! The snippet works on my test website, so you will need to enable WP_DEBUG to know what else is breaking your website 🙂

  63. Here`s the complete php functions file
    I`m using elegant themes divi child theme
    Keeping getting site can`t be reached

    1. Sorry here`s the complete code

      
      add_filter( 'woocommerce_package_rates', ‘funsical_woocommerce_tiered_shipping', 10, 2 );
         
      function funsical_woocommerce_tiered_shipping( $rates, $package ) {
           
          if ( WC()->cart->cart_contents_weight < 6.5 ) {
            
              if ( isset( $rates['flat_rate:13’] ) ) unset( $rates['flat_rate:14’], $rates['flat_rate:15’] );
             
          } elseif ( WC()->cart->cart_contents_weight < 12.9) {
             
              if ( isset( $rates['flat_rate:13’] ) ) unset( $rates['flat_rate:13’], $rates['flat_rate:15’] );
             
          } else {
             
              if ( isset( $rates['flat_rate:13’] ) ) unset( $rates['flat_rate:13’], $rates['flat_rate:15’] );
             
          }
         
        return $rates;
         
      }
      
      1. Christian, thanks so much for your comment! Unfortunately this is custom troubleshooting work and I cannot help here via the blog comments. Thanks a lot for your understanding! ~R

      2. @Christopher
        Have a look at your APOSTROPHE’s in use, I think you have the wrong ones in parts…. look at the last ‘ after:13
        it is different to the one in the beginning!

        if ( isset( $rates['flat_rate:13’] ) ) unset( $rates['flat_rate:13’],
        

        Paste that code into an online php checker so it can look for ‘syntax’ errors
        Hope that helps

  64. hi,
    the code is working fine, but it missed the tax calculation. Can you please explain?

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

  65. Hi I need help setting up this. I have not been able to quite understand it. I tried to do it and my website was unavailable.

    Orders Below 15.84oz: $5.00
    Orders Below 72oz: $10.00
    Orders below 144oz: $15.00
    Orders below 320oz: $20.00
    Orders over 320oz: $25.00

    /**
    * @snippet Shipping by Weight | WooCommerce
    * @how-to Get CustomizeWoo.com FREE
    * @sourcecode https://businessbloomer.com/?p=21432
    * @author Rodolfo Melogli
    * @testedwith WooCommerce 2.6.8, WordPress 4.7
    */
     
    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 10, 2 );
       
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
         
        if ( WC()->cart->cart_contents_weight < 15.84 ) {
          
            if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:6'], $rates['flat_rate:8'] );
           
        } elseif ( WC()->cart->cart_contents_weight < 72 ) {
           
            if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:5'], $rates['flat_rate:8'] );
        
        } elseif ( WC()->cart->cart_contents_weight < 144 ) {
           
            if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:5'], $rates['flat_rate:8'] );    
           
        } elseif {
           
            if ( isset( $rates['flat_rate:5'] ) ) unset( $rates['flat_rate:5'], $rates['flat_rate:6'] );
           
        }
       
      return $rates;
       
    }
    
    
    1. Hola Marcela, thanks so much for your comment! Unfortunately this is custom troubleshooting work and I cannot help here via the blog comments. Thanks a lot for your understanding! ~R

    2. Hi Marcela, try to code it according to this code. I also have 5 shipping classes and this code works for me.

      /**
      * @snippet Shipping by Weight | WooCommerce
      * @how-to Get CustomizeWoo.com FREE
      * @sourcecode https://businessbloomer.com/?p=21432
      * @author Rodolfo Melogli
      * @testedwith WooCommerce 3.2.6
      */

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

      function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {

      if ( WC()->cart->cart_contents_weight cart->cart_contents_weight cart->cart_contents_weight cart->cart_contents_weight < 30 ) {

      if ( isset( $rates['flat_rate:11'] ) ) unset( $rates['flat_rate:11'], $rates['flat_rate:12'], $rates['flat_rate:13'], $rates['flat_rate:17'] );

      } else {

      if ( isset( $rates['flat_rate:11'] ) ) unset( $rates['flat_rate:11'], $rates['flat_rate:12'], $rates['flat_rate:13'], $rates['flat_rate:16'] );

      }

      return $rates;

      }

  66. Hi I am trying to set up this in my shipping by weight. I have made the flat shipping fees but I set them up in wordpress to be onces. I need help setting up this to match my cart as in the example

  67. Code works great – we used this method for our US to Canada calculations. Not quite at the point of needing Table Rate Shipping yet even with 4500 SKUs and a huge mix of different products.

    1. Brilliant, great to know 🙂

  68. Thanks for the article, this really helps. Although, I’m a bit confused: isn’t ‘shipping classes’ meant for this? I was under the impression shipping zones is more geographical and classes is for anything else. If I’m wrong, I’d love an article explaining the difference between the 2.

    1. Hey Maarten, thanks for your comment!

      Shipping classes can be used to group products of similar type and used by some shipping methods, such as Flat Rate Shipping, to provide different rates to different classes of product.

      Source: https://docs.woocommerce.com/document/product-shipping-classes/

      So, shipping classes don’t really help with weight calculations. Does this help?

  69. Thank you soooo much!

    I was using a plugin for that, but that didn’t work out with WPML as the translations where somwhow cached because of the ID. This is really awesome as it unfolds some shipping-cost tweaking to me.

    1. Excellent 🙂 Glad it helped!

  70. Thanks so much! I set this up with all my U.S. shipping weights and it worked great.

    However…..that was for my U.S. shipping. My International shipping rates use the same weight, but different pricing. How do I add those in the php code? I set up 3 different shipping zones with the flat rate pricing. One for USA, one for Canada or Mexico and one for International (not Canada or Mexico).

    I would really appreciate your help if you can. 🙂

    Thank you!

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

  71. hi… can u share how source code to calculate each shipping by weight? i still confused about this…
    for e. g. my shipping cost 5$/kg and i need add this every 1 kilos charge 5$. and please tell me how put this code on php woocommerce thanks alot

    1. Sarah, thanks for your comment! Sorry but I can’t help you directly. Try watching https://businessbloomer.com/woocommerce-customization-hangout/ for some PHP tips

  72. Thanks a lot for your sharing. It is very useful for me without plugin.

  73. Hey,
    I have an odd question, which doesn’t quite have to do with this article, but I’ve been looking for an answer for days and this is the one thing that gets sort of close to it.
    So, I’m making a website that sells PVC banners. The product page lets you customize the size and a couple of other things, and the price changes. For that, I’ve used a plugin called Woo Price Calculator, and it works fine.
    But, of course, if the size is bigger, also is the weight and the shipping price.
    Is there a way to calculate the weight and apply the shipping prices trick from this post to it?
    Thanks.

    1. Hey Gabriele, thanks for your comment! Of course there is always a PHP way, but it would be time consuming as this is custom to your plugin. Sorry but I can’t help here in the comments 🙂

  74. Hey

    Thank you for this, it works perfectly.
    But how would I adapt this so I can add more weight bands? I would like at least another 1 option.
    Thank you.

    1. Hey Guto thanks for your comment! My snippet has 3 bands, so adding the fourth shouldn’t be a problem if you have minimal coding knowledge. Good luck 🙂

  75. Hi

    thanks for your code snippet, I just use the code snippet in one of my site and it is working.

    1. Thanks so much for your feedback Faruk!

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 *