OfferKitDocs

Build an automatic cart discount

Build automatic cart discounts with OfferKit promotion tiers, qualify eligible offers from customer and cart data, and apply the selected result.

Use an automatic promotion when the customer should receive a benefit because their cart qualifies, without entering a code. Examples include “USD 10 off orders over USD 100” and tiered offers where a larger cart earns a larger discount.

Design the customer experience

Decide whether your storefront will:

  • apply the result selected by your priority and exclusivity settings;
  • show all eligible benefits and let the customer choose;
  • show progress before qualification, such as “Spend USD 12 more”; or
  • explain that another exclusive offer won.

OfferKit returns eligible and skipped tiers plus a calculated preview. Your application decides how to present and persist that result.

Configure the promotion

  1. In Campaigns, create a PROMOTION campaign.
  2. Enable Auto-apply at checkout.
  3. Set the currency, dates, and campaign-wide validation rule.
  4. Activate the campaign.
  5. Add one or more promotion tiers to the campaign.

Each tier has its own name, fixed or percentage effect, optional rule and activation window, priority, and exclusivity setting.

For “USD 10 off USD 100; USD 25 off USD 200,” create two tiers and attach an order-total rule to each. Give the more valuable tier higher priority. Make it exclusive if only one tier should win.

Qualify the cart

Call qualification from your server whenever relevant customer or cart context changes:

const result = await offerkit.promotions.qualify({
  customerId: customer.id,
  order: {
    amount: cart.totalCents,
    currency: cart.currency,
    items: cart.items.map((item) => ({
      productId: item.productId,
      collectionId: item.collectionId,
      quantity: item.quantity,
      unitPrice: item.unitPriceCents,
    })),
  },
  metadata: { channel: "web" },
  filters: { includeSkipped: true },
});

Use:

  • eligible to identify the promotion tiers that survived all checks;
  • preview.amount for the combined discount;
  • preview.finalOrder.amount for the calculated post-discount amount;
  • skipped to debug or explain why a tier did not apply.

Qualification is read-only. In the current promotion surface, it does not create a redemption ledger row. Persist the chosen promotion tier IDs and applied amount with your order so the final commercial decision is auditable in your system.

Re-run at the commit boundary

Do not rely on a browser-held result. Re-run qualification on your server immediately before accepting the order, using the final customer, items, prices, and currency. If the result changed, update the order or ask the customer to review it again.

Priority and exclusivity

Larger priority numbers run first. If any eligible tier is exclusive, only the highest-priority exclusive tier contributes a monetary discount; all other tiers lose, even non-exclusive tiers with a larger priority number. Without an exclusive tier, non-exclusive tiers combine against the running order total until it reaches zero. Equal-priority promotion tiers are ordered by ID. Priority is a configured preference, not a search for the largest possible saving.

The response identifies skipped tiers with reasons such as exclusivity_lost, zero_after_running_total, currency_mismatch, or rule_failed.

Test before launch

Test every boundary around each tier, including one minor unit below and at a spend threshold. Also test:

  • campaign and tier activation windows;
  • wrong currency;
  • missing customer context for customer rules;
  • two simultaneously eligible tiers;
  • an exclusive tier with lower-priority competitors;
  • a discount larger than the remaining cart amount.

Operate the promotion

Pause the parent campaign to stop every tier. Disable one tier when only that level is incorrect. When changing live rules, retest the boundary carts that originally justified the campaign.

If the customer must present a code or you need a redemption ledger and usage limits, use Run a promotional code instead.

What auto-apply does

autoApply includes a PROMOTION campaign in qualification. Setting it on a DISCOUNT campaign does not make its vouchers automatic. Your storefront still has to call qualification and apply the returned amount to its own order.

Promotion qualification creates no usage counter, stored redemption, or promotion event. There is no promotion commit call or reservation. If you need a one-use or per-customer limit, use a voucher. If you combine promotions with voucher discounts, pass the amount remaining after the promotion to the voucher calculation. Promotion exclusivity only compares promotion tiers; it does not exclude voucher codes. See the checkout calculation example.

Product conditions can qualify a tier, but effect.appliesTo does not restrict the calculated discount to matching items. The discount uses the submitted order amount.