Promotions and coupons
A coupon is a code the customer types in the cart; an automatic promotion applies on its own when the cart meets its conditions.
A coupon is a code the customer types in the cart; an automatic promotion applies on its own when the cart meets its conditions. Both are worked out by the same engine, on the server, every time the cart changes.
🔴 There is no screen in the panel to create or edit promotions, and no management API route for it either. Today a promotion reaches the store in one of two ways: it is brought from WooCommerce by the move-in, or someone writes it directly into the database. What this page describes is what the engine does with the promotions that exist.
What the customer does
In the cart there is a field for the code. The code is not case-sensitive:
summer10 and SUMMER10 are the same coupon.
- If it applies, the cart shows the discount and the code.
- If it does not, the code is not left hanging in the cart: it is removed, and the API answers with the reason (it has expired, it has run out, its conditions are not met, there is nothing in the cart it applies to…). That reason is currently written in Spanish only.
Of the factory themes, only base has the code field in the cart. It shows a
generic "invalid code" message, not the reason. The API routes are
POST /tienda/carritos/<id>/cupon (with codigo) and
DELETE /tienda/carritos/<id>/cupon/<code>; in the commerce contract they are
cart.applyPromo and cart.removePromo.
When a promotion is left out
Every time the cart is recalculated, each promotion is checked, and it is dropped if:
- it is not active (draft or deactivated);
- its campaign has not started or has ended;
- it has reached its usage limit, or its campaign has run out of uses;
- it is a fixed amount in another currency than the cart's;
- its conditions are not met;
- there is nothing in the cart it can apply to;
- it is of the "buy X, get Y" type: that type is not calculated yet.
A campaign can also have a spend budget. It is checked, but nothing adds to it when a promotion is used, so today it never runs out. The usage budget does advance.
The same check runs again when the order is placed. A coupon that expired while the customer was paying is not applied.
How the discount is calculated
A promotion is a percentage or a fixed amount, and it applies to one of two things:
- the products in the cart, or
- the shipping.
And it is spread in one of three ways:
| Spread | What it does |
|---|---|
| Across | One discount for the whole set, split between the lines in proportion to their amount. A fixed 10 off is 10 off in total. |
| Each | Per unit: a fixed 2 off is 2 off every unit it applies to, up to the maximum quantity if there is one. |
| Once | Up to a maximum quantity (1 if none is set), starting with the cheapest units. |
A discount never makes a line or a shipping cost negative.
Several promotions can apply at once. They are applied in order of creation, and each works on what the previous ones left, so two 50 % coupons are not a free order.
Conditions
A promotion can have two sets of rules:
- Conditions, which decide whether it applies to the cart at all.
- Target rules, which decide which lines (or which shipping) it discounts.
Each rule is an attribute, an operator (eq, in, ne, gt, gte, lt,
lte) and one or more values. The attributes the engine understands:
| For conditions | For target rules |
|---|---|
subtotal (products, before discounts) | product.id |
currency_code, region_id, sales_channel_id | product_type.id |
email | product_collection.id |
customer.id, customer_group.id | variant.id |
items.product.id, items.product_type.id, items.product_collection.id, items.variant.id | shipping_option.id |
An unknown attribute never matches, so a promotion with a rule the engine does not understand is not applied — it does not discount by mistake.
When a use is counted
A use is counted when the order is placed, not when the payment comes in. The promotion is recorded on the order, so later you can tell which orders used which coupon.
Coupons brought from WooCommerce
The move-in brings each coupon with its code, its type (percentage or fixed), its amount, its usage limit, the uses already spent and its expiry date. An expired one comes in deactivated.
Of its conditions, three come across as rules: the minimum spend, only these products (the ones already brought over) and only these emails. The rest — maximum spend, excluded products, categories, free shipping, "cannot be combined", uses per customer, excluding sale items — does not, and those codes are listed with what they left behind so you can review them before advertising them.
Two more things to know:
- A fixed-amount coupon comes in euros. If the store sells in another currency, it is dropped for the currency mismatch.
- Codes come in upper case. As matching ignores case, customers can still type them however they like.
With taxes, points and gift cards
The order in which a cart is calculated is: promotions, then points, then taxes.
- Taxes are calculated on the price after the discount. A coupon lowers the taxable amount.
- Points are redeemed on what the coupons left.
- A gift card is a means of payment, not a discount: it is used after all of this and does not touch the taxable amount. Unlike points, a coupon does discount a gift card in the cart; the card is still issued for its full value.
- Quantity pricing (see advanced selling) is not a promotion: it changes the unit price, and coupons then apply on top of it.
See also
Products and catalogue
This guide covers what the panel does today, and also what it does not do yet, so you do not go looking for a button that is not there.
Abandoned carts
A cart with an email address, untouched for 30 minutes, that never became an order. Carts created in the last 30 days are shown.