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?
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.
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.
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 | Shipping cost |
---|---|
1 to 2 | $3 |
3 to 4 | $6 |
5 to 6 | $9 |
7 to 8 | $12 |
…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:
Table Rate Shipping can give you advanced WooCommerce tiered shipping based on item count, and other properties such as weight or price.
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).
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.
Excellent post, thank you very much for sharing. [qty] shortcode was something magical :)
Thank you Beka! you save me with this straight well explained tutorial.
nice post, thanks a lot
Which plugin would you suggest to achieve what you described here:
https://www.sellwithwp.com/how-to-charge-woocommerce-shipping-by-item/#tiered-woocommerce-shipping
I found a $99 plugin sold by Woocommerce that looks like it would work, but the cost seems excessive for such a simple set up. Looking for the most cost effective way to do it.
The best plugin I’ve found is the one linked there — WooCommerce Table Rate shipping.
Thanks, the * [qty] saved me, I didn’t know about that!
Sure thing, it’s super useful :)
I ship per item. So 1-3 items cost the same, 4-10 cost the same and so on. Most of my items are just 1 but occasionally I want to sell a bundle would count as 4-7 items. Is there a way to count the bundle as 4 items when calculating shipping?
Hey Jason, the Product Bundles plugin should handle this, as you can mark as item as “shipped individually” so it’s treated as a separate shipped item: http://cloud.skyver.ge/2a4aeb3fe243
This article was super helpful and saved me time. Thank you so very much
This was SO helpful! I was frustrated and took me just a second to fix the shipping issue once reading this article!
Glad to hear it! :)
I’m glad found your article. I didn’t know about qty code before. Thank you for sharing ;)
this is great, thanks! I’m trying to do something basic and would prefer to not use a plugin. I’m wondering if [fee] can be used with negative percentages? I’d like to ( for example ) charge $100 shipping for first item, and say $80 for each additional item. So, 20% OFF the original shipping price… Thanks!
Hey Mark, this is a table rate rather than a negative fee since it’s based on the number of items, not the cart total. So with that in mind, the Table Rate Shipping plugin is your best bet!
How could I do this on Woocommerce:
I need to charge 10.95 per item plus 1.00 for any additional item (2ormore) for example 10.95 1st item, 11.95 second item 12.95 3rd item etc. etc.
With this formula for your shipping:
10.95+(([qty]-1)*1)
In more detail:
{FirstItemShipping}+(([qty-1]*{SubsequentPerItemCost})
What’s my options for this:
I have one product with a flat rate of $45. If customer buys more of the SAME product – I want to only add half of the $45 FOR each additional item.
Hey Dawn, you could use a shipping class coupled with a formula like the one shown here. I haven’t tested this out, so I’d play with it, but something like this should work.
thanks for that!
I need your help with Flat Rate Shipping using WooCommerce. I have 2 Flat Rate Shipping options: 2 or less items $8 and 3 or more items $12. I think I have the rates to display as expected but both rates display at checkout.
Hey Leedra, this is an example that would require Table Rate Shipping, as seen here — this sort of shipping schedule isn’t possible with the built in flat rates.
Can you show how to change the price of shipping for different items.
Hey Anecia, using shipping classes is the best way to do this — here’s our guide to getting started with them!
Hello Beka,
I’m new with woocommerce and I sell products but with only unique qty, (paintings)
I search a method to set a shipping price per product, just this.
Can I do this without plugin or do I need a plugin ? If yes, does exist a free plugin for this ?
Thanks for your response
Best regards
Pat Grossard
Hey Pat! Your best bet to have shipping classes for each item, here’s a guide to getting started with them.
Becky, I have a client that sells Cinnamon rolls and cinnamon roll mix. based on the amount if roll and mix combos we have 3 different shipping flat rates.
● Small Padded Envelope $7.55 :
○ Holds up to 2 bags of mix OR up to 3 rolls with one 8 oz frosting
● Medium Box $12.80:
○ Holds up to 6 bags of mix OR up to 15 rolls with frosting
● Large Box $17.60:
○ Holds up to 10 bags of mix OR up to 18 rolls with frosting
What would be the best way or plugin to set this up in woocommerce?
Thanks for your help
Brian
I think you’d need an extension that supports box packing — there are some listed here.
Hi Beka,
Brilliant article! I’m trying to do something that I think should be quite simple, and I thought I had all the tools, but I can’t quite get it to work correctly.
I want to charge £6.50 per item (which I think should be ‘6.5*[qty]’ ), but I want it to be capped at £13.00 (which I think can be done with [max_fee=”13″]). I think these are the two segments of formula that I need, but I can’t get them to work together. Can you offer any advice?
Thanks,
Steve
Hey Steve, I think you’d need the Table Rate Shipping plugin to do per-item rates like this, similar to the examples outlined above. That “max_fee” parameter only applies to percentage-based fees.
Hi Becka,
I want to set up a single shipping price – let’s say $10 – for each product – not as per quantity – so even if someone buys 3 watches and 5 earphones, the total shipping price should be $20 because they are only two products. if they buy only 3 watches, the shipping price should be $10, for a single product. Is there is a way to set this up in Woocommerce? I have the latest version installed. I tried typing $10*[product], but it is not working. it is still adding only $10 even for multiple products. Please help.
Hey Manoj, you could do this with shipping classes, as shown here — check out the part about charging “per class”.
could you please help me to find the percentage wise shipping for regions based on MRP rate of an item
Just my 5 cents, i have found a easy and effective way of adding per product shipping wordpress and it is free just search “Innozilla Per Product Shipping WooCommerce” in the wordpress plugins, it really helped me, just sharing.
Hi Beka,
Am I missing something? I can’t see the “for developers” code snippet anywhere?
Thanks for the heads up, Sam! Looks like the gist embed broke :( just fixed it!
Great help on the qty feature, thanks.
Hello. Thanks for thé article. I have a not found an answer to my issue but maybe you Can recomand one ? I am setting up a shop in which the items will be sent from différent location. How Can i Set up a delivery method considering that i have several expeditor location ? Thank you very much for your help.
Is it possible to implement shipping per product? For example, customer adds two products to their cart, one product will ship via Free FedEx 2-Day, the other via Free Economy (4-5 days).
Customer then has an option to pay $XX.XX to upgrade the entire order to FedEx 2-Day, etc?
I’ve looked through a lot of plugins, etc and without much success. Amazon does something like this where you can have a dozen items in your cart and each one has a different estimated delivery date but you can pay to expedite each item.
Thanks in advance!
Hey Xyla, there’s not a super clean way to do this that I know of. You can set free shipping on specific products using WooCommerce shipping classes, so here’s the closest I can think of:
It’s not totally clear to customers unless you add details to the product pages, and it’s not an upgrade rate specific to the product, but I’d play with the different shipping classes and rates to see if you can get close to what you want!
Hi Beka! Hoping you can help me! I need to set shipping as example:
1 Cup is $6.25 to ship. If you order quantity between 2-9 it is total of $9.38 shipping. So, 2 cups would be $9.38 shipping and a different order of 7 cups would still be $9.38 shipping.. HOWEVER – If the qty is between 10-20 then the shipping goes to $16.38 per order. And continues to go up with an increase of qty.
Hey Tabatha, the only way I know of to create quantity breaks like this is to leverage the Table Rate Shipping plugin, as there’s not really a way to model this with the built-in quantity rules 😕
Hey Beka, thanks for the information and code snippet!
I just noticed that WC()->cart->get_cart_contents_count() doesn’t really work for this purpose if the cart has both virtual (no shipping) as well as physical products. E.g. I have 2 physical products and one virtual. So I only have 2 items to be shipped (and shipping fee applied to) but it will calculate 3 and charge extra for the third item while it won’t be shipped. What would be the best way to cater for this?