By default, WooCommerce offers 3 built-in shipping methods: Flat Rate, Free Shipping, and Local Pickup. While these work for most stores, there is no direct option to set up weight-based shipping rates.
So, what if you want to charge different shipping costs depending on the total weight of the cart? For example:
- $10 for orders below 1kg
- $20 for orders up to 5kg
- $30 for orders above 5kg
In this tutorial, you’ll learn how to create weight-based shipping rules in WooCommerce without installing a heavy plugin. We’ll use simple PHP code + Flat Rates to achieve this.
Requirements for Weight-Based Shipping
- Set Product Weights:
Make sure every product (and variation) in your store has a weight value greater than0
. If the weight is missing, WooCommerce can’t calculate cart weight. - Check Weight Units:
Go to WooCommerce > Settings > Products and ensure you’ve selected the correct Weight Unit (e.g., kg, g, lbs). By default, WooCommerce uses kg.
Step 1: Setup Flat Rate Shipping Methods
For this example, let’s create 3 flat rates inside your desired Shipping Zone (e.g., “USA – Shipping by Weight”):
- Flat Rate #1 → Rename to “Orders Below 1kg”, Cost =
$10
- Flat Rate #2 → Rename to “Orders Up to 5kg”, Cost =
$20
- Flat Rate #3 → Rename to “Orders Above 5kg”, Cost =
$30
Your zone setup will look something like this:
USA – Shipping by Weight
Flat Rate #1 → Orders Below 1kg ($10)
Flat Rate #2 → Orders Up to 5kg ($20)
Flat Rate #3 → Orders Above 5kg ($30)
Step 2: Add PHP Snippet for Weight Logic
WooCommerce generates all shipping methods for a package. To show only the correct rate based on total cart weight, we’ll use the woocommerce_package_rates
filter.
Copy and paste this code into your child theme’s functions.php or a custom plugin:
/**
* WooCommerce Weight-Based Shipping
* Show specific flat rate based on cart weight
* Author: Your Name
* Updated: 2025
*/
add_filter( 'woocommerce_package_rates', 'custom_weight_based_shipping', 9999, 2 );
function custom_weight_based_shipping( $rates, $package ) {
// Get total cart weight
$weight = WC()->cart->get_cart_contents_weight();
// Replace with your actual Flat Rate IDs
$below_1kg = 'flat_rate:5';
$below_5kg = 'flat_rate:6';
$above_5kg = 'flat_rate:8';
if ( $weight < 1 ) {
// Show only "Orders Below 1kg"
foreach ( $rates as $rate_id => $rate ) {
if ( $rate_id !== $below_1kg ) {
unset( $rates[ $rate_id ] );
}
}
} elseif ( $weight < 5 ) {
// Show only "Orders Up to 5kg"
foreach ( $rates as $rate_id => $rate ) {
if ( $rate_id !== $below_5kg ) {
unset( $rates[ $rate_id ] );
}
}
} else {
// Show only "Orders Above 5kg"
foreach ( $rates as $rate_id => $rate ) {
if ( $rate_id !== $above_5kg ) {
unset( $rates[ $rate_id ] );
}
}
}
return $rates;
}
How to Find Flat Rate IDs
Each flat rate has a unique ID such as flat_rate:5
.
To find them:
- Go to WooCommerce → Status → Logs → Shipping Debug Mode (enable temporarily).
- Or, temporarily add
var_dump( $rates );
inside the filter and check which IDs appear.
Final Result
Now, WooCommerce will automatically show the correct shipping method based on the total cart weight:
- Cart < 1kg → $10
- Cart 1–5kg → $20
- Cart > 5kg → $30
This is a lightweight solution without needing an extra plugin.