If you sell to customers in the EU and you announce a discount, the page has to show the prior price: the lowest price you charged for that product during at least the 30 days before the reduction began. We explained the rule itself, the Aldi Süd ruling and the usual mistakes in Omnibus rule: lowest 30-day price in WooCommerce. This article is the hands-on part: how to actually get that number onto a WooCommerce product page, and how to check that it is right before a campaign goes live.
The short version: WooCommerce does not remember old prices, so the work is mostly about recording history early and refusing to show a number you cannot prove. Everything below works with any tool that does both. We use our own free plugin, PN Scripts Price History for Discounts, as the example because we know exactly how it behaves.
#Step 1: know which rules apply to your shop
The EU minimum is in Article 6a of Directive 98/6/EC, added by the Omnibus Directive (EU) 2019/2161. Every Member State then chose its own options, so write down the rules of each country you sell to before you touch any settings. For a Bulgarian shop the requirement is in Article 65 of the Consumer Protection Act (ЗЗП):
- every announced reduction shows the prior price;
- the prior price is the lowest price in a period of not less than 30 days before the reduction, in the same shop, website or app;
- goods on the market for less than 30 days may use a period of not less than 7 days;
- for a progressive reduction, the prior price stays the price before the first reduction;
- food and other perishable goods have their own exceptions, which change on 5 February 2027 (ДВ бр. 13/2026).
A period longer than 30 days is never wrong, because it can only give the same or a lower prior price. If you are unsure whether a shorter period applies to new products, do not announce reductions for them.
#Step 2: start recording prices before the sale, not during it
WooCommerce stores the current regular price and the current sale price. It keeps no history, so on the day you start a sale it cannot tell you what the price was three weeks ago. This is the step most shops miss: whatever tool you choose has to be running for at least 30 days before the campaign, or the first campaign will have products with no provable prior price.
Prices change through more than the edit screen: quick and bulk edit, CSV import, the REST API used by ERP systems, WP-CLI, and scheduled sales. A history that only watches the edit screen has holes. Price History for Discounts records every product save from all of those sources, stores a row only when a price actually changes, and records the starting prices of the whole catalogue in the background after activation.
If you used another lowest-price plugin before, import its data. Our plugin reads, without changing, the history of three other plugins and uses it only for the time before its own first record.
#Step 3: install the plugin and choose a preset
The plugin is free and open source (GPL) on GitHub and has been submitted to WordPress.org. It needs WordPress 6.5 or newer, WooCommerce 9.0 or newer and PHP 8.1 or newer. After activation:
- Open WooCommerce → Price History.
- Choose a preset: EU strict, Bulgaria, Germany, Poland or custom. The Bulgaria preset uses 30 days without the shorter periods of Article 65(3) and (4), which is stricter than the minimum and therefore safe.
- Decide what happens to new products: hide the notice (the default) or, where your country allows it, use the lowest price since launch.
- Flag perishable goods per product or per category only if your national rules give them an exemption. It is off by default.
- Set your wording. The default reads "Lowest price in the 30 days before the discount", and you can write your own with the
{price},{days}and{date}placeholders.
Presets are starting points, not legal advice. If you sell in several countries with different options, choose the strictest one you can live with.
#Step 4: check every place a discount is shown
A shopper can see a crossed-out price on the product page, in category and shop grids, in related products, in block-theme product collections and after picking a variation. The prior price has to be next to the reduction in each of those places, and it must be shown with or without VAT exactly like the current price.
The plugin appends the notice to WooCommerce's own price output, so it appears in classic themes, in the Product Price block and in product collections, and for the selected variation of a variable product. A parent product that shows a price range gets no notice, because a range has no single prior price. For a custom layout there is a shortcode: [pnscripts_price_history] on a product page or [pnscripts_price_history id="123"] anywhere.
Then walk through the shop on a phone. Page builders that print prices with their own code need the shortcode or a small template change.
#Step 5: rehearse a campaign on a staging copy
On a staging copy of the shop, before the campaign:
- Pick a simple product, a variable product and a product that was already on sale.
- Change prices the way your team really does it: the editor, a CSV import, your ERP sync.
- Schedule a sale, then lower the sale price again in the middle of it to test a progressive reduction.
- Read the result for each product in the Coverage report, which lists every product and variation on sale with the prior price it shows or the reason it shows nothing. From the command line,
wp pnscripts-price-history history <id>prints the recorded history andwp pnscripts-price-history reference <id>the computed prior price.
For a progressive reduction the period must still end when the first reduction started. If your number drifts down to the previous sale price, something is calculating from today instead of from the start of the sale.
#Step 6: fix the percentage badges
Since the Court of Justice's judgment in C-330/23 (26 September 2024), a percentage or a "best price" claim has to be measured from the prior price. Most themes calculate the "-25%" badge from the regular price. If the regular price is not the 30-day low, the badge is wrong even when the notice under it is right.
Our plugin does not rewrite badges or crossed-out prices printed by a theme or another plugin. It gives developers the filter pnscripts_omnibus_price_html to recalculate them. If you cannot change the badge, switch percentage badges off for the campaign.
#Step 7: decide what to do with "unknown"
Sometimes the history cannot prove the number: the product was already on sale when recording began, prices changed while the plugin was inactive, or the period reaches back before a tax or currency change. In those cases our plugin shows no prior price rather than a guess. That is deliberate. WooCommerce will still show the sale, so for each of those products you decide: wait until the history covers the period, or end the reduction. The Coverage report shows the reason product by product.
#Frequently asked questions
Can I type the old price into a custom field by hand?
You can, but you then have to prove that number for every product and variation, earlier sales included. A recorded history is easier to defend.
Why is there no notice right after I installed the plugin?
Because the history does not yet cover the period for products that were already on sale. The notice appears once the recorded history reaches back far enough, and the Coverage report explains each case.
Does it work with variable products?
Yes. Each variation has its own history and its own prior price, and the notice appears when the shopper selects a variation.
Is the plugin really free?
Yes. The plugin is free and open source on GitHub under the GPL, has no locked features and makes no external requests. It is in review for WordPress.org.
Does installing it make my shop compliant?
No plugin can promise that. It calculates and shows the prior price from a recorded history; badges, campaign wording and national rules stay your responsibility. This article is not legal advice.
#Sources
- Directive (EU) 2019/2161 (the Omnibus Directive) and Directive 98/6/EC, Article 6a
- Commission Notice 2021/C 526/02, guidance on Article 6a
- Court of Justice, case C-330/23, judgment of 26 September 2024
- Consumer Protection Act (ЗЗП), Article 65, as amended in ДВ бр. 20/2022 and бр. 13/2026
Product page: PN Scripts Price History for Discounts. Download: github.com/pnscripts/pnscripts-price-history.
Comments
Comments
Be the first to leave a comment.
Leave a comment