Priority System: Why Order Matters
CRITICAL CONCEPT
The priority system is the most misunderstood feature of Shopify Delivery Checkout. Understanding it correctly will save you hours of troubleshooting.
The Core Problem
When multiple rules match the same cart conditions, only ONE rule is applied. The system uses priority to determine which rule wins.
Priority Numbers Explained
- Priority 0 = Highest priority (executed first)
- Priority 1 = Second highest
- Priority 2 = Third highest
- And so on...
REMEMBER
Lower number = Higher priority
Think of it like race positions: 1st place, 2nd place, 3rd place.
The Common Mistake
Let's examine a real-world scenario that confuses many users:
❌ What Users Expect (But Doesn't Happen)
Users create these rules thinking heavier carts will match the higher prices:
[
{
"name": "Over 10kg €50",
"price": 50.00,
"priority": 2,
"conditions": [{"type": "cart_weight", "value": ["10"], "operator": ">"}]
},
{
"name": "Over 20kg €100",
"price": 100.00,
"priority": 1,
"conditions": [{"type": "cart_weight", "value": ["20"], "operator": ">"}]
},
{
"name": "Over 30kg €200",
"price": 200.00,
"priority": 0,
"conditions": [{"type": "cart_weight", "value": ["30"], "operator": ">"}]
}
]
User's cart: 35kg
What they expect:
- ✅ Matches "Over 10kg" → Yes (35 > 10)
- ✅ Matches "Over 20kg" → Yes (35 > 20)
- ✅ Matches "Over 30kg" → Yes (35 > 30)
- Result: €200 charge (the 30kg rule)
What actually happens:
- System evaluates rules in priority order (0, 1, 2)
- Priority 0: "Over 30kg" → MATCHES (35 > 30) → Apply €200
- STOP - First matching rule found
Looks correct, right? Now let's see what breaks...
❌ The Actual Problem
User's cart: 25kg
What they expect:
- ✅ Matches "Over 10kg" → Yes (25 > 10)
- ✅ Matches "Over 20kg" → Yes (25 > 20)
- ❌ Matches "Over 30kg" → No (25 < 30)
- Result: €100 charge (the 20kg rule)
What actually happens:
- System evaluates rules in priority order (0, 1, 2)
- Priority 0: "Over 30kg" → FAILS (25 < 30)
- Priority 1: "Over 20kg" → MATCHES (25 > 20) → Apply €100
- STOP - First matching rule found
This works! But wait...
User's cart: 15kg
What they expect:
- ✅ Matches "Over 10kg" → Yes (15 > 10)
- ❌ Matches "Over 20kg" → No (15 < 20)
- ❌ Matches "Over 30kg" → No (15 < 30)
- Result: €50 charge (the 10kg rule)
What actually happens:
- System evaluates rules in priority order (0, 1, 2)
- Priority 0: "Over 30kg" → FAILS (15 < 30)
- Priority 1: "Over 20kg" → FAILS (15 < 20)
- Priority 2: "Over 10kg" → MATCHES (15 > 10) → Apply €50
- STOP - First matching rule found
Still works! So what's the issue?
🔴 The Breaking Point
User's cart: 12kg
What they expect:
- ✅ Matches "Over 10kg" → Yes (12 > 10)
- ❌ Matches "Over 20kg" → No (12 < 20)
- ❌ Matches "Over 30kg" → No (12 < 30)
- Result: €50 charge (the 10kg rule)
What actually happens:
- System evaluates rules in priority order (0, 1, 2)
- Priority 0: "Over 30kg" → FAILS (12 < 30)
- Priority 1: "Over 20kg" → FAILS (12 < 20)
- Priority 2: "Over 10kg" → MATCHES (12 > 10) → Apply €50
- STOP
Wait, this works too! So when does it actually break?
💥 The Real Breaking Scenario
The issue arises when users reorder priorities thinking higher numbers should match higher weights:
User mistakenly changes to:
[
{
"name": "Over 10kg €50",
"price": 50.00,
"priority": 0, // Changed to highest priority
"conditions": [{"type": "cart_weight", "value": ["10"], "operator": ">"}]
},
{
"name": "Over 20kg €100",
"price": 100.00,
"priority": 1,
"conditions": [{"type": "cart_weight", "value": ["20"], "operator": ">"}]
},
{
"name": "Over 30kg €200",
"price": 200.00,
"priority": 2, // Changed to lowest priority
"conditions": [{"type": "cart_weight", "value": ["30"], "operator": ">"}]
}
]
User's cart: 35kg
What happens:
- System evaluates rules in priority order (0, 1, 2)
- Priority 0: "Over 10kg" → MATCHES (35 > 10) → Apply €50
- STOP - First matching rule found
Result: ❌ €50 charge instead of €200!
The 35kg cart gets charged the minimum price because the "Over 10kg" rule matches first and stops execution.
The Solution: Inverted Priority Logic
✅ Correct Configuration
For tiered pricing based on increasing thresholds, assign priorities in reverse order:
[
{
"name": "Over 30kg €200",
"price": 200.00,
"priority": 0, // Highest priority - check most restrictive first
"conditions": [{"type": "cart_weight", "value": ["30"], "operator": ">"}]
},
{
"name": "Over 20kg €100",
"price": 100.00,
"priority": 1, // Second priority
"conditions": [{"type": "cart_weight", "value": ["20"], "operator": ">"}]
},
{
"name": "Over 10kg €50",
"price": 50.00,
"priority": 2, // Lowest priority - catch-all for lighter weights
"conditions": [{"type": "cart_weight", "value": ["10"], "operator": ">"}]
}
]
Why This Works
| Cart Weight | Evaluation Flow | Result |
|---|---|---|
| 35kg | Priority 0 (30kg) ✅ MATCH → STOP | €200 ✓ |
| 25kg | Priority 0 (30kg) ❌ → Priority 1 (20kg) ✅ MATCH → STOP | €100 ✓ |
| 15kg | Priority 0 (30kg) ❌ → Priority 1 (20kg) ❌ → Priority 2 (10kg) ✅ MATCH → STOP | €50 ✓ |
| 8kg | Priority 0 (30kg) ❌ → Priority 1 (20kg) ❌ → Priority 2 (10kg) ❌ → Base price | Base price ✓ |
Key Principles
GOLDEN RULE
Most Specific → Most General
Assign Priority 0 to your most restrictive/specific conditions, and increase the priority number as conditions become more general.
For Increasing Thresholds
Priority 0: Highest threshold (e.g., >30kg)
Priority 1: Medium threshold (e.g., >20kg)
Priority 2: Lowest threshold (e.g., >10kg)
For Decreasing Discounts
Priority 0: Largest order discount (e.g., >€500 → 20% off)
Priority 1: Medium order discount (e.g., >€200 → 10% off)
Priority 2: Small order discount (e.g., >€100 → 5% off)
Visual Execution Flow
┌─────────────────────────────────┐
│ Cart: 35kg │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Priority 0: Weight > 30kg? │
│ YES → Apply €200 → STOP │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ Cart: 25kg │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Priority 0: Weight > 30kg? │
│ NO → Continue │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Priority 1: Weight > 20kg? │
│ YES → Apply €100 → STOP │
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ Cart: 15kg │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Priority 0: Weight > 30kg? │
│ NO → Continue │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Priority 1: Weight > 20kg? │
│ NO → Continue │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Priority 2: Weight > 10kg? │
│ YES → Apply €50 → STOP │
└─────────────────────────────────┘
Testing Your Priority Configuration
Use these test cases to verify your rules work correctly:
- Test boundary conditions: Try weights like 10.1kg, 20.1kg, 30.1kg
- Test between thresholds: Try 15kg, 25kg, 35kg
- Test below minimum: Try 5kg
- Test edge cases: Try exactly 10kg, 20kg, 30kg
Common Priority Patterns
Pattern 1: Tiered Pricing
[
{ "name": "Premium", "priority": 0, "conditions": [{"value": ["1000"], "operator": ">"}] },
{ "name": "Standard", "priority": 1, "conditions": [{"value": ["500"], "operator": ">"}] },
{ "name": "Basic", "priority": 2, "conditions": [{"value": ["100"], "operator": ">"}] }
]
Pattern 2: Location-Based with Fallback
[
{ "name": "Rural Surcharge", "priority": 0, "conditions": [{"type": "postcode", "value": ["rural_area"]}] },
{ "name": "Standard Rate", "priority": 1, "conditions": [{"type": "country", "value": ["US"]}] }
]
Pattern 3: Product-Specific Overrides
[
{ "name": "Hazardous Material", "priority": 0, "conditions": [{"type": "product_tag", "value": ["hazmat"]}] },
{ "name": "Oversized Item", "priority": 1, "conditions": [{"type": "product_tag", "value": ["oversized"]}] },
{ "name": "Standard Shipping", "priority": 2, "conditions": [{"type": "cart_weight", "value": ["0"], "operator": ">"}] }
]
Debugging Priority Issues
If your rules aren't working as expected:
- List your rules by priority (0, 1, 2, ...)
- For each rule, ask: "Is this more specific than the next rule?"
- If YES: Priority is correct
- If NO: Swap the priorities
Example debugging session:
Priority 0: Weight > 10kg
Priority 1: Weight > 30kg
Question: Is "Weight > 10kg" more specific than "Weight > 30kg"?
Answer: NO - 30kg is more restrictive than 10kg
Action: Swap priorities
✅ Priority 0: Weight > 30kg
✅ Priority 1: Weight > 10kg
Next Steps
- Common Scenarios - See more real-world examples
- Troubleshooting - Fix priority-related issues
