Appearance
Coupons
Flow ID: CF-13 | Module(s): coupons, Promotion domain | Complexity: High
Business Overview
Coupons offer percentage or fixed-amount discounts with hierarchical targeting. A master template defines the discount; individual codes are generated from it. Validation checks date ranges, usage limits, audience restrictions, cart totals, and product/category/vendor/tag restrictions with configurable AND/OR logic.
Key business behaviors:
- Percentage discount: hierarchical cascade — vendor → product → category → tag → all items
- Fixed discount: direct subtraction from cart total (no targeting)
- Coupon codes tracked individually: each has
is_sentandis_usedcounters - Auto-applied default coupon:
is_default=1coupon applied automatically if valid - Audience targeting: coupon can restrict to specific customer segments
API Reference
REST Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /rest/promotion/coupon | Backend | List coupons |
| POST | /rest/promotion/coupon | Backend | Create coupon |
| GET | /rest/promotion/coupon-code | Backend | List coupon codes |
| GET | /rest/promotion/coupon-rule | Backend | List rules |
| POST | /rest/checkout/coupon/validate | Guest/Customer | Validate coupon against cart |
Related REST Controllers
CouponCode, CouponProduct, CouponRule, CouponVendor — all in src/Rest/Promotion/Controllers/
Validation Chain (isValidCoupon())
Sequential checks (returns false on first failure):
- Code exists in
couponstable is_sent = 1(distributed)is_used < max_count_usage- Date range:
date_start <= NOW <= date_end - Audience: customer in coupon's audience segment
- Cart subtotal:
total_cart_from <= cartTotal <= total_cart_to - Vendor restrictions (AND/OR logic)
- Category restrictions (AND/OR logic, includes children)
- Tag restrictions (AND/OR logic)
- Product restrictions (AND/OR logic)
New features (2024 migrations): categories_rule_type and tags_rule_type columns added to coupon_rules — support AND/OR logic for category and tag restrictions.
Discount Calculation
Percentage (calculateCartDiscountPercent())
Priority cascade — first match wins:
- Vendor-restricted items → apply discount
- Product-restricted items → apply discount
- Category-restricted items → apply discount
- Tag-restricted items → apply discount
- All cart items → apply discount (no restrictions)
Formula per item: round(final_price × quantity × discount_percent / 100, 2)
Fixed (calculateCartDiscountPrice())
Simple: cart_total_vat -= discount_price. No product/vendor filtering.
Client Extension Points
- Validation: Override
isValidCoupon()for custom rules - Discount calculation: Override
calculateCartDiscountPercent()for custom logic - Registry: Audience targeting via
audienceIdfield - REST Validator: Custom rules in Domain layer
Data Model
| Table | Purpose |
|---|---|
coupon | Master template (discount %, price, max usage, is_default) |
coupons | Individual codes (code, is_sent, is_used) |
coupon_rules | Date range, cart/price thresholds, AND/OR logic |
coupon_vendors/categories/product_tags/products | Restriction targets |
For full column-level schema details, see AD-08 Coupon Management.
Related Flows
- CF-05 Cart Management — default coupon auto-applied
- CF-06 Order Preview — coupon validated at checkout
- CF-07 Order Confirmation — coupon discount in final total
- CF-08 Payment Processing — coupon rolled back on failure
- CF-23 Gift Cards — gift cards create coupon codes
- AD-08 Coupon Management — admin coupon CRUD and code generation
- AD-22 Audience Campaigns — audience targeting for coupons