> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usecharlie.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Cart Rules

> Prioritize fulfillment locations based on cart properties

Cart rules let you prioritize locations based on **cart properties**. When a cart meets specific criteria like total quantity, total amount, or contains items with specific attributes, you can control which locations should be preferred for fulfillment.

<Info>
  Unlike [fulfillment constraints](/constraints/cart-rules) which **block** locations, cart routing rules **prioritize** locations. If the preferred location is out of stock, Shopify automatically falls back to the next available location.
</Info>

## Constraints vs Routing

|                                       | Fulfillment Constraints                             | Order Routing Rules                                                         |
| ------------------------------------- | --------------------------------------------------- | --------------------------------------------------------------------------- |
| **Effect**                            | Blocks locations entirely                           | Ranks locations by preference                                               |
| **If no stock at preferred location** | Checkout blocked                                    | Falls back to next priority                                                 |
| **Configured in**                     | Charlie app                                         | Shopify Order Routing settings                                              |
| **Use case**                          | "Orders > €500 can ONLY ship from secure warehouse" | "Prefer secure warehouse for high-value orders, but allow stores as backup" |

## How cart routing rules work

A cart routing rule has two parts:

1. **When** (condition): Which cart properties trigger the rule
2. **Then** (groups): How to rank locations when triggered

```mermaid theme={"system"}
flowchart LR
    A[Customer reaches<br/>checkout] --> B{Cart matches<br/>rule condition?}
    B -->|No| C[Default routing<br/>applies]
    B -->|Yes| D[Apply location<br/>group ranking]
    D --> E[Try Group 1 first]
    E --> F{Stock<br/>available?}
    F -->|Yes| G[✅ Fulfill from Group 1]
    F -->|No| H[Try Group 2]
    H --> I[Continue to next group...]
```

## Configure a cart routing rule

<Steps>
  <Step title="Access order routing settings">
    Go to **Charlie → Settings → Order routing** or **Shopify → Settings → Shipping and delivery → Order routing**.
  </Step>

  <Step title="Add the Cart Rules rule">
    Find Charlie's **Cart Rules** and add it to your routing strategy.
  </Step>

  <Step title="Configure the condition (When)">
    Set up which cart properties trigger this rule:

    | Condition                   | Description                                    |
    | --------------------------- | ---------------------------------------------- |
    | **Total cart quantity**     | Total number of items in the cart              |
    | **Total cart amount**       | Total value of the cart in your store currency |
    | **Line item has attribute** | Items with specific custom attributes          |

    Choose the appropriate operator and enter the value.
  </Step>

  <Step title="Configure location groups (Then)">
    Create ranked groups of locations. Group 1 has highest priority, Group 2 is the fallback, and so on.

    For each group, click **Add selector** and choose how to select locations:

    | Selector type          | Description                          |
    | ---------------------- | ------------------------------------ |
    | **Specific locations** | Choose individual locations manually |
    | **Location type**      | All Warehouses or all Stores         |
    | **Location tag**       | Locations with specific tags         |

    <Tip>
      Locations that don't match any group will be ranked last.
    </Tip>
  </Step>

  <Step title="Enable the rule">
    Toggle the rule to **Enabled** when you're ready to apply it to live orders.
  </Step>
</Steps>

## Condition types

<Tabs>
  <Tab title="Total cart quantity">
    Triggers based on the total number of items in the cart.

    **Operators available:**

    | Operator                  | Description                                |
    | ------------------------- | ------------------------------------------ |
    | **Equal**                 | Cart has exactly this many items           |
    | **Not Equal**             | Cart does not have exactly this many items |
    | **Greater Than**          | Cart has more than this many items         |
    | **Less Than**             | Cart has fewer than this many items        |
    | **Greater Than Or Equal** | Cart has this many or more items           |
    | **Less Than Or Equal**    | Cart has this many or fewer items          |

    **Best for:**

    * Routing bulk orders to warehouses
    * Preferring stores for single-item orders
  </Tab>

  <Tab title="Total cart amount">
    Triggers based on the total value of the cart.

    **Operators available:** Same as Total cart quantity

    **Best for:**

    * Preferring secure locations for high-value orders
    * Routing premium orders to flagship stores
  </Tab>

  <Tab title="Line item has attribute">
    Triggers based on custom attributes attached to line items.

    **Operators available:**

    | Operator       | Description                     |
    | -------------- | ------------------------------- |
    | **Equal**      | Attribute value exactly matches |
    | **Not Equal**  | Attribute value does not match  |
    | **Is Set**     | Attribute exists (any value)    |
    | **Is Not Set** | Attribute does not exist        |

    **Best for:**

    * Gift-wrapped items preferring stores with gift services
    * Personalized items preferring specialty locations
    * Pre-order items preferring specific fulfillment centers

    <Note>
      With line item attributes, the routing applies only to the specific items matching the attribute. Other items in the cart follow default routing.
    </Note>
  </Tab>
</Tabs>

## Examples

### Large orders prefer warehouse

A retailer wants orders with more than 10 items to prefer warehouse fulfillment for efficient bulk packing.

<Steps>
  <Step title="Create the rule">
    * **Condition:** Total cart quantity
    * **Operator:** Greater Than
    * **Value:** 10
  </Step>

  <Step title="Configure groups (Then)">
    * **Group 1:** Location type = Warehouse
    * **Group 2:** Location type = Store
  </Step>
</Steps>

**Result:** Large orders prefer warehouses. If the warehouse is out of stock, stores can still fulfill. No checkout blocking.

***

### High-value orders prefer secure locations

A jewelry retailer wants orders over €500 to prefer locations with secure handling and insurance.

<Steps>
  <Step title="Tag secure locations">
    Add the tag `high-value-certified` to locations with secure handling processes.
  </Step>

  <Step title="Create the rule">
    * **Condition:** Total cart amount
    * **Operator:** Greater Than
    * **Value:** 500
  </Step>

  <Step title="Configure groups (Then)">
    * **Group 1:** Location tag = `high-value-certified`
    * **Group 2:** Location type = Warehouse
    * **Group 3:** Location type = Store
  </Step>
</Steps>

**Result:** High-value orders prefer certified locations. If out of stock, other warehouses are tried, then stores.

***

### Gift-wrapped items prefer flagship stores

A fashion brand offers gift wrapping, and wants these items to prefer stores with premium packaging services.

<Steps>
  <Step title="Tag capable stores">
    Add the tag `gift-wrap-capable` to stores with gift wrapping services.
  </Step>

  <Step title="Create the rule">
    * **Condition:** Line item has attribute
    * **Operator:** Equal
    * **Attribute key:** `gift_wrap`
    * **Attribute value:** `true`
  </Step>

  <Step title="Configure groups (Then)">
    * **Group 1:** Location tag = `gift-wrap-capable`
    * **Group 2:** Location type = Store
    * **Group 3:** Location type = Warehouse
  </Step>
</Steps>

**Result:** Gift-wrapped items prefer stores with gift services. Other items in the same cart follow default routing.

***

### Small orders prefer local stores

A retailer wants single-item orders to prefer nearby stores for faster delivery.

<Steps>
  <Step title="Create the rule">
    * **Condition:** Total cart quantity
    * **Operator:** Equal
    * **Value:** 1
  </Step>

  <Step title="Configure groups (Then)">
    * **Group 1:** Location type = Store
    * **Group 2:** Location type = Warehouse
  </Step>
</Steps>

**Result:** Single-item orders prefer stores (potentially closer to the customer). Warehouses are the backup.

## Combining with constraints

For maximum control, combine routing rules with constraints:

| Rule type        | Purpose                                        |
| ---------------- | ---------------------------------------------- |
| **Constraint**   | Block locations that absolutely cannot fulfill |
| **Routing rule** | Prioritize among remaining eligible locations  |

**Example: High-value order strategy**

1. **Fulfillment Constraint:** Orders > €1000 → Include only locations tagged `insured`
   → Uninsured locations are **blocked**

2. **Cart Routing Rule:** Orders > €500 → Prefer locations tagged `secure-packaging`
   → Secure locations are **preferred** among eligible locations

**Result:** Very high-value orders (>€1000) can only ship from insured locations. High-value orders (>€500) prefer secure packaging locations among those eligible.

## Combining with other routing rules

Cart rules work well with other routing rules:

| Combination                | Use case                                              |
| -------------------------- | ----------------------------------------------------- |
| **Cart + Inventory Rules** | Large orders prefer warehouses with most stock        |
| **Cart + Customer Rules**  | VIP customers with large orders get premium treatment |
| **Cart + Capacity Rules**  | Bulk orders avoid locations at capacity               |

**Example setup:**

1. **Cart Rules:** Orders > 10 items → Prefer warehouses
2. **Inventory Rules:** Among warehouses, prefer those with most stock
3. **Capacity Rules:** Deprioritize locations near capacity

**Result:** Large orders go to the warehouse with the most stock that isn't overloaded.

## Best practices

<CardGroup cols={2}>
  <Card title="Use quantity for operational efficiency" icon="boxes-stacked">
    Route bulk orders to locations equipped for efficient multi-item packing.
  </Card>

  <Card title="Use amount for risk management" icon="shield">
    Prefer secure locations for high-value orders without blocking checkout.
  </Card>

  <Card title="Use attributes for special handling" icon="wand-magic-sparkles">
    Route items with special requirements to capable locations.
  </Card>

  <Card title="Combine with inventory rules" icon="warehouse">
    Add Inventory Rules to prefer locations with stock among the prioritized group.
  </Card>
</CardGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Orders not routing to expected locations">
    **Check:**

    1. Is the rule **enabled**?
    2. Does the cart actually meet the condition? (Check quantity/amount/attributes)
    3. Does the preferred location have stock?
    4. Are there constraint rules blocking the location?
    5. Is another routing rule with higher priority overriding this one?
  </Accordion>

  <Accordion title="Line item attribute rule not triggering">
    **Check:**

    1. Is the attribute key spelled exactly right? (Case-sensitive)
    2. Is the attribute actually being set on the line item? Check the cart data in your theme.
    3. For "Equal" operator, does the value match exactly?
  </Accordion>

  <Accordion title="Wrong group being selected">
    Remember: Shopify tries groups in order and uses the first one with available stock. If Group 1 is out of stock, it moves to Group 2 automatically.

    Verify stock levels at each location for the products in question.
  </Accordion>

  <Accordion title="Threshold not working as expected">
    Check your operator:

    * **Greater Than 10** triggers at 11+ items (not 10)
    * **Greater Than Or Equal 10** triggers at 10+ items

    Use the right operator for your threshold.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Cart Constraints" icon="ban" href="/constraints/cart-rules">
    Block locations based on cart properties (hard rules)
  </Card>

  <Card title="Customer Rules" icon="user" href="/order-routing/customer-rules">
    Prioritize by who is buying
  </Card>

  <Card title="Inventory Rules" icon="warehouse" href="/order-routing/inventory-rules">
    Prioritize by stock availability
  </Card>

  <Card title="Capacity Rules" icon="gauge-high" href="/order-routing/capacity-rules">
    Prioritize by location capacity
  </Card>
</CardGroup>
