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

  1. Set Product Weights:
    Make sure every product (and variation) in your store has a weight value greater than 0. If the weight is missing, WooCommerce can’t calculate cart weight.
  2. 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:

  1. Go to WooCommerce → Status → Logs → Shipping Debug Mode (enable temporarily).
  2. 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.