Commerce
Coupon / Promo Code
Lets users apply a discount code at checkout (percentage off, fixed amount, free shipping) with rules around usage limits and expiry.
When to use this
For promotional campaigns, partner discounts, retention offers, or seasonal sales.
What I assumed
I made these guesses to fill gaps. Let me know if any are wrong.
Flow diagram
Step-by-step recipe
Copy this and paste into Cursor, Claude Code, or v0.
PATTERN: Coupon Application
INPUT: code_string, cart_or_subscription
OUTPUT: discount_applied | error_message
SETUP_STEPS (admin creates coupon):
1. Admin defines: code, discount type (%, fixed, shipping), amount
2. Set rules: max uses (total + per user), expiry, min order value
3. Set scope: applies to all/specific products/specific plans
APPLY_STEPS (user enters code):
1. User enters code in input field at cart or checkout
2. Validate code: exists, not expired, not exhausted, not already used by this user
3. IF invalid โ show specific reason ("This code expired", "Already used", "Doesn't exist")
4. Validate cart eligibility: meets min order value, has eligible items
5. IF ineligible โ show "Code requires $X minimum / specific items"
6. Calculate discount amount
7. Show updated total with line item: "Coupon SAVE10: -$10.00"
8. Persist code on cart so it carries through to checkout
9. On checkout, double-check validity (race condition protection)
10. Apply at payment: pass discount to payment provider
11. After successful payment: increment usage counter, mark per-user used
ERROR_HANDLING:
- Code typed wrong โ trim whitespace, lowercase compare, show "Code 'X' not found"
- Stacking attempt (multiple codes) โ policy: allow stacking OR replace with newer (be explicit)
- Last available use claimed by another user mid-checkout โ show "Sorry, this code just sold out"
- Discount makes total negative โ cap at $0, never refund money
- Provider rejects coupon โ fall back to manual discount on order
EXTENSION_POINTS:
- First-purchase-only (composable_with: ["new-user"])
- Subscription discount on first month (composable_with: ["subscription"])
- Auto-applied discount based on URL param (UTM-driven)
States โ how things change
| State | Description | Transitions |
|---|---|---|
| No coupon applied | Cart at full price |
|
| Validating | Checking code against rules |
|
| Applied | Discount visible on cart |
|
| Used | Coupon consumed, counter incremented | terminal |
Easy-to-miss situations
The kinds of edge cases that break demos.
What if a viral coupon code leaks publicly?
highMassive unintended usage, budget blown.
Suggested handling: Set hard total-uses limit on every coupon (default 1000). Set per-user limit (default 1). Monitor unusual usage spikes. Have a "burn coupon" admin action to instantly disable.
What if a user tries to stack 3 coupons?
mediumWithout explicit policy, stacking creates massive discounts.
Suggested handling: Default to one coupon per cart. Show "Replacing previous coupon X with Y" when applying second. Allow stacking only if explicitly enabled (e.g., welcome + free shipping).
What if the coupon makes the order total negative?
medium$30 cart with $50 coupon โ do we owe the customer money?
Suggested handling: Cap discount at order subtotal โ never go below $0. Show "Coupon -$30 (max for this order)" with explanation. Don't credit unused balance.
What if the user changes cart after applying coupon (removes the eligible item)?
mediumCoupon silently stops working, user confused at checkout.
Suggested handling: Re-validate on every cart change. If newly ineligible, show clear toast: "Coupon SAVE10 no longer applies โ needs item X". Auto-remove from cart with notification.
What if a coupon was used but checkout failed (user retries)?
mediumPer-user limit hit but no successful purchase. Frustrating.
Suggested handling: Only increment usage counter on successful payment, not on apply. Allow same code re-application on retry. Idempotency by user_id + code on success.
Composes well with
Combine these patterns when you need a richer flow.