Split Shipments for WooCommerce

Split Shipments for WooCommerce allows stores to break orders into multiple fulfillment packages—either automatically at checkout based on logistics rules, or manually by fulfillment staff.


Quickstart

  1. Upload and activate the plugin via Plugins > Add New > Upload Plugin.

  2. Navigate to WooCommerce > Settings > Split Shipments.

  3. Choose your default Backordered Items handling mode.

  4. Configure how Shipping Classes should be treated for single-unit, single-line, or grouped fulfillment.

  5. Configure how Store Categories should be treated for grouped fulfillment.

  6. Click Save changes.

When does automated splitting trigger? Automation executes the moment an order transitions to Processing (typically immediately after credit card payment is confirmed at checkout). For offline payment methods like Direct Bank Transfer or Cash on Delivery, automated rules run once payment is verified and the order status changes to Processing.


System Requirements

To ensure optimal performance and full database transaction safety, your server must meet the following minimum requirements:


Plugin Compatibility

Split Shipments uses native WooCommerce CRUD APIs and hooks, ensuring compatibility with standard ecosystem tools:


Physical Logistics & Shipping Classes

Logistics Options

Under Backordered Items, you can choose how to handle items that are out of stock:

Inventory Setup Tip: For backorder splitting to take effect, ensure your products have Manage stock enabled with Allow backorders set to Allow (or the product's Stock Status set to On backorder). Split Shipments uses these real-time inventory counts at the moment of checkout to divide in-stock vs. backordered quantities.

Automatic On-Hold Safeguard: If an automated split leaves only backordered items on the parent order, Split Shipments automatically transitions the parent order to On-Hold. This prevents warehouse staff from mistakenly packing a parent order that currently contains zero in-stock units.

Shipments can also be split automatically based on product shipping classes:

Rule Precedence: If a product qualifies for multiple rules (for example, it has a Single-Unit shipping class and also belongs to a Grouped Category), rules are evaluated in order of physical parcel priority: Single-Unit → Single-Line → Grouped Classes & Categories → Standard Parcel.


Note: To prevent conflicting fulfillment logic, shipping classes selected in one tier are automatically disabled in the other dropdowns.


Category Grouping

Category Grouping

If a product is assigned to a grouped category, all items in that category will be moved to a child order. Like grouped shipping classes, this is useful for products that must be shipped together, but does not require individual products to be assigned to a shipping class.

Variation Support: Category grouping works seamlessly with variable products. Variations automatically inherit the categories of their parent product.


Other Settings

Other Settings

Shipping Fee Allocation

Three options are available to control how shipping fees are distributed:

Order History Visibility

Controls how split packages are displayed in the customer's My Account > Orders list:


Manual Order Splitting

Split Order Dialog

  1. Open any eligible order in WooCommerce > Orders.

  2. Scroll to the Order Items box and click the Split Order button.

  3. Enter the quantities of each line item you want to move into a child shipment.

  4. Click Create Child Order.


Reuniting Orders

If an order was split by mistake, fulfillment staff can merge packages back together:

  1. Open the specific Child Order you wish to return to the parent.

  2. Scroll to the bottom of the items table and click Reunite Order.

  3. Confirm the action when prompted.

What happens during a reunite?


Order Management & Tracking

Split Shipments provides dedicated tools to help warehouse staff and customers track multi-package orders seamlessly.

Admin Order List & Filtering

In WooCommerce > Orders, a dedicated Split Info column highlights order relationships at a glance:

Customer Notifications (Split Shipment Email)

When an order is divided into separate packages, an automated Order Split notification email is sent to the customer detailing:

You can customize the email subject, heading, and template under WooCommerce > Settings > Emails > Order Split.

To manually resend the notification at any time:

  1. Open the parent order in WooCommerce > Orders.
  2. Locate the Order Actions box in the right sidebar.
  3. Select Resend split shipment email to customer and click the update arrow.

Customer Communication Sequence: The customer receives their standard WooCommerce Order Processing receipt for their full order at checkout. Once automation splits the order, the customer receives the dedicated Order Split notification explaining the package division. Customers are never sent duplicate sales receipts.

Email Queue & WP-Cron: To ensure instantaneous checkout performance without slowing down the customer's payment screen, automated split notifications are dispatched asynchronously via WooCommerce Action Scheduler with a brief 5-second buffer. Ensure your site's standard WP-Cron or system cron is functioning normally.

Customer Account & Order Details View

Independent Shipping Destinations: Because each package is an independent order record, warehouse staff can edit the shipping address on Child Order #2 (e.g. shipping direct to a customer's job site or alternate address) without altering the delivery address on Package #1.

Carrier Tracking Numbers & Multi-Box Shipping

Because each child shipment is a native WooCommerce order:

Invoices & Warehouse Packing Slips

Because line items, taxes, and costs are divided directly across orders, third-party document plugins (such as WooCommerce PDF Invoices & Packing Slips or WooCommerce Print Invoices / Packing Lists) treat each shipment independently:

Automatic Audit Trail & Order Notes

Every manual and automated split or reunite event logs an entry directly into the WooCommerce Order Notes timeline:


Financials, Taxes & Bookkeeping

When you divide an order, WooCommerce creates a separate order for each new package. Here is how your numbers, taxes, and customer payments balance out across those shipments.

1. How the Money Balances

When items are divided across separate shipments, Split Shipments calculates the exact totals for the new child package first, and assigns the remaining balance directly to the main order. Consequently, the sum of all packages always matches the original customer receipt to the penny.

Example: A $135.53 order split across two packages will balance out to something like $84.76 on Package 1 and $50.77 on Package 2 — never $135.52 or $135.54.

Multi-Currency Support: Child shipments inherit the parent order's currency code. Line subtotals and taxes remain locked to the checkout exchange rate, preventing currency conversion discrepancies.

2. How Sales Tax & VAT are Handled

Sales tax calculations are preserved line-by-line:

3. Choosing a Shipping Fee Strategy

When a customer pays one flat shipping fee at checkout (e.g. $10), how should that fee be recorded once their items are in two separate boxes? You can choose one of three approaches under WooCommerce > Settings > Split Shipments:

Customer Pays Once (Zero-Cost Clone) — Recommended

The main order keeps 100% of the customer's paid shipping charge. The new split shipment gets an identical copy of the shipping method, but with the cost set to $0.00.

Best for: Stores using shipping tools like ShipStation, Shippo, or carrier plugins that require a shipping method on every order to print a label, but where you don't want to falsely double your shipping revenue in bookkeeping.

Divide Proportionally (Prorate)

The customer's shipping fee (and any tax on shipping) is mathematically divided between the packages based on the value of the items in each box.

Best for: Stores that track profitability, packaging costs, and margins for each individual package in an external accounting system.

Main Order Only

The original shipping fee stays on the main order. The child shipment is created with no shipping line at all.

Best for: Simple store setups where warehouse staff manually select shipping methods at the packing bench, or when split packages ship at store expense.

4. Discounts & Coupons

If the customer used a discount code (such as a fixed $15 off cart coupon), the discount follows the items:

5. Credit Cards & Payment Gateways

6. Working with Shipping & Accounting Tools

Marketing & Campaign Attribution: Split Shipments natively copies WooCommerce Order Attribution data (UTM campaign, source, medium, and referral channels) from the parent order to all child shipments. Your analytics, conversion tracking, and multi-touch reporting remain unbroken across all packages.


Eligibility Guardrails

To prevent accounting discrepancies, stock desynchronization, and gateway errors, actions are restricted by order status:

Order Status Can Split? Can Reunite? Operational Notes
Processing Allowed Allowed Standard active fulfillment state.
On Hold Allowed Allowed Used for backordered packages awaiting stock.
Completed Blocked Blocked Fulfillment is finalized. Packages cannot be reverted.
Refunded / Cancelled Blocked Blocked Orders with processed refunds are locked to protect audit trails.

Uninstallation & Data Retention

Split Shipments protects historical sales records and financial audit trails:

Parent Order Cancellation & Independent Statuses

Parent and child orders maintain independent fulfillment statuses:


Frequently Asked Questions

Does this work with PayPal, Klarna, Apple Pay, or Buy Now Pay Later (BNPL)?

Yes, universally. Because Split Shipments never initiates secondary payment gateway captures or modifies original transaction tokens, it is compatible with all WooCommerce payment gateways (including Stripe, PayPal, WooPayments, Klarna, Authorize.net, and offline BACS/COD methods).

Why didn't an eligible order split automatically at checkout?

Automated splitting executes only when an order status changes to Processing and meets your rule criteria. If an order did not split, check the following:

  • Status transition: Orders that jump directly from checkout to Completed (such as orders consisting purely of virtual/downloadable items) bypass the Processing trigger.
  • Stock settings: For backorder splitting, products must have Manage stock checked and Allow backorders set to Allow. If stock is not tracked, WooCommerce does not record backordered quantities at checkout.
  • Single bucket evaluation: If all items in the cart resolve to the same fulfillment tier (for example, all items are standard in-stock parcel items), no division is necessary and the order remains a single parent order.
  • Total quantity: The order must contain more than one total unit or line item.
Why is the "Split Order" button missing on an order?

The split button is hidden automatically if the order fails validation:

  • Already a Child: Child packages cannot be divided into sub-orders.
  • Single-item orders: The order has 1 or fewer physical units (nothing to divide).
  • Partial Refunds: If a refund has already been recorded, splitting is locked.
  • Permissions: The logged-in user lacks edit_shop_order capability.
Does splitting an order charge the customer's card again?

No. Payment capture occurs exclusively on the original parent order. Child orders note the payment method used for fulfillment context, but the transaction ID remains on the parent order to ensure refunds are only ever processed against the primary charge.

How is inventory tracked across split packages?

If the parent order already reduced stock (upon entering Processing), allocated child items inherit the _reduced_stock flag. This prevents WooCommerce from double-deducting stock when child orders are completed.

Is this compatible with High-Performance Order Storage (HPOS)?

Yes. The extension is natively architected for WooCommerce custom order tables (HPOS) as well as legacy post-based storage.

Can I split an order into more than two shipments?

Yes. You can split a parent order multiple times. For example, you can move 1 item to Child Order #101 today, and another item to Child Order #102 next week. All child shipments remain permanently linked to the primary parent order.

Can child orders be split further?

No. To prevent convoluted order hierarchies and broken financial reconciliation, child shipments cannot be divided into sub-orders. If you need to reallocate items, reunite the child order back into the parent first, then perform the new split.

Can I move 100% of items from the parent order to a child order?

No. The parent order represents the primary financial invoice and must retain at least one physical item (or remaining quantity). If you need to reassign an entire order, adjust the original order directly rather than splitting it.

Why did my parent order switch to "On-Hold" after an automated split?

This is a built-in fulfillment safeguard. If an automated split moves all in-stock items into child shipments, leaving only out-of-stock or backordered items on the parent order, the plugin places the parent order On-Hold.

This prevents warehouse staff or automated print-station software from accidentally picking a parent order that currently has zero physical stock available to pack.


Customizing Templates (Theme Overrides)

All customer-facing emails, notices, and breakdown tables can be customized using standard WooCommerce template override hierarchy.

To override a template, copy the file from: wp-content/plugins/split-shipments/templates/

Into your active child theme directory: wp-content/themes/your-active-theme/split-shipments/

Template FilePurpose / Placement
emails/customer-order-split.phpHTML notification email sent to the customer detailing package breakdowns
emails/plain/customer-order-split.phpPlain-text version of the split shipment email
frontend/child-orders-table.phpMulti-package shipment breakdown table shown on the parent order view
frontend/parent-order-banner.phpBlue alert banner at the top of the parent order details page
frontend/child-order-banner.phpYellow notice at the top of a child order clarifying its parent link


Developer Reference & Hooks

Split Shipments for WooCommerce provides dedicated action and filter hooks so developers can integrate with warehouse management systems (WMS), 3PL APIs, or custom ERP workflows.

Splitting Lifecycle

Action split_shipments_before_split

Fires inside the database transaction before line items, shipping, and totals are divided.

Parameters
  • WC_Order $parent_order — The source order being split
  • WC_Order $child_order — The freshly instantiated child order
  • array<int, int> $items_to_split — Map of [item_id => quantity]
Action split_shipments_after_split

Fires immediately after the split transaction is committed and orders are saved. Ideal for triggering warehouse notifications or dispatching webhooks to a 3PL.

Parameters
  • WC_Order $child_order — The finalized child shipment
  • WC_Order $parent_order — The updated parent order

Reunite Lifecycle

Action split_shipments_before_reunite

Fires inside the transaction before a child shipment is merged back into its parent order.

Parameters
  • WC_Order $parent_order — The parent receiving items
  • WC_Order $child_order — The child order about to be merged and deleted
Action split_shipments_after_reunite

Fires after the child order has been completely reunited and deleted from the database.

Parameters
  • WC_Order $parent_order — The restored parent order
  • int $child_id — ID of the deleted child shipment

Notifications & Events

Action split_shipments_order_split_notification

Fires when automated split notification emails are dispatched via Action Scheduler.

Parameters
  • WC_Order $parent_order — The primary parent order
  • array<WC_Order> $child_orders — Array of newly generated child shipments

Automation & Strategy

Filter split_shipments_should_automate_split

Return false to conditionally halt automated splitting (e.g., for B2B wholesale roles, specific shipping countries, or custom checkout gateways).

Parameters
  • bool $should_split — Default true
  • WC_Order $order — The order entering processing
Filter split_shipments_split_plan

Inspect or mutate the planned buckets (parent item list vs child buckets) before automation splits the order.

Parameters
  • array $plan — Calculated split plan ['parent_bucket' => ..., 'child_buckets' => ...]
  • WC_Order $order — The order being planned
Filter split_shipments_item_tier_and_group

Override the tier resolution (single_unit, single_line, grouped, or standard) for custom product classifications.

Parameters
  • array $resolved — [string $tier, string $group_key, ?string $reason]
  • WC_Product $product — The product being evaluated
  • string $shipping_class — Assigned class slug
  • WC_Order $order — Order context

Order Creation

Filter split_shipments_child_order_args

Modify the arguments passed to wc_create_order() before a child order is instantiated.

Parameters
  • array $child_args — Arguments array (status, customer_id, customer_note)
  • WC_Order $parent_order — Source parent order

Eligibility & Guardrails

Filter split_shipments_can_split_order

Add custom business logic to permit or block splitting an order.

Parameters
  • EligibilityResult $result — Current eligibility object
  • WC_Order $order — Order being evaluated
Filter split_shipments_can_reunite_order

Add custom business logic to permit or block merging a child shipment back into its parent.

Parameters
  • EligibilityResult $result — Current eligibility object
  • WC_Order $child_order — Child shipment evaluated

Order & Item Metadata Reference

REST API Access: For authenticated WooCommerce REST API queries (/wp-json/wc/v3/orders), all plugin keys are exposed within the standard meta_data array on both parent and child order objects.

If you are syncing orders with an external ERP, WMS, or querying the WooCommerce REST API, Split Shipments stores the following internal meta keys:

Order-Level Meta (WC_Order)

Meta KeyDescriptionType
_split_shipments_parent_order_idPresent on child orders; contains the ID of the parent orderint
_split_shipments_child_order_idsPresent on parent orders; array of linked child order IDsarray<int>
_split_shipments_split_by_nameName of the user or system automation that triggered the splitstring
_split_shipments_split_atMySQL timestamp of when the order split occurreddatetime
_split_shipments_is_reunitedFlagged yes on orders that previously absorbed a reunited childstring
_split_shipments_split_by_user_idID of the user who performed the split (0 for system automation)int
_split_shipments_automation_executedFlagged yes if the split was performed automaticallystring

Line Item-Level Meta (WC_Order_Item_Product)

Meta KeyDescriptionType
_split_shipments_line_item_idPresent on child line items; stores the parent line item ID from which it originatedint
_split_shipments_backordered_qtyQuantity recorded as out of stock at the time of checkoutint

Shipping Item-Level Meta (WC_Order_Item_Shipping)

Meta KeyDescriptionType
_split_zero_cost_cloneFlagged yes on child shipping items created via the Zero-Cost Clone strategystring

3PL & Webhook Dispatches: When a split occurs, WooCommerce automatically dispatches standard order.created webhooks for each new child shipment, and an order.updated webhook for the modified parent order. External warehouse management systems (WMS) will detect the new package automatically.


Code Examples

Example 1: Disable Automated Splitting for Wholesale/B2B Roles

add_filter( 'split_shipments_should_automate_split', function( bool $should_split, WC_Order $order ): bool {
    $user = $order->get_user();
    
    // Don't auto-split wholesale customer orders; let warehouse staff split manually
    if ( $user && in_array( 'wholesale_customer', (array) $user->roles, true ) ) {
        return false;
    }
    
    return $should_split;
}, 10, 2 );

Example 2: Notify External WMS / 3PL Webhook on Split

add_action( 'split_shipments_after_split', function( WC_Order $child_order, WC_Order $parent_order ): void {
    // Dispatch webhook to custom warehouse management system
    wp_remote_post( 'https://api.yourwms.com/v1/shipments', [
        'headers' => [ 'Content-Type' => 'application/json' ],
        'body'    => wp_json_encode( [
            'child_shipment_id' => $child_order->get_id(),
            'parent_order_id'   => $parent_order->get_id(),
            'status'            => $child_order->get_status(),
        ] ),
    ] );
}, 10, 2 );

Have a Question or Need Technical Assistance?

Our engineering team provides dedicated support for all verified WooCommerce Marketplace subscribers.

Get Support →