Sales are part of every online shop’s routine. Since 2022, however, every price reduction in the EU comes with a mandatory statement, and since the CJEU ruling of September 2024 also with the question of which price you may calculate the discount from. This guide shows what applies, where WooCommerce reaches its limits and how to set up your shop step by step.
What the Omnibus Directive requires for discounts
With the so-called Omnibus Directive (EU) 2019/2161, the EU added a new Article 6a to the Price Indication Directive 98/6/EC. Member states transposed it into national law, for example Germany as § 11 PAngV (since 28 May 2022) and Austria as § 9a PrAG (since 20 July 2022).
The core rule is the same everywhere: anyone who announces a price reduction to consumers must state the lowest price they charged in the 30 days before the reduction. The aim is that shoppers can tell whether an offer is really cheaper, or whether the price was just raised shortly before.
The duty applies to every announcement of a price reduction. That includes the strike-through price in your shop, a “−20 %” badge, a “Now reduced” banner, and just as much a newsletter or social media post with a discount.
What the CJEU ruling changed
For a long time it was disputed whether it is enough to mention the 30-day lowest price somewhere in small print while the strike-through price and percentage refer to a higher price. The Court of Justice of the EU settled this on 26 September 2024 in case C-330/23 (Aldi Süd).
Aldi Süd had advertised bananas with “−23 %”: €1.29 instead of a struck-through €1.69. Three weeks earlier, however, the bananas had already cost €1.29. The CJEU ruled that a reduction announced as a percentage or as an advertising claim must be determined on the basis of the lowest price of at least the 30 days before. The Regional Court of Düsseldorf then ordered Aldi Süd to cease this advertising on 31 October 2024 (not yet final according to its press release).
For your shop this means: the strike-through price and the percentage should refer to the lowest price of 30 days. Merely stating the lowest price in addition is not enough. More in the article The CJEU ruling on strike-through prices.
Why WooCommerce cannot do this on its own
WooCommerce knows a regular price and a sale price per product. When a sale price is set, WooCommerce strikes through the regular price and shows a “Sale” badge. It does not store a price history. This leads to typical problems:
- No lowest price: without a history, the shop does not know which price was lowest in the 30 days before the sale.
- Wrong strike-through price: if the regular price was raised shortly before the sale, WooCommerce strikes through the higher price. That is exactly what the CJEU objected to.
- Sham discounts: a product never sold at its regular price still appears as “reduced”.
- No evidence: if someone asks, you cannot prove which price applied when.
Step by step to a correct discount
- Record the price history. Every price change needs a date and amount, whether it comes from the product editor, a CSV import, an ERP via the REST API or a scheduled sale. Variations need their own history.
- Calculate the lowest price correctly. What counts are the 30 days before the reduction started, not the last 30 days until today. Otherwise the sale price becomes its own reference. You will find worked examples in Calculating the lowest price of 30 days.
- Show the notice. On the product page and in product lists, close to the price, for example: “Lowest price of the 30 days before the reduction: €249.00”.
- Align strike-through price and percentages. The struck-through price should be the lowest price, and the percentage should be calculated from it. If the sale price is not below the lowest price, it is not a reduction and should not appear as one.
- Keep evidence. Keep the price history long enough to prove older sales, too.
Special cases at a glance
| Case | What applies | Note |
|---|---|---|
| Stepwise reductions | If a reduction is deepened without interruption, the price before the first step stays the reference (e.g. § 11(2) PAngV, § 9a(1) PrAG). | If the sale price goes up in between, a new reduction starts. |
| New products | Austria: lowest price since the product came on the market (§ 9a(2) PrAG). | The German PAngV has no specific rule for this. |
| Perishable goods | Exempt when the price is cut because the goods are about to spoil or expire (e.g. § 11(4) PAngV, § 9a(3) PrAG). | In Germany, the reason must be made clear. |
| Individual discounts | Exempt in Germany (§ 11(4) no. 1 PAngV), e.g. a personal voucher. | A code for everyone is not an individual discount. |
| Discount and currency plugins | Their prices are price information, too. | Check whether your solution can see these prices at all. |
Beyond your shop
The duty is tied to announcing the reduction, not to where you do it. If you advertise “−30 %” in a newsletter, on Instagram or in a flyer, the same rule applies. A plugin can cover your shop; the rest of your advertising is yours to check.
Checklist for your shop
- Is every price change recorded with a date, including imports and scheduled sales?
- Is the lowest price calculated from the 30 days before the sale started?
- Is the notice shown on product pages and in lists?
- Is the strike-through price the lowest price, and the percentage calculated from it?
- Are products without a real discount kept from showing as “Sale”?
- Have you covered stepwise reductions, new products and perishable goods?
- Can you still show a sale’s price history months later?
How Strikewise helps
Strikewise does these steps in WooCommerce automatically: it records every price change, shows the lowest price of 30 days on product pages and in lists, and corrects the strike-through price and discount in CJEU mode. Everything the law requires is included in the free version. If you use the “Omnibus” plugin, you can import your price history in one click.