
Omnibus-Preisangaben: Ein Datenmodell für den 30-Tage-Tiefstpreis
Ein praxistaugliches Datenmodell für eine prüfbare Preishistorie, stabile Aktionsreferenzen und konsistente Storefront-Daten.
In Deutschland verlangt § 11 Abs. 1 Preisangabenverordnung, dass ein Händler bei der Bekanntgabe einer Preisermäßigung für Waren gegenüber Verbrauchern den niedrigsten Gesamtpreis der vorherigen 30 Tage angibt. Der Auslöser ist wichtig: Es geht um die Bekanntgabe einer Ermäßigung, nicht bloß um einen Datenbankwert, bei dem der heutige Preis unter einem anderen Preis liegt.
Dieses Detail bestimmt die technische Lösung. Die Storefront sollte eine rechtliche Aussage nicht aus currentPrice < referencePrice ableiten. Ebenso wenig darf ein rollierendes Minimum während einer laufenden Aktion weiterwandern. Das System braucht ein ausdrückliches Preisermäßigungsereignis, eine prüfbare Preishistorie und einen Referenzpreis, der am Start der Aktion festgeschrieben wird.
Dieser Beitrag beschreibt die technische Architektur und ist keine Rechtsberatung. Geltungsbereich, Beschriftung und Ausnahmen sollten für jeden Markt rechtlich geprüft werden.
Was der 30-Tage-Tiefstpreis leisten muss
Artikel 6a der EU-Preisangabenrichtlinie definiert den vorherigen Preis als den niedrigsten Preis, den der Händler mindestens innerhalb der 30 Tage vor der Ermäßigung angewendet hat. Die Auslegungshinweise der Europäischen Kommission erläutern Regel und Anwendungsbereich.
Der Europäische Gerichtshof hat den Berechnungspunkt im Aldi-Süd-Urteil von 2024 präzisiert. Wird eine prozentuale Preisermäßigung oder eine werbliche Aussage zum Preisvorteil veröffentlicht, muss sie auf dem 30-Tage-Tiefstpreis beruhen. Es reicht nicht, den Tiefstpreis irgendwo neben einem Prozentsatz zu nennen, der von einem höheren Preis berechnet wurde. Die Pressemitteilung zu C-330/23 zeigt ein kurzes Beispiel.
Für die Anwendung entstehen daraus drei getrennte Werte:
- der aktuelle Verkaufspreis;
- der vorherige Preis für die angekündigte Ermäßigung, berechnet vor deren Beginn;
- die Werbeaussage, die aus diesen beiden Werten abgeleitet wird.
Diese Werte gehören nicht in ein einziges rollierendes Feld.
Jeden tatsächlich angewendeten Verbraucherpreis speichern
Die dauerhafte Grundlage ist eine Historie der Preise, die für Verbraucher tatsächlich galten. Ein sinnvoller logischer Schlüssel enthält Händler, Produktvariante, Markt, Vertriebskanal und Währung. Wenn Steuern oder Kundengruppen den sichtbaren Gesamtpreis verändern, muss das Modell auch diesen Kontext reproduzieren können.
1price_history
2 trader_id
3 variant_id
4 market_id
5 sales_channel_id
6 currency
7 gross_price_minor
8 valid_from
9 valid_toJede Preisänderung schließt das vorherige Gültigkeitsintervall und öffnet das nächste in derselben Transaktion. Geldbeträge werden als ganze Werte in der kleinsten Währungseinheit gespeichert, nicht als Gleitkommazahl. Der Vorgang bleibt erhalten, auch wenn gerade keine Aktion läuft. Diese Historie ist der Nachweis. Ein Suchindex oder zwischengespeichertes Produktdokument ist nur eine daraus erzeugte Projektion.
Eine einzelne product_id ist dafür meist zu grob. Varianten können unterschiedliche Preise haben. Ein Shop für sechs Märkte kann für dieselbe Variante zur selben Zeit verschiedene Bruttopreise ausspielen. Auf einem Marktplatz kommen möglicherweise mehrere Händler hinzu, wodurch sich auch die rechtlich maßgebliche Preishistorie ändert.
Das Zeitfenster vor dem Aktionsstart verankern
Beim Start einer Aktion werden die Preise abgefragt, die im vorherigen 30-Tage-Zeitraum galten. Mit Gültigkeitsintervallen kann die Abfrage so aussehen:
1SELECT MIN(gross_price_minor)
2FROM price_history
3WHERE trader_id = :trader_id
4 AND variant_id = :variant_id
5 AND market_id = :market_id
6 AND sales_channel_id = :sales_channel_id
7 AND currency = :currency
8 AND valid_from < :promotion_starts_at
9 AND COALESCE(valid_to, 'infinity')
10 > :promotion_starts_at - INTERVAL '30 days';Die strikte Grenze valid_from < :promotion_starts_at schließt den neuen Aktionspreis aus. Durch die Überschneidungsbedingung wird trotzdem ein regulärer Preis berücksichtigt, der schon vor dem Zeitfenster begann und innerhalb des Zeitfensters weiter galt.
Das Ergebnis wird auf dem aktiven Preisermäßigungsdatensatz gespeichert:
1price_reduction
2 id
3 variant_id
4 market_id
5 starts_at
6 ends_at
7 sale_price_minor
8 prior_price_minor
9 policy_versionDieser Wert bleibt während der Aktion stabil. Ein täglich rollierendes Minimum, das den laufenden Aktionspreis einschließt, senkt irgendwann seinen eigenen Referenzwert und kann dadurch eine falsche Anzeige erzeugen. Neu berechnet wird nur, wenn das rechtliche Ereignis oder die dafür geltende Regel einen neuen Referenzwert verlangt.
Für eine ohne Unterbrechung schrittweise ansteigende Preisermäßigung enthält § 11 Abs. 2 PAngV eine eigene Regel: Während der Aktion darf weiterhin der niedrigste Gesamtpreis vor Beginn der schrittweisen Ermäßigung angegeben werden. Andere nationale Umsetzungen und Ausnahmen brauchen eine eigene geprüfte Regel. Deren Version gehört zum gespeicherten Referenzwert, damit eine Prüfung später nachvollziehen kann, wie der Wert entstanden ist.
Eine Projektion veröffentlichen, keine zweite Wahrheit
Sobald der Referenzpreis feststeht, werden die anzeigefertigen Werte in das Lesemodell kopiert, das die Storefront ohnehin nutzt. In einem Suchdokument könnte es so aussehen:
1display_price
2 current
3 prior
4 reduction_announced
5 reduction_percentage
6 currency
7 valid_untilProduktseiten, Kategorieseiten, Suchergebnisse und Feeds sollten dieselbe Projektion verwenden. Das Frontend formatiert Beschriftung und Währung, wählt aber weder das Referenzfenster noch berechnet es eine andere Ersparnis. Ändert sich die Aktion, wird zuerst der dauerhafte Datensatz aktualisiert und anschließend die Projektion neu erzeugt.
Der schnelle Leseweg bleibt dadurch einfach, ohne den Suchindex zur rechtlichen Grundlage zu erklären. Geht der Index verloren, kann die Datenbank ihn reproduzieren. Fragt das Unternehmen nach dem Ursprung eines bestimmten Referenzpreises, liefern Preisintervalle, Aktionsdatensatz und Regelversion die Antwort.
Ausnahmen als ausdrückliche Regel behandeln
Das EU-Recht erlaubt den Mitgliedstaaten für bestimmte Fälle Ausnahmen oder kürzere Zeiträume. § 11 PAngV nimmt beispielsweise bestimmte individuelle Preisermäßigungen und bestimmte Preisermäßigungen für schnell verderbliche Waren unter den Voraussetzungen von Absatz 4 aus. Für schrittweise Ermäßigungen gilt die oben beschriebene Sonderregel.
Solche Ergebnisse gehören nicht als Vermutung in eine Komponente. Jeder Markt braucht eine freigegebene Regel mit Verantwortlichem und Gültigkeitsdatum. Bei einem neuen Produkt mit weniger als 30 Tagen Historie bewahrt das System die tatsächlich vorhandene Historie vollständig auf. Die geprüfte Marktregel bestimmt Bekanntgabe und Beschriftung. Die Software setzt diese Entscheidung konsistent um, statt sie zu erfinden.
Vor dem Start sollten mindestens diese Fälle geprüft werden:
- eine reguläre Ermäßigung nach mehreren Preisänderungen;
- eine zweite Ermäßigung, während ein vorheriger Tiefstpreis noch im 30-Tage-Fenster liegt;
- eine ohne Unterbrechung schrittweise ansteigende Ermäßigung;
- eine geplante Aktion an einer Zeitumstellung oder Marktzeitgrenze;
- dieselbe Variante in verschiedenen Märkten, Kanälen oder Währungen;
- Abbruch, Ablauf und Neuindexierung einer Aktion.
Im normalen Betrieb plant der Händler die Ermäßigung, das Backend speichert den Referenzpreis, alle Oberflächen erhalten dieselben Werte und die Historie bleibt prüfbar. Keine Seite betreibt beim Rendern rechtliche Preisberechnung.
Falls die Plattformentscheidung noch vor der Umsetzung liegt, erläutert mein Vergleich von Medusa und Shopify, wann sich die zusätzliche Betriebsverantwortung eines eigenen Workflows lohnt.
Quellen
Quellen geprüft am 1. August 2026.
Stehst du vor einer schwierigen Plattformentscheidung?
Beschreib mir, was das System leisten muss. Ich helfe dabei, aus den Anforderungen eine klare Architektur und einen umsetzbaren nächsten Schritt zu machen.
Projekt besprechen