Promotions V2 is a new promotions engine that runs in parallel with the original V1 promotions system. V1 promotions are unchanged — V2 is additive, not a replacement. Both engines evaluate independently and can be active on the same store simultaneously.

## How V2 differs from V1

| Capability | V1 | V2 |
|------------|----|----|
| Coupon-based promotions | Yes | Yes |
| Automatic promotions (no code) | No | Yes |
| Advanced scheduling | Date range only | Dates, times, daily windows, days of week, recurring |
| Stacking between promotions | Limited | Configurable (stackable / not stackable / stop) |
| Multiple reward tiers | No | Yes (tiered or stacked strategy) |
| Channel scoping | No | Store or outlet |
| Customer scoping | Contact, account, or membership (via PromotionScope records — multiple combinations supported per promotion) | Contact, account, or membership (set on the promotion header directly — one scope value per promotion) |
| Usage limits | Total only | Total and per-customer |
| Usage tracking | Promotion Credits | Promotion 2 Usage records |

## Salesforce objects

Promotions V2 uses four objects:

| Object | Purpose |
|--------|---------|
| **Condition** (`s_c__Condition__c`) | Defines what qualifies (e.g., spend $50, buy 3 items). See [Condition Object Reference](condition-object-reference). |
| **Reward** (`s_c__Reward__c`) | Defines what discount to apply (e.g., 10% off, free shipping). See [Reward Object Reference](reward-object-reference). |
| **Promotion 2** (`s_c__Promotion2__c`) | Promotion header with scheduling, scoping, and stacking rules |
| **Promotion 2 Condition** (`s_c__Promotion2Condition__c`) | Links a Condition and Reward to a Promotion 2 |

Conditions and Rewards are reusable — the same Condition or Reward can be used across multiple Promotion 2 records.

## Conditions

A Condition defines what must be true for a reward to apply. The following condition types are available:

| Type | Description |
|------|-------------|
| `always_applies` | No qualification required — always applies |
| `total_value` | Minimum cart value (after product filtering). Set the threshold in the **Amount** field on the Condition record. |
| `total_quantity` | Minimum item count (after product filtering). Set the threshold in the **Amount** field on the Condition record. |
| `product_count` | Minimum count of distinct products (after product filtering). Set the threshold in the **Amount** field on the Condition record. |
| `liquid_condition` | Custom Liquid template evaluated at runtime |

Conditions can be scoped to specific products, categories, brands, or shipping zones using [Promotion 2 Product Scope](promotion2-product-scope-object-reference) records. When product scopes are set on a condition, the cart is filtered to matching items before the condition is evaluated. Shipping zone scopes restrict the condition to carts with a delivery address in a matching zone.

An optional **Currency** field on the Condition restricts it to carts in a specific currency. Leave blank to apply to all currencies.

## Rewards

A Reward defines what discount to apply when a condition is met:

| Type | Description |
|------|-------------|
| `discount_on_subtotal` | Percentage or fixed amount off the cart subtotal |
| `discount_on_products` | Percentage or fixed amount off matched or specified products |
| `discounted_shipping` | Percentage or fixed amount off shipping charges (100% = free shipping) |
| `free_product` | Adds free products from a specified set (defined via product scopes). Set **Quantity** for how many free items to add. |
| `fixed_price_for_n_products` | Sets a fixed price for a quantity of matching products. Set **Quantity** for N and **Fixed Amount** for the price. |

For product-level rewards, configure:
- **Apply to** — `matched_products` (items from the condition's scope) or `specified_products` (from the reward's own scopes)
- **Apply first to** — `most_expensive` or `least_expensive`
- **Max eligible** — limit the discount to N items
- **Exclude discounted** — skip items already discounted
- **Exclude free** — skip items already free

The **Frequency** field controls how many times the reward applies per promotion evaluation. `once` (default) applies the reward once per evaluation. `no_limit` allows the reward to repeat for each qualifying group of items — useful for repeating discounts (e.g., every 3 items get 10% off).

## Reward strategy

Each Promotion 2 record has a **Reward Strategy** that controls how multiple Promotion 2 Conditions are evaluated:

| Strategy | Behavior |
|----------|----------|
| **Tiered** (default) | Only the highest-priority matching condition applies its reward. Use this for spend-and-save tiers: "Spend $50 get $5 off, Spend $100 get $15 off" — only the best tier applies. |
| **Stacked** | All matching conditions apply their rewards. Use this when multiple independent discounts should accumulate. |

## Stacking between promotions

When multiple Promotion 2 records are active simultaneously, stacking rules control how they interact:

| Field | Value | Behavior |
|-------|-------|----------|
| **Stacking Behaviour** | `stackable` | Can combine with other promotions |
| **Stacking Behaviour** | `not_stackable` | Conflicts with other non-stackable promotions |
| **Stacking Priority** | `existing_promotions` | When conflict arises, keep the promotions already applied |
| **Stacking Priority** | `biggest_reward` | When conflict arises, keep whichever gives the biggest discount |
| **Stop After This Promo** | `true` | Stop evaluating further promotions once this one applies |

Promotions are evaluated in ascending order of **Priority**. Lower numbers run first.

## Scheduling

V2 promotions support fine-grained scheduling:

| Field | Description |
|-------|-------------|
| **Start Date** | Date from which the promotion is active (leave blank to activate immediately) |
| **End Date** | Date after which the promotion is no longer active (optional — no end date = runs indefinitely) |
| **Start Time** | Time on the start date from which the promotion activates |
| **End Time** | Time on the end date after which the promotion deactivates |
| **From Time** | Daily window start — promotion only applies after this time each day |
| **To Time** | Daily window end — promotion only applies before this time each day |
| **Days of Week** | Specific days the promotion is active (0 = Sunday, 6 = Saturday) |
| **Week Frequency** | Recurrence — 1 = every week, 2 = every two weeks, etc. (from start date) |
| **Timezone** | Timezone for all time-based fields. Defaults to the store's timezone. |

## Scoping

### Channel scope

Restrict a promotion to a specific channel using one of the following (mutually exclusive):

| Field | Description |
|-------|-------------|
| **Channel Scope Store** | Restrict to orders from a specific store |
| **Channel Scope Outlet** | Restrict to orders from a specific outlet (POS) |

Leave both blank to allow the promotion on all channels.

### Customer scope

Restrict a promotion to a specific customer using one of the following (mutually exclusive):

| Field | Description |
|-------|-------------|
| **Customer Scope Contact** | Restrict to a single contact |
| **Customer Scope Account** | Restrict to a single account (all contacts under it) |
| **Customer Scope Membership** | Restrict to contacts with a specific active membership |

Leave all blank to allow the promotion for all customers.

## Coupon codes

- Leave **Coupon Code** blank for automatic promotions — these apply without customer action.
- Set a **Coupon Code** for promotions that require customer entry at checkout.

Coupon code matching is case-insensitive. Multiple Promotion 2 records can be active simultaneously, but stacking rules control which discounts actually apply.

## Customer experience at checkout

**Automatic promotions** (blank Coupon Code) apply silently as soon as the cart meets the promotion's conditions. No customer input is needed. The discount appears in the cart totals and order summary automatically.

**Coupon-code promotions** require the customer to enter a code at web checkout. Applied coupon codes and their discounts are shown in the cart and order summary. Customers can remove a coupon-code promotion from their cart if they choose. Automatic promotions cannot be manually removed — they apply or withdraw based on whether the cart still meets the conditions.

**Free product rewards** add a complimentary product line item to the customer's cart when the promotion applies. The free item appears as a separate line at $0. If the promotion conditions are no longer met (for example, the customer removes qualifying items), the free product line is removed automatically.

:::note
The `promotions.max_coupon_codes_per_cart` store variable limits how many coupon codes a customer can apply to a single cart. See [Store variables](store-variables) for configuration details.
:::

## Usage limits

| Field | Description |
|-------|-------------|
| **Total Usage Limit** | Maximum total uses across all customers. Leave blank for unlimited. |
| **Per Customer Usage Limit** | Maximum uses per customer. Leave blank for unlimited. |

Usage is tracked via [Promotion 2 Usage](promotion2-usage-object-reference) records created when a promotion applies at checkout.

## Configuring a Promotion 2 in Salesforce

1. Create or identify the **Condition** records you need (one per tier or scenario).
2. Create or identify the **Reward** records you need.
3. Create a **Promotion 2** record:
   - Set the **Store**
   - Set a **Start Date**
   - Choose a **Reward Strategy** (Tiered or Stacked)
   - Configure stacking, scheduling, scoping, and usage limits as needed
   - Optionally set a **Coupon Code**
4. Create one or more **Promotion 2 Condition** records linking the Promotion 2 to its Condition–Reward pairs. Set **Priority** to control evaluation order within the promotion.
5. If product filtering is needed, create **Promotion 2 Product Scope** records on the Condition or Reward to include or exclude specific products, categories, or brands.

:::note
V1 promotions and V2 promotions evaluate independently. A cart can receive discounts from both V1 and V2 promotions simultaneously. To prevent overlap, use channel or customer scoping to isolate V2 promotions, or move your workflows to V2 entirely.
:::

## Object references

- [Condition Object Reference](condition-object-reference)
- [Reward Object Reference](reward-object-reference)
- [Promotion 2 Object Reference](promotion2-object-reference)
- [Promotion 2 Condition Object Reference](promotion2-condition-object-reference)
- [Promotion 2 Product Scope Object Reference](promotion2-product-scope-object-reference)
- [Promotion 2 Usage Object Reference](promotion2-usage-object-reference)