Skip to content

Loyalty points

Panel → Points. Give points for buying, and let customers spend them as a discount on later purchases.

It ships switched off. A loyalty programme changes the margin on every order, so you turn it on deliberately, with your own numbers in it.

🔴 A point is not money, and that is the whole difference

Section titled “🔴 A point is not money, and that is the whole difference”

This is the opposite of a gift card, and mixing them up is the mistake that makes a shop account for VAT wrongly for years without a single error ever showing on screen.

Gift card / store credit Points
How you get it Bought (or credited) Earned by buying
What it is Means of payment Future discount
Order’s taxable amount Unchanged Goes down
VAT on the order The full amount On the reduced base
Can it become cash? Yes, it is money No, never

This is not an opinion. The Court of Justice of the EU settled it on 5 March 2026 (case C-436/24, Lyko Operations). Points that are not bought, are worth nothing on their own, cannot be transferred and cannot be turned into money are not vouchers: they are a discount on a later purchase. And a discount reduces the taxable amount, so VAT is due only on what the customer actually pays.

At 21 % on a 100 € purchase you can see it at a glance:

10 € gift card base 100.00 · VAT 21.00 · total 121.00 · you take 111.00
1,000 points (= 10 €) base 90.00 · VAT 18.90 · total 108.90 · you take 108.90

Both are correct. What is not — and what many shops do — is to book points as a payment method: you take 108.90 and declare VAT on 121.00, paying 2.10 € out of your own pocket on every order.

That is why points never turn into store credit and never buy gift cards. It is not a missing feature: it is the line that keeps them points. The moment they become something the shop is obliged to accept as payment, they are vouchers again, with full VAT.

Panel → Points, in the “How it works” block.

Setting What it does Default
Active Turns the programme on No
Points per euro How many each euro of base gives 1
Point value How many cents one point takes off 1
Minimum to redeem Below this, they cannot be spent 100
Redemption step Spent in blocks of N 100
Cap per order Max % of the order points can pay none
Expire after Days a point lives 365
Earn on shipping Whether the shipping fee earns too No

With the defaults, 100 points = 1 € and you give back 1 % of what was bought. It is a reasonable starting point: it fits in one sentence, and the reward is noticeable without giving away margin.

On the base of the goods: excluding tax, after coupons and after the points themselves, without shipping (unless you turn it on) and without gift cards. Every exclusion closes a specific hole:

  • Excluding tax, or a customer in a high-VAT country would earn more points for the same purchase.
  • After discounts, or a 50 %-off order would earn as much as paying full price.
  • Without gift cards, or the same purchase would earn points when the card is bought and again when it is spent.

And they are earned when the money is taken, not when the order is placed. A bank-transfer order arrives before the money does: giving the points earlier is giving away a discount against a payment that may never land.

Every time someone earns points, a batch opens with its own date. They do not all expire at once, nor “if you don’t buy for a year”: each batch expires when its own term is up, and spending always draws from the batch that expires soonest.

That avoids the two usual complaints: losing 4,000 points in one go on day 366, and spending the points that never expire while the ones that do quietly die.

A nightly job records what expired in the ledger, so the customer reads “−1,200 expired on 3 March” instead of watching a number shrink with no explanation. Leave Expire after empty and they never expire.

Watch the breakage. The panel shows the share of earned points that end up expiring. Below 20 % you are giving away margin — the reward is too easy. Above 50 % nobody reaches it, and a programme nobody uses builds no loyalty: it only grows the liability.

At checkout the customer says how many they want to spend. What actually applies is capped in four places, and the smallest one wins:

  1. How many they asked to spend.
  2. How many they actually have.
  3. What is left to pay for the goods (never leaves a line negative, and gift cards are excluded).
  4. Your cap per order, if you set one.

Then it is rounded down to the step, so someone who asks for 1,000 spends 1,000 and not 1,037.

They must be signed in: points belong to an account and are not transferable. There is no code to type.

The discount is spread across the order lines, like a coupon. Without spreading it you cannot tell how much was paid for each item, and a partial refund would give back too much or too little.

When an order is refunded in full, what it produced is undone:

  • The points that were spent go back to their batch, with the expiry date they already had. Coming back as a fresh batch would make buy-and-return the way to keep points alive forever.
  • The points that purchase gave are taken back, from the batch that gave them. If the customer already spent them, they go negative: those points came from a purchase that no longer exists, and buying again clears it. Writing them off would make returning profitable.

A partial refund does not touch points. Scraping three points off for returning 3 € of 100 leaves a ledger nobody understands, and rounding each sliver costs more than it returns.

Panel → Points → a customer → Adjust. For a goodwill gesture, or to fix a mismatch. The note is required: an adjustment with no reason is indistinguishable from an error when someone looks at it a year later, and who made it is recorded.

  • GET /store/mis-puntos — how many they have, what expires and when, and their ledger.
  • POST /store/carritos/:id/puntos with { "puntos": 1000 } — redeem.
  • DELETE /store/carritos/:id/puntos — undo the redemption.

The response always carries how many were actually applied and, if it could not be done, why. A button that silently applies a different amount than the one asked for is the number one reason people write to support.

  • Live points are a liability. They are a promised discount someone will use. The panel shows it in euros at today’s value: that is what it will cost if they are all redeemed.
  • Expiry is your call, but look at it. There is no legal minimum here like the one for gift cards, because a point is not the customer’s money; but the programme’s terms have to be written down and available, and a change for the worse cannot be applied to what is already earned without notice.
  • This is not tax advice. The treatment described is the one for a programme with the conditions above (not sold, not transferable, not convertible into money). If you build something different — points that are sold, gifted between customers, or swapped for cards — the treatment changes and it is worth asking.