Experimental. This Module has no test or production evidence recorded yet. Read it, run it locally, and hold off on real Orders. See maturity levels.
The Discounts Module creates, validates, and applies promo codes. It has no Module dependencies and no init-time options. You manage discount rules and codes at runtime through the admin endpoints or the controller API. The Checkout Module picks up discounts through structural typing, so promo codes entered in CheckoutSummary flow through without extra wiring.
Source: modules/discounts · npm: @86d-store/discounts
Installation
Configuration
The Discounts Module takes no configuration options. Initialize it with no arguments:
Discount types
Store endpoints
POST /discounts/validate
This endpoint checks a promo code and calculates the discount amount without applying it or incrementing any usage counters. That makes it safe to call on every cart update or preview.
Request body:
Response:
Admin endpoints
Deleting a discount cascades: all promo codes attached to that discount are removed first, then the discount record is deleted.
Components
DiscountCodeInput is a promo code entry field with live validation. When a valid code is entered it shows an applied state with the discount amount, and the Shopper can remove the code.
With props:
CartDiscounts
CartDiscounts summarizes the applied discount on the cart page: the code and the amount deducted.
DiscountBanner
DiscountBanner shows active discount offers to Shoppers in a promotional banner.
AutoAppliedSavings
AutoAppliedSavings shows savings applied without a promo code, such as sale prices or tiered discounts.
Types
Notes
Case-insensitive codes. Promo codes are stored and matched as uppercase. SAVE10, save10, and Save10 all resolve to the same code.
validateCode vs. applyCode. Use validateCode for previews and cart-page feedback; it never mutates state. Call applyCode exactly once per order at confirmation time; it increments both the code’s usedCount and the parent discount’s usedCount.
Checkout integration. The Checkout Module accesses DiscountController through the runtime context via structural typing; no direct import is needed. The CheckoutSummary component handles the promo code form automatically, so you do not need to wire up DiscountCodeInput separately on the Checkout page.
Related pages