WooCommerce: Flat Rate Calculation Based on Weight (Without a Plugin!)

We already talked about weight based shipping and in this post we found out how to charge different flat rates based on shipping weight thresholds.

But now I want to show you how you can use the default “Flat Rate” to calculate shipping costs based on cart weight, thanks to a multiplier. For example, your shipping rate might be “$5 for each Kg” – as you know the default “Flat Rate” only allows you to define one rate e.g. $10.

So, what if you want to calculate shipping charges by weight? Well, here’s a simple workaround for you.

Shipping by Weight: first of all create a new “Flat Rate” with cost = 0 and get its ID

PHP snippet: Turn Flat Rate into a Weight Multiplier Shipping Rate

Before getting into coding, a few notes first. The following snippet won’t work unless you:

  • enter weight for every product in your store
  • create a Flat Rate and get its ID (“84” in the example below)
  • define your shipping by weight formula ($5 multiplied by rounded kilos in the example below. My snippet will return $5 if cart weight is 1.4Kg, $10 if cart weight is 1.6Kg, $15 if cart weight is 3.1Kg and so on… Adjust as per your project specifications)

The following snippet might not fully work if the Flat Rate is taxable and if you have tax enabled in your store. It might need a little tweak to make it work.

Also make sure to empty your Cart before testing – every time you work with shipping rates you need to clear your “session” and emptying the Cart should trigger that automatically.


/**
 * @snippet       Flat Rate = Shipping by Weight
 * @how-to        Watch tutorial @ https://businessbloomer.com/?p=19055
 * @sourcecode    https://businessbloomer.com/?p=114302
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 3.5.4
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */

add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 999, 2 );
   
function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {   
  	$cart_weight = WC()->cart->cart_contents_weight;
  	if ( isset( $rates['flat_rate:84'] ) ) {
		  $rates['flat_rate:84']->cost = 5 * round ( $cart_weight ); 
	}
  	return $rates;
}

Where to add this code?

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

Does this snippet still work?

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

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

Need Help with WooCommerce?

Check out these free videos, tutorials and tips!

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

Rodolfo Melogli

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

8 thoughts on “WooCommerce: Flat Rate Calculation Based on Weight (Without a Plugin!)

  1. this code multiply amount per kg in cart

    add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 999, 2 );
        
    function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {   
         $cart_weight = WC()->cart->cart_contents_weight;
    
    	foreach($rates as $key => $rate ) {
            $rates[$key]->cost = $rates[$key]->cost * round ( $cart_weight );
        }
         return $rates;
    }
    
    1. Nice 🙂

  2. Great. It works.
    What code to add if I want that if the Cart value is over a certain value (let’s say 75 $ or EUR) it will apply a free shipping option?
    Thank you in advance.

    1. Ciao Giacomo 🙂 You can do that via the settings: https://docs.woocommerce.com/document/free-shipping

  3. How to get the weight from a group of products in a specific shipping class only? So the weight of only that products which have that one specified shipping class?

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

  4. Greetings Rodolfo!
    Great… you’re not so far from what I’m looking for 😉
    I’m looking for add a fixed amount to the shipping costs. As example, if UPS plugin (which is connected to the UPS API) return $10 for the cart, I want to be able to add $2, so $12 for the shipping cost. (or a %). The operate (for 1% more + $2) can be ShippingCost = ShippingCost*1.01 + $2.
    Maybe for the next post 🙂
    Have a good continuation
    Great posts!
    Rémi

    1. Thank you Remi!

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

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

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

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