Person using laptop on computer table

How to charge WooCommerce shipping by item

5 min read
Beka Rice

I’ve seen some variation of this question multiple times from both new and experienced WooCommerce shop owners: Can I charge shipping based on the number of items in the cart instead of just a flat fee?

Launch your business in minutes with GoDaddy Airo™

Definitely doable. The best part? You don’t even need any plugins or code snippets to do it—you can do quantity-based shipping within WooCommerce itself.

WooCommerce shipping per item

Many shop owners use the built-in WooCommerce shipping zones and rates to create their shipping fee structures. You can find these under WooCommerce > Settings > Shipping.

Notice that many of my shipping methods are flat rate methods, such as those named “Ground” or “Expedited”. By default, these charge a set rate for that zone, such as $5 per order.

However, you can do a lot more with flat rates than simple costs! This is where I encourage you to read the tooltips in WooCommerce core more frequently.

You can add advanced costs such as quantity-based costs or additional fees, to your flat rate shipping. You can use this to include the item quantity in your shipping cost formula with the [qty] shortcode:

Now, instead of charging $3 per order, I can charge $3 per item in the cart, which means that my shipping rate can adjust based on the number of items being ordered.

This lets you create WooCommerce shipping per item rather than per order with the built-in shipping tools.

Tiered WooCommerce shipping per item

Since shipping tends to bring up all sorts of questions, let’s look at a more complex example I saw in the WooCommerce community Slack recently: I need to charge shipping in multiples of two as you can get two items per container. How would I go about doing that?

This question is interesting because it sets up a tiered shipping system rather than strictly pricing per item—this needs to change shipping for every two items, not for every item.

While more complex shipping like this can’t be done with the core tools, you could create tiered shipping with the Table Rate Shipping extension for WooCommerce. This plugin lets you create rates per item count, so you could do a table of rates like this:

Item count
…and so on

The benefit here is that, based on the description in my question above, I think this is supposed to be per line item quantity (given it packs similar items in a box), which Table Rate Shipping can account for with “calculated rates per line item” as the calculation type.

This will then change the rate using your tiers for each line item’s quantity, providing the summed total as the shipping cost to the customer:

For developers: creating more WooCommerce shipping tiers

For developers, you can create even more complex shipping schemes or tiered pricing using the woocommerce_shipping_rate_cost filter. This lets you adjust the cost of any shipping method programmatically. You should be comfortable with PHP code and WordPress hooks to use the examples in this section.

Let’s take the above example for tiered pricing, but do it based on the entire cart item quantity, not per line, using this filter.

First, I’ll set up the base rates for my shipping methods. I’m going to use $3 as my per box price, and then I’ll programmatically change the box count in a code snippet.

Now, I’ll filter the method cost, multiplying this base cost by my box count. I’ll get the box count by rounding the cart item quantity divided by 2 (which should give me whole numbers always for my box count). Note that you could also use a modulus operator here to check for instances where you have no remainder for cart item qty ÷ by 2.

Notice that I’m using the instance IDs for the rates I want to use this tiered pricing for. You can get this by hovering over the link to each shipping rate and you’ll see &instance_id=number in the URL (or you can inspect the HMTL for the rate to get this).

<?php // only copy if needed!

 * Filters the shipping method cost to account for tiered quantity pricing.
 * @param float $cost the shipping method cost
 * @param \WC_Shipping_Rate $method the shipping method
 * @return float cost
function swwp_wc_shipping_cost_tiers( $cost, $method ) {

	// TODO: change the numbers in this array with your desired instance IDs
	// see if this shipping instance is one we want to modify cost for
	if ( in_array( $method->get_instance_id(), array( 22, 23 ) ) && WC()->cart ) {

		$cart_item_count = WC()->cart->get_cart_contents_count();

		// if we have items that need shipping, round the quantity / 2 to the nearest whole number
		// this produces tiered cost increases for every 2 items
		if ( $cart_item_count > 1 ) {
			$cost = round( $cart_item_count / 2 ) * $cost;

	return $cost;
add_filter( 'woocommerce_shipping_rate_cost', 'swwp_wc_shipping_cost_tiers', 10, 2 );

Now I’ve created a system in which I’ll get the total box count for all cart items, assuming any of my products fit 2 per box, and multiply that to the per box cost. If I have 2 items, this charges for one box:

While having 5 cart items charges for 3 boxes:

That’s it! There are many ways to create WooCommerce shipping per item, including using the item quantity directly, or by creating more advanced tiered rates via plugins and customization.