Skip to content

Promotions & Coupons

Vectis promotions let you create discount rules that apply automatically or via coupon codes. Promotions are evaluated during checkout and allocated per line item on the resulting order.

Promotion editor — Basics

Discount Rules

Every promotion is a discount rule composed of two parts:

  • Conditions — criteria that must be met for the rule to activate.
  • Actions — the discount applied when conditions are satisfied.

Conditions

Conditions can be combined. The Add condition dialog groups built-in conditions by scope (cart, products, customer, and more):

Add condition dialog

Common condition types:

Condition Example
Cart minimum Order subtotal ≥ $500
Customer group Buyer belongs to "Gold Distributors"
Product category Cart contains items from "Safety Equipment"
Specific products Cart contains SKU WIDGET-100
Date range Between Jan 1 and Jan 31
Minimum quantity At least 20 units of qualifying items

Actions

The Add action dialog exposes every built-in discount type:

Add action dialog

Action Behavior
Percentage off Reduce qualifying line items by X%
Fixed amount off Reduce qualifying line items by a flat amount
Volume-tiered % Discount percentage grows with quantity
Bundle discount Discount activates when a bundle is matched
BOGO Buy X, get Y free (or at reduced price)
Free shipping Waive the shipping cost for the order
Free item gift Add a free gift item to the cart

Coupon Codes vs Automatic Promotions

Type How it activates Use case
Coupon code Buyer enters the code at checkout One-time offers, partner deals, targeted campaigns
Automatic Evaluated on every cart that meets conditions Site-wide sales, volume discounts, loyalty rewards

Coupon codes can have a usage limit (total redemptions) and a per-customer limit. The Usage limits tab exposes global, per-customer, per-account (B2B), per-location, per-group, and daily caps, plus a max-discount-per-redemption value cap:

Promotion usage limits

For campaigns that need many unique codes, Bulk generate produces N coupons from a template:

Bulk generate coupons

Stacking and Priority

When multiple promotions match a cart, stacking rules determine which apply:

  • Exclusive — only this promotion applies; all others are ignored. Use for "best deal wins" scenarios.
  • Stackable — combines with other stackable promotions inside the same stack group.

Promotions are evaluated in priority order (lower number = higher priority). If an exclusive promotion matches, the system stops and applies only that one.

Phase-Based Engine (Decided #162, #170, #171)

Promotions evaluate in four stages so allocation distributes correctly across line, order, shipping, and payment surfaces:

Stage Phase What it touches
100 Cart Line-item discounts (percentage, fixed amount, BOGO)
200 Order Order-subtotal discounts redistributed across lines using distribute_order_discounts
300 Shipping Shipping waivers / discounts
400 Payment Gateway-conditional surcharges or rebates

Within a stage, the engine groups stackable promotions by stack_group — promotions in the same stack group are mutually exclusive (only the highest-priority one wins), promotions in different stack groups stack additively. A configurable $0 floor (Decided #170) prevents any individual order line from going negative, even when multiple discounts pile up.

The Stacking tab controls the stacking policy, max simultaneous-in-cart, and mutually-exclusive sibling promotions:

Promotion stacking configuration

Tip

Set your best blanket discount (e.g., "20% off everything") as exclusive with high priority. Stackable promotions work well for layered discounts like "free shipping + 5% category discount."

Cart Integration (GraphQL)

Storefront code applies and removes coupons with these mutations:

mutation {
  applyCoupon(cartId: "...", code: "SUMMER20") {
    cart {
      applied_coupons { code discount_amount }
      grand_total
    }
  }
}

mutation {
  removeCoupon(cartId: "...", code: "SUMMER20") {
    cart { grand_total }
  }
}

The cart.applied_coupons field shows all active coupon codes and their computed discount amounts. Automatic promotions appear in cart.applied_promotions.

Checkout Allocation

When checkout completes, each matching promotion writes allocations to individual order lines:

  • Every line item records which promotions contributed and how much was discounted.
  • The order's discount_total is the sum of all allocations.
  • This per-line granularity supports accurate tax calculation (tax is computed on the discounted price).

Note

Promotion allocations are immutable after order creation. Editing a discount rule does not retroactively change existing orders.

Analytics

Promotion performance is tracked at two levels: a cross-promotion overview report and a per-promotion Analytics tab.

Promotion Analytics report

Analytics → Promotions is a date-ranged, channel-filtered overview across every active discount rule. It surfaces four headline KPIs (active promotions, total uses, total dispensed, average redemption rate), Top 10 charts by dispensed value and attributed revenue, a per-rule breakdown table (uses, dispensed, attributed revenue, redemption rate, ROI), and an attribution breakdown (order count, AOV, customers per promo). Results are exportable as CSV.

Promotion Analytics report

Per-promotion Analytics tab

Each promotion's editor has its own Analytics tab scoped to that single rule. It shows redemptions, dispensed value, unique customers, and average discount; a daily redemptions chart with 7/30/90-day windows; a Top 10 days by dispensed value table; and a recent-usage sidebar with the latest order-level redemptions.

Per-promotion Analytics tab

Admin Panel

From Marketing → Promotions in the admin:

  • Create / edit discount rules — set name, priority, date range, and exclusive/stackable flag.
  • Configure conditions — add one or more condition types with their parameters.
  • Configure actions — choose the discount type and amount.
  • Manage coupon codes — generate single codes or bulk batches. Set usage limits.
  • View performance — see how many times a promotion has been used and total discount given.

Warning

Deleting a promotion does not affect existing orders, but it immediately stops applying to new carts. Use the date range or disable toggle to end a promotion gracefully.

Enforcement vs Observability (Decided #152)

Promotion conditions support two enforcement modes:

  • deny_invalid_for_order — the engine enforces the condition and the promo is skipped when it doesn't apply. Usage rows are written only on successful redemption.
  • allow_warn_on_invalid — the engine logs that the condition didn't pass but still allows the promo to apply when the operator wants to observe drift (e.g., new minimum being phased in). Usage rows are written and tagged with the warn reason for the analytics report.

This split lets you measure the impact of a tighter rule before flipping it to enforcement.