Creating Order Routing Rules

Order routing decides where each order is sent for fulfillment after the app pulls it from your sales channel. You define this logic with routing rules in the Order Routing Engine.

With routing rules, you can:

  • Route orders to the warehouse closest to the customer's shipping address.
  • Route orders based on inventory availability.
  • Route orders based on SKU, tag, or other order attributes.
  • Split orders across locations when no single location can fulfill them.

You need at least one routing rule, unless your orders arrive already routed, with a fulfillment location assigned in your ERP or sales channel.


How order routing works

When a new order enters the app:

  1. The app evaluates routing rules in order, from top to bottom.
  2. For each rule, the app checks the rule's filters. If the order doesn't match, or no fulfillment location applies, the app skips the rule.
  3. For the first rule that matches, the app selects the first fulfillment location with available inventory.
  4. If no rule matches, the app raises an exception and sets the order's routing status to failed, even if the order status stays Ready For Fulfillment. The app retries failed orders every 3 hours.

Place rules for special cases, such as wholesale, pre-orders, or drop-ship, at the top. Place general rules below them.


How to create a routing rule

  1. Navigate to Order Routing in the left navigation pane. The Routing Rules tab opens.
  2. Click Add custom rule at the bottom of the rule list, and then select Manually configure rule. To describe the rule in plain language instead, select Create rule with Pippen.
  3. Enter a Name for the rule, for example, "Wholesale orders" or "West Coast."
  4. (Optional) Click Add filter to set the conditions an order must meet for this rule to apply. See Adding filters below.
  5. Select the rule options you need, such as Do not check inventory or Allow split orders. See Rule options below.
  6. Under Destination Fulfillment Preferences, add the locations the rule can route to. See Setting fulfillment preferences below.
  7. Drag the rule by its handle to set its position in the list. Rules at the top run first.
  8. Click Save changes.

New rules show a Not saved label until you click Save changes. Each rule shows Enabled or Disabled. To turn a rule off without deleting it, use the menu next to its status.

Order Routing Engine page with the Routing Rules, Settings, Routing Runs, and Transformers tabs and a list of rules

New routing rule named Pre-orders with the Add filter menu open, showing Simple filter and Code (JavaScript)


Adding filters

Filters set the conditions an order must meet for a rule to apply. A rule without a filter applies to every order that reaches it. In a rule, click Add filter and select a filter type:

  • Simple filter: Build conditions from a field, an operator, and a value. Use this for straightforward logic, such as filtering by SKU, shipping state, or order tag.
  • Code (JavaScript): Write a script that returns true or false. Use this when simple conditions can't express your logic, for example, calculations across fields or string parsing. It works the same way as code filters in automation rules.
  • Line item code (JavaScript): Write a script that returns the specific line items this rule routes. Use this when only some lines on an order should go through the rule, for example, routing frozen items to a cold-storage location while the rest of the order continues to other rules. See Add a line item code filter below.

A rule can have both an order-level code filter and a line item code filter.

Add a simple filter

  1. In the rule, click Add filter, and then select Simple filter. The Create Advanced Filter window opens.
  2. Enter a Name for the filter. You can also search for and reuse an existing filter by name.
  3. Select OR or AND in Operator to set how conditions combine. Select Not to match orders that don't meet the conditions.
  4. For each condition, select a Field (for example, Tags or Line Item SKU), an Operator (for example, Equals, Equals Any Of, or Contains), and enter a Value.
  5. Click Add Rule to add more conditions.
  6. Click Save & Apply, and then click Save changes on the rule.

Create Advanced Filter window with Tags equals wholesale and the Preview and Save & Apply buttons

About Preview: Preview opens the All Orders page in a new tab with your filter conditions applied. The All Orders page also applies its default filter, which shows only orders ingested in the last 14 days, and the filter conditions don't appear in the filter bar. If you click Clear All, the filter conditions are removed too. To check which orders a rule catches, use Test routing rules instead.

Add a code filter

The full order is available to your script as the order variable. Return true to route the order through this rule, or false to skip to the next rule.

  1. In the rule, click Add filter, and then select Code (JavaScript). The Add Code Filter window opens.
  2. Load an order to test against: click Load latest order, or enter a Pipe17 order ID and click Load.
  3. Write your script in the Code panel, for example, return order.total > 100;
  4. Click Test code. The Output panel shows Passed if the script returned true, or Failed if it returned false. Any console.log output or errors appear under Debug.
  5. Adjust the script and test again until it behaves as expected.
  6. Click Save & Apply, and then click Save changes on the rule.

Use Input, Code, and Output under View to show or hide each panel.

Add Code Filter window with the latest order loaded, the default script, and a Passed result

Add a line item code filter

A line item code filter selects which lines on an order a rule routes. The app runs the script once per order, with the full order available as the order variable. Your script returns an array of line item unique IDs. The rule routes only those lines.

Each line item has a uniqueId field that identifies that specific line on the order, even when two lines share the same SKU. Return these IDs, not SKUs.

How the app reads the result

Your script returns Result
An array of line item unique IDs The rule routes only the listed lines.
An empty array [] No lines match, so the rule routes nothing for this order.
Anything that isn't an array, such as true, null, or a string The app treats it as an empty array, so no lines match.

Lines your script doesn't return aren't routed by this rule. The rules below it evaluate them.

Your script can look at every line on the order at once. You can compare lines, count them, or total quantities and values across lines before deciding which IDs to return.

  1. In the rule, click Add filter, and then select Line item code (JavaScript).
  2. Load an order to test against: click Load latest order, or enter a Pipe17 order ID and click Load.
  3. In the Input panel, find the uniqueId of each line item in the order data.
  4. Write your script in the Code panel. The script must return an array of line item unique IDs.
  5. Click Test code. The Output panel shows the line item IDs your script returned. Any console.log output or errors appear under Debug.
  6. Adjust the script and test again until it selects the lines you expect.
  7. Click Save & Apply, and then click Save changes on the rule.

Example: route lines by SKU prefix

This filter selects every line whose SKU starts with FRZ- so the rule can send them to a cold-storage location:

return order.lineItems
  .filter(line => line.sku.startsWith('FRZ-'))
  .map(line => line.uniqueId);

Example: route lines based on a total across lines

This filter selects all PAL- lines only when their combined quantity is 10 or more, for example, to send bulk orders to a freight location. If the total is lower, it returns an empty array and the lines go on to the rules below:

const palletLines = order.lineItems.filter(line => line.sku.startsWith('PAL-'));
const totalQty = palletLines.reduce((sum, line) => sum + line.quantity, 0);

return totalQty >= 10 ? palletLines.map(line => line.uniqueId) : [];

Limitations

  • Original lines only: Line item code filters evaluate the lines as originally ordered, not alternate SKUs. When alternate SKU evaluation swaps a SKU, the filter still sees the original SKU and quantity. For example, if a customer orders SKU A and the app ships alternate SKU B, a filter that checks for SKU B doesn't match that line. Write your filter against the SKUs customers order. For more on alternates, see Routing Rules (High-Level Concept).
  • Non-shippable lines: The app never routes lines that don't require shipping, such as digital goods or gift cards, even if your script returns their IDs.

Best practices

  • Always return an array. Use [] when nothing should match, rather than false or null, so the script's intent is clear.
  • Use uniqueId, not SKU, to identify lines. One order can have several lines with the same SKU.
  • Place rules with line item filters above your general rules, so the lines they don't select fall through to a broader rule.
  • Before you enable a rule, check the result with Test routing rules using Test Order As A Net New Order.

Setting fulfillment preferences

Destination Fulfillment Preferences sets where a rule can send orders. The router tries each location in order and picks the first one with available inventory.

  1. In Destination, select the region the preference applies to, for example, Western US. Leave it blank to apply to all regions. Click Add Destination to add preferences for other regions.
  2. Click Add Location, and then select Add a single location, Add a location group, or Add a dynamic location group.
  3. Select the location or group. For a location group, click Show locations to see which locations it includes.
  4. For a location group or dynamic location group, select a Location prioritization strategy. For a dynamic location group, also enter its name.
  5. Drag the rows into the order you want the router to try them.
  6. Click Save changes.
Type What it is Order of locations When to use
Single Location One specific location Not applicable Orders for this destination always ship from one known location.
Location Group A saved group of locations Set for each order by the Location prioritization strategy You want to reuse the same set of locations across rules. Choose By default sort order to keep the same fallback sequence for every order, for example, primary 3PL, then backup 3PL.
Dynamic Location Group A list of locations stored on the order, set by an order routing code action and referenced by name Set by the Location prioritization strategy, unless the order's group specifies its own The locations to try depend on the order and are set by your routing logic.

For a location group or dynamic location group, choose a Location prioritization strategy:

  • By highest inventory (default): Tries the locations with the most available stock for the order's items first. Use this to reduce split shipments and avoid low-stock locations.
  • By location priority: Tries the location closest to the order's shipping address first. Each location in the group needs an address. Use this to shorten delivery distance and time. See Location Groups for how distance is measured.
  • By default sort order: Tries locations in the order they were added to the group. Use this for a stable, predictable sequence.

If a rule has no valid fulfillment locations, the app skips the rule and shows a red warning.

Destination Fulfillment Preferences with Western US as the destination and a Location Group prioritized by highest inventory


Rule options

Each rule includes these options:

Option Description
Do not check inventory Ignores inventory levels and routes to the first listed location. Use this for drop-ship or made-to-order items.
Skip location Skips a location during routing when it can't fulfill the order.
Include future inventory Treats incoming stock as available when checking locations.
Send future order immediately Sends orders that rely on future inventory to the location right away. Available when Include future inventory is selected.
Allow split orders Splits an order across locations when no single location has every item.
Optimize for location priority Follows the location sequence when splitting an order. Available when Allow split orders is selected.

For orders with alternate SKUs, see Routing Rules (High-Level Concept). Line item code filters evaluate the originally ordered SKUs, not alternates.


Testing routing rules

Test routing rules simulates how your rules would route an order, without creating shipping requests or sending anything to a 3PL. Use it before you enable new rules, after you change filters or locations, and when an order routes unexpectedly.

  1. On the Routing Rules tab, click Test routing rules.
  2. Click Pull latest order to load your most recent order, or paste a Pipe17 order ID.
  3. Review the order data under Order JSON.
  4. Click the arrow on Test Order Routing, and then select one of these options:
    • Test Order As Is: Tests the order in its current state, including its routing history.
    • Test Order As A Net New Order: Tests the order as if it were newly ingested, ignoring earlier routing attempts. Use this to check new or reordered rules.
  5. Review the Test Result, which shows the rules that matched, the locations evaluated, and the final routing decision.

Test Order Routing Rules window with an order loaded and the Test Order As Is and Test Order As A Net New Order options


Order routing settings

The Settings tab holds global settings for how the Order Routing Engine handles orders.

Category Setting Default Description
General Only enable order routing for orders created after this time Not set Skips orders created before this date and time. Leave blank to route all orders.
General Manually release each shipping request Off Holds each shipping request until someone releases it in the app.
General Require review for auto re-routing orders created X days ago Off Marks older orders for review instead of releasing them when they're re-routed automatically.
General Review required for auto re-routing orders created X days ago 5 days Sets the age threshold for the setting above.
General Cancel order if no inventory is found for all items Off Cancels an order when no location has inventory for any of its items.
General Auto cancel orders that have all shipping requests canceled Off Cancels an order when all of its shipping requests are canceled.
General Auto fulfill orders with no shippable items On Marks orders with only non-shippable items, such as digital goods, as fulfilled.
Stuck orders Auto re-route stuck orders every 3 hours Off Retries orders that are stuck, for example, while waiting for inventory.
Stuck orders Auto re-route stuck orders less than X days old 30 days Limits automatic re-routing to orders younger than this.
Inventory buffer Inventory buffer threshold 5 units When available inventory at a location is at or below this number, the engine pauses routing for that run and retries about 5 minutes later. If inventory is the same on retry, the order can still route.
Pre-routed orders Create shipping request for pre-routed orders/items Off Creates shipping requests for orders or items that already have routing information. When off, pre-routed items bypass the engine.
Out-of-stock orders Out of stock order faster re-routing age limit 15 days Orders younger than this are retried more often while out of stock.
Failed orders Failed order faster re-routing age limit 15 days Orders younger than this are retried more often after a routing failure.
Overship prevention Set Review Required when more than 1 shipping request is created per order Off Flags orders for review when routing splits them into several shipping requests.
Overship prevention Over-fulfillment policy Raise exception and mark for review Controls what happens when a possible over-fulfillment is detected. You can also change it from Change policy on the Routing Rules tab.

Settings tab of the Order Routing Engine showing the routing start date and the manual release settings


Order routing runs

The Routing Runs tab records every routing attempt, so you can see which rules and locations were evaluated, the inventory at each location, and the outcome. Use it to audit routing decisions and troubleshoot unexpected results.

Filter the list by Run ID, Status, Ext Order ID, or Order ID. Select a run ID to see its details.

  • Run ID: Unique identifier for one routing attempt. One order can have several runs.
  • Ext Order ID: The order ID from the sales channel, so you can match runs to the order you know.

Routing Runs tab with filters for Run ID, Status, Ext Order ID, and Order ID and a list of runs


Troubleshooting

  • A routing rule is skipped
    The rule has no valid fulfillment location, the order doesn't match its filters, or no location has enough inventory. Check that the rule has at least one active location, review its filters, and check whether the inventory buffer or Do not check inventory affects which locations qualify.
  • An order stays in Ready For Fulfillment without a shipping request
    No rule matched the order, or no location had inventory. Use Routing Runs to see which rules were evaluated and why they failed. Add a fallback rule at the bottom of the list, or turn on Auto re-route stuck orders every 3 hours.
  • An unexpected location was chosen
    Check the order of the locations in the rule, and whether Allow split orders or Optimize for location priority is selected. If the rule uses a location group or dynamic location group, the order of locations depends on its Location prioritization strategy, so check that setting.
  • An order fails with an inventory threshold message, then routes a few minutes later
    This is expected. When inventory is at or below the inventory buffer threshold, the engine pauses about 5 minutes and retries. If the delay doesn't suit your workflow, lower or turn off the threshold in Settings.
  • Preview shows no orders
    Preview opens the All Orders page, which shows only orders ingested in the last 14 days by default. Use Test routing rules with a known order ID instead.
  • A code filter doesn't match the orders you expect
    Open the filter, load a sample order, and click Test code. Check Debug for errors, undefined fields, or type mismatches, such as comparing a number to a string.
  • Failed or out-of-stock orders aren't retried
    The orders might be older than the re-routing age limits. Check Out of stock order faster re-routing age limit and Failed order faster re-routing age limit in Settings.

Need Help?

If you need additional assistance:

  • Use Ask Pippen, our AI agent, located at the top of the app page.

  • Submit a support request with as much relevant detail as possible. Learn how to submit a request.

We're here to help you succeed with your operations.

Was this article helpful?
0 out of 0 found this helpful

Comments

0 comments

Article is closed for comments.

Have more questions?
Submit a request
Share it, if you like it.