---
title: "Show the lowest earlier price beside a · Agent Wranglers"
url: https://agentwranglers.se/playbook/payments/price-display-and-consumer-law/price-reduction-prior-price
id: PAY-9
level: Required
applies: payments, eu-users
region: EU
risk: law
updated: 2026-10-27
build: a2a6bdfed830
tokens: 1174
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Show the lowest earlier price beside a discount

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Price display and consumer law](https://agentwranglers.se/playbook/payments/price-display-and-consumer-law.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: PAY-9
- Level: Required
- Chapter: [Price display and consumer law](https://agentwranglers.se/playbook/payments/price-display-and-consumer-law.md)
- Rule: When you announce a price cut on goods to EU consumers, show as prior price the lowest price of the 30 days before. Compute every percentage or saving from that price.
- Check: A unit test sets a price of 200, then 150 for 10 days, then 200 again, then a sale at 120. The page shows 150 as the prior price and a reduction of 20%, not 40%. Every badge and saving on the page comes from the stored prior price.
- Risk: A law broken
- Applies when: The project takes payments, or has users in the EU.
- Region: European Union (EU). The duty comes from the law there. The rule applies only when the project serves people there, and its Applies when also holds.
- How: Article 6a of the Price Indication Directive, added by the Omnibus Directive 2019/2161, sets this rule. A struck-through list price that nobody paid breaks it. Member states may set other periods for goods that spoil fast or are new on the market. Keep a history of every price with its start and end time, so the prior price comes from data. Compute it on the server when the discount starts, and store it with the discount. The EU Court of Justice ruled in Aldi Süd (C-330/23, 2024) that a "-40%" badge or a saving must also start from this price. A badge counted from the list price misleads. Log every price change as [Log every staff action on money](https://agentwranglers.se/playbook/payments/invoices-and-records/money-audit-log.md) says.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### SQL example

```sql
SELECT min(amount_minor) AS prior_price_minor
FROM price_history
WHERE product_id = $1
  AND valid_from < $2
  AND coalesce(valid_to, $2) > $2 - interval '30 days';
```

### JavaScript example

```js
const PRIOR_PRICE_WINDOW_MS = 30 * 24 * 60 * 60 * 1000

function priorPrice(history, saleStartsAt) {
  const windowStart = saleStartsAt - PRIOR_PRICE_WINDOW_MS
  const inWindow = history.filter(p => p.validFrom < saleStartsAt && (p.validTo ?? saleStartsAt) > windowStart)
  return Math.min(...inWindow.map(p => p.amountMinor))
}

const reductionPercent = (priorMinor, saleMinor) => Math.round((1 - saleMinor / priorMinor) * 100)
```

### Python example

```python
from datetime import timedelta

PRIOR_PRICE_WINDOW = timedelta(days=30)

def prior_price(history, sale_starts_at):
    window_start = sale_starts_at - PRIOR_PRICE_WINDOW
    return min(p.amount_minor for p in history
               if p.valid_from < sale_starts_at and (p.valid_to or sale_starts_at) > window_start)

def reduction_percent(prior_minor, sale_minor):
    return round((1 - sale_minor / prior_minor) * 100)
```

## Sources

- [Directive (EU) 2019/2161, Article 2 adding Article 6a](https://eur-lex.europa.eu/eli/dir/2019/2161/oj)
- [Court of Justice, C-330/23 Aldi Süd](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:62023CJ0330)

## Related rules

- PAY-57 [Log every staff action on money](https://agentwranglers.se/playbook/payments/invoices-and-records/money-audit-log.md) in Payments and billing
- ECM-36 [Apply discounts on the server in one fixed order](https://agentwranglers.se/playbook/ecommerce/promotions-and-claims/discount-order.md) in E-commerce and fulfilment

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/payments/price-display-and-consumer-law/price-reduction-prior-price">Agent Wranglers payments and billing playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Show the total price with every mandatory fee](https://agentwranglers.se/playbook/payments/price-display-and-consumer-law/total-price-upfront.md)
- Next: [Never add a fee for paying by EU consumer card](https://agentwranglers.se/playbook/payments/price-display-and-consumer-law/no-card-surcharge.md)
- [Price display and consumer law](https://agentwranglers.se/playbook/payments/price-display-and-consumer-law.md)
