In WooCommerce version 2.1 a new feature was introduced that allowed one order to have multiple shipping packages. Having multiple shipping packages can come in handy in various situations. One that comes to mind at first is when you actually have multiple packages, for example when you can’t ship items together, or when someone has an order that should ship via two different vendors.
Or the other obvious scenario, having to ship one order to multiple different destinations.

Another very useful use-case that a other WooCommerce user pointed me too not long ago was the ability to allow free shipping on just a specific set of products. When using a shipping carrier plugin like UPS it can be hard to set this up, but when splitting your order into multiple packages, and then setup free shipping (with WooCommerce Advanced Free Shipping for example) you can target only the package with the free shipping items, while the UPS plugin still gets the shipping cost for the other products.

Splitting Shipping Package

Just to give a clear example of what ‘splitting a shipping package’ means, this is how it would look like for the user when shipping multiple packages;


Before actually splitting a order in multiple packages, you should first understand what a shipping package is exactly. Obviously a shipping package contains a part of the products to ship, but besides that, it also contains information like the cost, applied coupons and the destination address. A shipping package looks a bit like the following:

  • Contents
    • {{ All package contents }}
  • Contents cost
  • Applied Coupons
    • 10_OFF
  • User
    • User ID
  • Destination
    • Country
    • State
    • Postcode
    • City
    • Address
    • Address_2
Update I’ve build a plugin that allows you to split the cart into multiple packages. If you’re not comfortable with the code snippets below you may want to checkout the WooCommerce Advanced Shipping Packages plugin.

Splitting Shipping Package on Shipping Class

The follow code snippet will split the shipping package based on the shipping class. Each product that has a shipping class A will be split into a separate package from the other products.

Splitting Shipping Package on Product ID

If you want to split the shipping package based on product IDs you can replace the top part of the code with the following (partial code);

This will setup a separte shipping package for the products with the ID 188, 189 and 190.

Splitting Shipping Package on Category

The following code is similar to the (partial) code above. Use it by copying into the full code as seen as the first code snippet in this post.

Changing the shipping package name

When you’ve implemented the code above, the shippng should look something like this;



As you can see, there are two shipping packages, each where the user can select a shipping method. One thing that you will see is that the shipping packages are called Shipping #x. If you want to change this, you’re in bad luck, currently it is not possible to change that package name.

I made a Pull Request to WooCommerce in order to allow the re-naming of the shipping package name, so you can call it what you want from within the shipping package array (as you saw in the first code snippet). When this Pull Request is accepted and it is in WooCommerce Core, I will update this post to include the new feature.

Setting Up Shipping Based on Shipping Package

Not all shipping plugins support shipping packages, so make sure you test everything extensively so your customers will pay the right amount on shipping cost.

My own WooCommerce Advanced Shipping plugin supports shipping packages.

Jeroen Sormani

I'm a professional WordPress plugin developer on a mission to create the best plugins for my clients. I'm specialised in developing general WordPress, WooCommerce and Easy Digital Downloads plugins.

Interested in talking about a WordPress project? Get in touch!

Follow me on Twitter

81 thoughts on “Splitting Shipping Packages in WooCommerce

Oliver February 22, 2017 at 1:02 pm

Hi Jeroen,

I’m looking to implement your code on my website. We currently store small items on-site and any larger items we drop-ship direct from the supplier’s warehouse. We’d like to offer express & standard shipping methods for on-site products/classes and a ship by courier method only for the large dropship products/classes.

Is there a way to ‘group’ shipping classes together into packages, such as ‘small-2kg & medium-1kg’ (on-site) and ‘extra-large-15kg & large-10kg’ (drop-ship), to allow customers to pay/checkout for each package seperately?


Jeroen February 23, 2017 at 8:43 am

Hi Oliver,

Let me first note that split shipping packages cause shipping to be calculated separately per package, but it doesn’t allow customers to ‘pay/checkout for each package’.

Its relatively easy to do a conditional check for one of two shipping classes and pack them into one package.

If you’re not comfortable with coding that I’d recommend to take a look my plugin that would also fit your needs:


Oliver February 23, 2017 at 10:14 am

Thanks for the prompt reply. That’s great, separate calculation is what I actually meant/wanted and I appreciate you clarifying that. I’ll have to have a look at your plugin as my coding is very hit and miss!

Thanks again,

Francine February 23, 2017 at 4:29 pm

Could you tell me whether your plugin would be appropriate for me?

I am currently using Dokan plugin based on WooCommerc and I would like to see the shipping cost split between each vendor that the customer purchases from.

I would like the capability that if the customer reaches a particular dollar value on their order they may be entitled to free shipping and this is mentioned to them through the cart experience.

So it could end up being that they order from 3 vendors – vendor a $20 ordered, pay $10 shipping, vendor b – $70 orders pay $0 shipping, vendor c – orders $50, but if they spend up to $60 they get free shipping so in total the shipping only reaches $10.

Can you please tell me if your plugin will do this?

Jeroen February 24, 2017 at 8:49 am

Hi Francine,

The Advanced Shipping Packages would only be able to split the cart into separate packages. If you can distinguish the vendors by something like shipping class or category you’d be able to split those based on those identifiers.

Then for shipping,, do you mean that they get free shipping per vendor if the subtotal per that vendor is above $60? You might be able to setup something like that using my Advanced Shipping plugin, but that also depends on how your shipping cost is setup.

Re it being mentioned in the cart, neither of the plugins above adds any type of notification (outside the scope of the plugin(s)). I do have another that has such type of functionality, but that doesn’t work out of the box with different amounts that are in the cart per vendor.
It would require some additional work to get that working the way I imagine you want it to.

Does that help?


Young Kim March 7, 2017 at 6:15 am


Love your code how it works.
I have question.
I have two shipping class
“Products” – allow free shipping over 300.00
“Non-Free Shipping”

I setup your code to split order by shipping class which works great.
However, my second shipping package still shows “Free shipping” (by the way I am using your “Advanced Free Shipping Plugin” to determine the free shipping.

Is there a ways to hide free-shipping option for package 2?

Littile help will be appreciated.

Jeroen March 7, 2017 at 10:46 pm

Hi Young,

The AFS plugin currently doesn’t have the capability to look at the contents of a package. My other Advanced Shipping does have that capability, though the default ‘subtotal’ condition still looks at the cart subtotal.

I may have a code snippet available that makes it look at the package cost, but I’m not 100% sure about that.

Its also possible of course to manually remove the WAFS rate for the one package. You can look through the package rates to check and remove it.
Another option for that would be to use another plugin of mine that allows you to split the package and exclude rates (the same as above here, just with a UI):


Justin March 8, 2017 at 1:19 am

Hey Jeroen-

If I have a large product, like a bicycle, that isn’t shipped in a single box, how do I handle that? If you buy a frame-only, it’s box/weight A. If you buy a complete bike, it’s box/weight B + box/weight C.

It seems like the Advanced Shipping plugins are both geared towards creating multiple shipping boxes when dealing with multiple products… but what about one product and multiple boxes?

If it matters, we’re also using the UPS plugin to get dynamic shipping pricing on checkout.

Thanks for the help!

Jeroen March 8, 2017 at 8:55 am

Hi Justin,

Splitting one product into multiple packages isn’t possible as the packages do require a product to be in there.
It might work if you actually have separate products for the different parts / like a grouped / composite product for the full bike, but I’m not sure if that is possible for your site.

Note that Advanced Shipping itself doesn’t work with UPS, the Advanced Shipping Packages plugin would allow you to split the cart, hopefully too on the composite products (if you want to give that a try, I haven’t tested it myself). The UPS plugin would then need to support those shipping packages to get separate rates for each of them.

Hope that helps / makes sense.


Pekka April 26, 2017 at 4:28 pm

Hi Jeroen,
how the actual shipping of the Shipping Packages of one order is managed in WooCommerce and how the order status follows the process?
Example: Our customer orders one product, but we send first a tester, and after customer confirms we ship the actual product under the same order id and line. Customer doesn’t see the tester as an item in cart, but we manage it by custom made “between” order status. I was wondering if we can better manage the flow by creating own line item for the tester and have two Shipping Packages. But I couldn’t find out if we can ship the first Package only (to shipping-queue and tester-shipped) and week or two later the second Package (to shipping-queue and completed). How the order status follows Shipping Packages?
Thoughts or tips?
Many thanks in advance,

Jeroen April 27, 2017 at 9:12 am

Hi Pekka,

This won’t be possible without additional customization. As there are only order statuses it isn’t possible to have two separate shipping statuses. I do believe there are some plans to change things up and have separate order statuses and shipping statuses, but I’m not sure when those will be introduced.

If you’re starting such customization I’d advise to set things up based on the shipping packages and follow that as much as possible.


Pekka April 28, 2017 at 4:40 pm

Beste Jeroen,

couple of short ones:
Do you know if there’s a demo somewhere to test Advanced Shipping Packages?
Do have experience or know how Advanced Shipping Packages works with WooCommerce Warehouses plugin?


Jeroen April 28, 2017 at 6:29 pm


There’s no demo available, can’t tell how it works with that plugin, haven’t tested it.


Andy May 2, 2017 at 2:13 am

Hi, I tried the code, and everything works fine except TAX calculation.
All taxes starting from the second package aren’t calculating. In buyable version taxes calculating properly?
Or do you have any idea why it is might happen?

Jeroen May 2, 2017 at 8:47 am

Hi Andy,

Not sure why its not calculating tax for you. There are no known bugs in the plugin regarding taxes.
Might be something in your setup, don’t believe packages should influence taxes like that.


Andy May 2, 2017 at 11:43 pm

Just bought this plugin and there is still issue with Tax calculation and package names do not display properly as well.
I there a way to fix it? Please contact me directly thru email

Jeroen May 3, 2017 at 9:26 am

Hi Any,

Please contact support for any support questions regarding the Shipping Packages plugin, as its sold through their system I cannot answer support questions directly.


dani July 4, 2017 at 7:31 am

Seems like the code doesn’t work now sadly. Which means one is forced to have to buy the plugin. This is as of wc 3.1.0 btw.

Jeroen July 4, 2017 at 8:35 am

Hi Dani,

Just tested the first code snippet on WC 3.1 and seems to work perfectly with me. I’ve got no reason to believe WC has changed anything in regards of shipping packages here. The plugin itself hasn’t required or had a update for WC 3.1 either.

There’s likely something else going on why the snippet isn’t working for you.


Munaye October 21, 2017 at 2:06 am

I have UPS & USPS Shipping methods, but I want to apply each method to a specific product category, such that when one checkouts only the respective shipping method for that particular category is set. If there are two different products from different categories then both UPS & USPS appear on checkout. How can i go about this? Thank you

Jeroen October 21, 2017 at 10:27 am

Hi Munaye,

You can do this by using the Advanced Shipping Packages plugin. With that you can create the packages per category, and exclude shipping methods per package to only show the respective shipping carrier option.

Hope that helps!

Brett February 1, 2018 at 5:34 am

Hey Jeroen,

I want to enable free shipping when over $100 is spent in certain categories, is there a simple way to do this?


Mary Jo April 4, 2018 at 6:25 pm

Is it possible to split two products into two shipping packages with Advanced Shipping Package plugin?

Mary Jo April 4, 2018 at 6:59 pm

I should have been more explicit that the two products are the SAME product. So if I have two shirts – both same product – how do I indicate to separate these into two packages?

Jeroen Sormani April 4, 2018 at 8:41 pm

Hi Mary Jo,

It is not possible to split one product into two packages with the plugin.

Philip May 2, 2018 at 11:56 pm

Is it also possible to show the shipping price per product on cart?

Jeroen Sormani May 3, 2018 at 9:27 am

Hi Philip,

To do that you could split each product in a separate package so the shipping options are shown separately per product.

Alternatively you could also consider using the Extra Shipping Options plugin to display a ‘Description’ option, not sure if it will fully fit your needs, but it may 🙂


Dave B May 25, 2018 at 5:58 pm

Great code! I’m trying to split shipping into three possible variables:
1. Regular, courier ship items
2. Free ship items
3. Freight ship items (manually calculated after order).

I have created the free ship class and the manual ship class. Is there a way to include both classes in the array variable?

Thank you!

Zac September 22, 2018 at 11:22 pm

As this article was never updated if anyone else was looking for how to change the Shipping Package name, here’s a snippet I wrote which implements a filter to change the text to Package 1, Package 2 etc:

add_filter( ‘woocommerce_shipping_package_name’, ‘change_shipping_package_name’, 10, 3 );
function change_shipping_package_name($shipping_name, $index, $package) {
$shipping_name = “Package “.++$index;
return $shipping_name;

Diego Versiani December 20, 2019 at 2:59 pm

Hi Jeroen,

It would be nice if you can update the post content about the pull-request to make possible to change the shipping package name 🙂

Thanks for the great article, it saved me a lot of time 🙂

Ilze January 2, 2020 at 11:22 pm

Hoi Jeroen
Is there a plug in code that allows for separate shipping charges when an item in shopping basket is on back order? My current woo-commerce shop only charges one shipping rate, thus meaning that when an item on back order arrives, I will have to ship it to the customer on my own costs. (The shipping is most of the times almost more than the item itself)
Anyway around this issue?

Jeroen Sormani January 3, 2020 at 11:09 am

Hi Ilze,

You can do this with my Advanced Shipping Packages plugin 🙂


DD February 3, 2020 at 9:21 pm

If I setup Free Shipping for one “package” and FedEx ground for the second “package”, how do I hide the Free Shipping button on the FedEx ground package option?

Jeroen Sormani January 29, 2021 at 7:19 pm

Hiding shipping options in a package is not something covered in this post. You’d need a additional customization for that, or use the Advanced Shipping Packages plugin which has a feature build in for that.

Joe January 29, 2021 at 3:48 pm

I am having the same Tax issue the previous user mentioned. Tax calculates fine for one package but not the second. Do you know if this issue has been fixed with the paid plugin?

Jeroen Sormani January 29, 2021 at 7:16 pm

Hi Joe,

My prior answer to that earlier mention is still valid; no known issues with the plugin for that.


Johannes March 3, 2021 at 1:27 pm

I combined your Code with the Advanced Shipping Plugin. I could not find the correct conditions for my case.

I will set free shipping for a package if the Sub-Total of that package is greater than a certain value (not the sub total of the cart).

Is that possible?


Jeroen Sormani March 3, 2021 at 2:42 pm

Hi Johannes,

Out of the box it is not possible to setup a condition based on package amount, but this can be done with a custom condition for the plugin. Feel free to reach out through the support channel for the shipping plugin if you’d like help with this;


Ari June 29, 2021 at 4:46 am

Do you know of a plugin that can assign multiple, different box dimensions & weights for a single variable product? We are unable to fit our variable product into 1 shipping box – its takes 4 shipping boxes for just 1 product. We need to add/assign/specify specific dimensions and weights of multiple box that make up 1 product to be able to get a live FedEx shipping cost using our Fed Ex account negotiated rates. Ideas?

Jeroen Sormani August 10, 2021 at 11:12 am

Hi Ari,

Unfortunately this is not something that is uniformly supported by in WooCommerce. This would require to look at the carrier plugin and see if the request to it can be modified to make it so the product requests for the multitude of boxes. If this is possible would depend on the carrier plugin that is being used.


Leave a Reply