Discount codes
Three kinds of discount, two ways to apply one, and the four statuses that decide whether a code works.
Manage → Discounts. The list shows Code, Type, Value, Usage, Status.
Three kinds
| Type | vi | The value you enter |
|---|---|---|
| Percentage | Phần trăm | The percentage taken off |
| Fixed | Số tiền cố định | The amount taken off |
| Free shipping | Miễn phí vận chuyển | Nothing — shipping goes to zero |
Two ways to apply one
Code — the shopper types it at checkout, e.g. SUMMER20. The code is
stored uppercase, so it does not matter how the shopper types it.
But they can only type it if there is a box to type it into, and that box is not there by default: add Discount code to your order form — form builder → Basic group. Without it a code discount has no way into an order, and only the automatic ones below ever run.
A bad code stops the order: the shopper sees the error on the box they just typed into. That is deliberate — they type a code precisely to pay less, so an order that went through without it would charge them in full while the thank-you page said everything worked.
Automatic — no code at all. The discount applies itself when an order meets the conditions.
Not to be confused with Gift cards: a discount makes the goods cheaper, while a gift card pays for goods at full price. One order can use both.
To let shoppers see a code on the page — a voucher list they tap to use, or a countdown for a flash sale — see Flash sales and on-page promotions.
What it applies to
| Whole order | Applied to the order total |
| Specific products | Only the products you pick |
| Specific categories | Only the categories you pick |
For the latter two, a picker appears so you can search and tick the items.
Conditions and limits
Minimum order — the order value required for the discount to apply. Leave at
0 for no minimum.
Usage limit — the total number of times the code may be used across the
whole store. Leave at 0 for unlimited. The Usage column shows Used 12 /
100, or just Used 12 when unlimited.
Starts at / Ends at — the window during which it runs. Leave both blank for no time limit.
Active — the on/off switch. "Only active discounts can be used."
Four statuses, and they are derived
The status in the list is not a field you pick — it is the result of the Active switch plus the schedule:
| Status | Means |
|---|---|
| Active | Switched on and inside its window |
| Inactive | The switch is off |
| Scheduled | Switched on, but the start date has not arrived |
| Expired | The end date has passed |
When a code "does not work", the first question is always which of those four it is. Scheduled and Expired look identical to a shopper, but the fixes are nothing alike.
Duplicate codes
If you enter a code that already exists, the form says "A discount with this code already exists. Please choose another." Each code is unique within a store.
The internal title
The Title field is an internal label, optional, and shoppers never see it —
so that with twenty codes you still know which campaign SUMMER20 belonged to.
Deleting
Deleting a discount is permanent and cannot be undone.
For a code you merely want to stop, switch Active off rather than deleting. An inactive code cannot be used, but its usage count and its record survive — which matters when you need to reconcile the revenue of a finished campaign.
Why discounts are not in the public API
discounts exists in the scope vocabulary, but there is no /api/v1 endpoint
for it yet. The reason is that each public resource needs its own frozen shape
rather than exposing the internal structure directly — a struct that serialises
today publishes every field it grows tomorrow. See
What is not here yet.
Meanwhile, redeeming a code happens normally during checkout — the one place a code is ever redeemed, under a lock, with its usage limit genuinely enforced.
Updated 26/09/2026