EzyStudio ADF

Priorities & Strategies

Priorities & Strategies

When a discount function contains multiple rule groups, the system must determine which rules to evaluate and how to combine their results. This is controlled through two mechanisms: priority ordering (which rule evaluates first) and strategy modes (how many rules can match). Understanding these concepts is essential for building multi-rule configurations that behave predictably.


Priority Ordering

Each rule group has a priority field — an integer that determines evaluation order.

  • Lower numbers evaluate first. A rule group with priority: 1 is evaluated before one with priority: 10.
  • Rule groups are sorted by priority before any evaluation begins.
  • When two rule groups share the same priority value, their evaluation order is not guaranteed. Always use distinct priority values for deterministic behavior.
[
  { "id": "rule_vip", "priority": 1, "name": "VIP Discount" },
  { "id": "rule_sale", "priority": 2, "name": "Seasonal Sale" },
  { "id": "rule_general", "priority": 3, "name": "General Discount" }
]

In this example, the VIP rule is always evaluated first, followed by the seasonal sale, and finally the general discount.


Strategy Modes

The strategy field on the discount configuration determines how many rule groups can contribute to the final discount output. There are two modes:

“first” (Default)

The function stops at the first matching rule group and returns its discount. No subsequent rule groups are evaluated.

This is the default behavior when no strategy is specified. It creates a “waterfall” pattern where rule groups act as a priority-ordered list of mutually exclusive options.

{
  "strategy": "first",
  "ruleGroups": [
    {
      "id": "rule_vip",
      "priority": 1,
      "name": "VIP 25% Off",
      "conditions": [
        { "type": "customerTag", "operator": "hasAny", "tags": ["VIP"] }
      ]
    },
    {
      "id": "rule_general",
      "priority": 2,
      "name": "Everyone 10% Off",
      "conditions": []
    }
  ]
}

In this configuration:

  • VIP customers receive 25% off (rule 1 matches, evaluation stops).
  • All other customers receive 10% off (rule 1 fails, rule 2 matches).
  • A VIP customer never receives the 10% general discount because the first match terminates evaluation.

”all”

The function evaluates all rule groups and combines the results. Every matching rule group contributes its discount to the output.

{
  "strategy": "all",
  "ruleGroups": [
    {
      "id": "rule_volume",
      "priority": 1,
      "name": "Volume Discount 5%",
      "conditions": [
        { "type": "cartTotalQuantity", "operator": "greaterThanOrEqual", "value": 10 }
      ]
    },
    {
      "id": "rule_category",
      "priority": 2,
      "name": "Outerwear 10% Off",
      "conditions": [
        { "type": "productTag", "operator": "hasAny", "tags": ["outerwear"] }
      ]
    }
  ]
}

In this configuration:

  • A cart with 10+ items where some are outerwear would produce both discounts: volume discount on all eligible items and category discount on outerwear items.
  • Each rule group independently evaluates its conditions and contributes its own discount candidates.

Selection Strategies (Shopify-Level)

After your discount function returns its candidates, Shopify applies its own selection strategy to determine the final discounts. This behavior varies by discount operation type and is not configurable — it is built into the Shopify platform.

Operation TypeSelection StrategyMeaning
ProductDiscountsAddAllAll product discount candidates returned by the function are applied (stacked)
OrderDiscountsAddMaximumShopify picks the single highest-value order discount candidate
DeliveryDiscountsAddAllAll shipping discount candidates are applied

Key Implications

  • Product discounts from a single function are stacked. If your function returns multiple product discount candidates (via the "all" strategy with multiple matching rule groups), Shopify applies all of them.
  • Order discounts from a single function are deduplicated. Even if multiple rule groups match and each returns an order discount, Shopify selects only the one with the highest value.
  • Shipping discounts from a single function are stacked, similar to product discounts.

Strategy vs. Stacking

It is important to distinguish between strategy (within one function) and stacking (across functions and discounts):

ConceptScopeControlled By
StrategyWithin a single discount functionThe strategy field in your configuration
StackingAcross multiple discounts and functionsShopify’s combinesWith settings on the discount

Strategy determines which rule groups within your single function produce output. For example, with the "first" strategy, only one rule group can win.

Stacking determines whether your discount can combine with other discounts on the store. This is configured at the Shopify discount level through the combinesWith object, which specifies whether your discount can stack with product discounts, order discounts, and/or shipping discounts from other sources.


Examples

Example 1: “First” Strategy for Tiered Customer Pricing

A common pattern uses the “first” strategy with descending priority to create tiered pricing based on customer segments:

{
  "strategy": "first",
  "ruleGroups": [
    {
      "id": "tier_platinum",
      "priority": 1,
      "name": "Platinum Members - 30% Off",
      "enabled": true,
      "conditionLogic": "and",
      "conditions": [
        { "type": "customerTag", "operator": "hasAny", "tags": ["platinum"] }
      ]
    },
    {
      "id": "tier_gold",
      "priority": 2,
      "name": "Gold Members - 20% Off",
      "enabled": true,
      "conditionLogic": "and",
      "conditions": [
        { "type": "customerTag", "operator": "hasAny", "tags": ["gold"] }
      ]
    },
    {
      "id": "tier_silver",
      "priority": 3,
      "name": "Silver Members - 10% Off",
      "enabled": true,
      "conditionLogic": "and",
      "conditions": [
        { "type": "customerTag", "operator": "hasAny", "tags": ["silver"] }
      ]
    }
  ]
}

A customer tagged as both “platinum” and “gold” receives only the 30% platinum discount because evaluation stops at the first match.

Example 2: “All” Strategy for Stacking Volume and Category Discounts

When discounts should be additive, use the “all” strategy:

{
  "strategy": "all",
  "ruleGroups": [
    {
      "id": "volume_discount",
      "priority": 1,
      "name": "Buy 5+ Items - 5% Off",
      "enabled": true,
      "conditionLogic": "and",
      "conditions": [
        { "type": "cartTotalQuantity", "operator": "greaterThanOrEqual", "value": 5 }
      ]
    },
    {
      "id": "category_discount",
      "priority": 2,
      "name": "Electronics - 10% Off",
      "enabled": true,
      "conditionLogic": "and",
      "conditions": [
        { "type": "collection", "operator": "inAny", "collectionIds": ["gid://shopify/Collection/123456789"] }
      ]
    }
  ]
}

A cart with 5+ items that includes electronics would receive both discounts: 5% off all items from the volume rule and an additional 10% off electronics from the category rule.