Ulsav Docs
Passes

Coupons

Codes, immutable rule versions, caps, automatic selection, and the one-coupon-per-Order rule

A Coupon is a discount you fund: a set of terms plus one or more codes a buyer can type. It is the only way a buyer can take money off an Order, and exactly one Coupon applies per Order.

Coupons are worth the care because they interact with almost everything else: they lower the taxable base, lower the platform fee's percentage leg, hold capacity while a checkout is open, and have to be reversed exactly when someone is refunded.

  • Per Order

    Exactly one

    Never stacked, never combined

  • Funded by

    The Organization

    Ulsav's fee falls with the discount

  • Terms

    Immutable versions

    Editing publishes a new version

  • Discounts

    The offer price

    Never the list price

  • Discovery

    Public or unlisted

    Public codes can auto-apply

  • Caps

    Uses, budget, one Account

    Counted from redemptions

Three objects, not one

ObjectWhat it is
CouponThe durable identity: a name, a description, and the current terms
CouponRuleVersionOne published set of terms, frozen the moment you save it
CouponCodeThe string a buyer types, with its own caps and its own window

Editing a Coupon does not overwrite anything. It publishes a new rule version, and every past redemption keeps pointing at the version it used. That is what lets you explain a two-month-old Order after three price changes.

A code is 2 to 50 characters and is stored in upper case, so fest10 and FEST10 are the same code. Codes are unique inside an Organization.

Public and unlisted

Public code

  • Listed on your public coupon surface
  • Eligible for automatic selection at checkout
  • Can carry a campaign label for reporting

Unlisted code

  • Applies only when the buyer types it
  • Never auto-applies, never listed
  • Can be locked to one Account for a private offer

A code also has its own on/off switch, which is separate from its dates. Switching a code off stops it immediately without deleting anything; a redemption already recorded still counts as history.

What a rule version can say

A rule version chooses one effect:

EffectHow the discount is computed
PercentageA rate in basis points off the eligible base, optionally capped
Fixed amountA flat amount off the eligible base, never below zero
Fixed priceSets the eligible unit price, so the discount is the difference

A fixed amount applies once to the eligible total, not once per line. ₹200 off is ₹200 off, however many Passes are in the basket.

A rule can also require a minimum subtotal, a minimum quantity, or a first purchase in the Organization. It can target all eligible lines, specific Passes, the cheapest item, or the most expensive item. Per-Pass overrides let one Coupon express different rates on different Passes.

Caps count real redemptions

CapWhat it stops
Uses per buyerA second use by the same Account, or unlimited
Total redemptionsThe code's overall budget of uses
Total discountThe sum of money the code may ever give away
One allowed AccountAnyone else, for a private code

Every cap is counted from the redemption records themselves, so it cannot drift from what actually happened. A redemption is created when checkout starts, which means a live checkout holds a slot against the cap. If that checkout expires, the slot is released.

Which coupon wins

  1. A code the buyer typed wins if it is valid, even when a bigger public code exists.
  2. With no code typed, the best valid public code applies automatically by the largest saving.
  3. A typed code overrides the automatic choice, and the buyer can try another any time.
  4. An invalid typed code is an error with a reason, never a silent fall back to the automatic one.
  5. One Coupon per Order, enforced by the database.

Automatic selection compares the money actually saved. On a ₹900.00 basket a ₹100.00 code wins; on a ₹1,400.00 basket the 10% code wins with ₹140.00.

A worked two-line discount

The same Organization and Event as before: a Day Pass at ₹1,500 and a Workshop Add-on at ₹2,000, with a public code giving 10% off everything.

10% coupon across two lines
coupon_discount=∑iround⁡(line basei×rate)\text{coupon\_discount} = \sum_i \operatorname{round}(\text{line base}_i \times \text{rate})

Day Pass offer price

₹1,500.00 × 1 unit

₹1,500.00

Workshop Add-on offer price

₹2,000.00 × 1 unit

₹2,000.00

Eligible base

₹3,500.00

Day Pass share of the discount

10% of ₹1,500.00

−₹150.00

Workshop share of the discount

10% of ₹2,000.00

−₹200.00

Coupon total

−₹350.00

The coupon applies to the offer price, never to the list price, so the MRP strike-through is unaffected.

The split matters. From that point on the Order carries ₹150.00 against the Day Pass line and ₹200.00 against the Workshop line, and a partial refund reverses exactly the line's share. The Coupon is never re-run to work out what a refund should be.

A discount also lowers the tax on the discounted base and the platform fee's percentage leg, because both are computed after the discount. It never lowers the fee's fixed ₹10.00 leg.

Failure paths

Every rejection carries a stable reason the checkout page can show.

ReasonWhat it means
invalid_codeNo such code in this Organization
inactiveThe code is switched off
not_yet_activeThe code's start date has not arrived
expiredThe code's end date has passed
not_for_accountThe code is locked to another Account
outside_scopeThe code does not cover this Event or Pass
first_purchase_onlyThe buyer already has a confirmed Order here
already_usedThe buyer's uses are used up
global_limit_reachedThe code's total redemptions are gone
budget_exhaustedThe code has given away its whole budget
below_min_subtotalThe basket is under the code's minimum
below_min_quantityThe basket has too few units
no_eligible_itemsNothing in the basket is covered
no_discountThe terms produce zero money off

A typed code that fails stops the checkout with that reason. The buyer fixes the basket or removes the code; nothing is applied behind their back.

One more edge is worth knowing: a Coupon cannot make a priced Order free. If the total reaches zero, checkout refuses and asks for a smaller discount, because a paid Order always needs a real payment to confirm.

  • Pricing — offer, list, and the fee
  • Orders — where the discount is stored
  • Refunds — how a discount comes back
  • Reports — coupon redemption reporting

On this page