
EU-Verpackungsverordnung (PPWR): Auswirkungen auf den E-Commerce
Ab 12. August 2026 gilt die EU-Verpackungsverordnung (PPWR) und bringt neue Spielregeln für den E-Commerce. Wir zeigen, welche Aufgaben diese
tl;dr: Diese Anleitung zeigt dir Schritt für Schritt, wie du Stripe-Zahlungen in deinem Shop oder in deiner E-Commerce-Plattform zuverlässig über Webhooks und Server-Side Google Tag Manager (sGTM) mithilfe des Data Client von Stape tracken kannst. Wir zeigen dir, wie du purchase-Events mit vollständigen Conversion-Daten an Tools wie Google Analytics 4, Google Ads, Meta Ads oder LinkedIn Ads senden kannst.
Lesezeit: ca. 20 Minuten
Letztes Update: 20. Februar 2026
Die nachfolgende Anleitung basiert auf einer realen, funktionierenden Implementierung für ein österreichisches SaaS-Unternehmen. Bei Fragen oder für individuelles Setup-Consulting, kontaktiere uns gerne!
Zuverlässiges Conversion Tracking (unabhängig von Ad-Blockern und ITP)
Enhanced Conversions mit vollständigen Kundendaten
Automatische Deduplizierung zwischen Browser- und Server-Events
Server-Side Tracking für alle wichtigen Werbeplattformen
Du verwendest Stripe für die Zahlungsabwicklung in deiner Shop-Plattform
Du verwendest Google Tag Manager Server-Side-Tracking über stape.io (MONOBUNT ist offizieller Partner)
Du willst Kauf-Daten an GA4 und Google Ads oder Meta CAPI bzw. LinkedIn CAPI datenschutzoptimiert weiterschicken
Funktioniert auch wenn der User seinen Browser schließt, bevor er auf eine Danke-Seite kommt
Funktioniert auch in proprietären Shopsystemen oder wenn kein E-Commerce dataLayer vorhanden ist
Umgeht Ad-Blocker und Cookie-Blocking
Zugriff auf vollständige Stripe Payment Intent Daten
Keine Manipulation durch Client-Side Code möglich
Nachfolgend siehst du ein Flow-Chart. Dieses Diagramm zeigt den kompletten Ablauf von der Stripe-Zahlung auf deiner E-Commerce-Plattform über den Webhook bis zur parallelen Verteilung der Conversion-Daten an die verschiedenen Server-Side Tracking APIs:
Bevor du den Stripe Webhook anlegen kannst, brauchst du deine Stape-Subdomain. Die bildet die Basis deiner Webhook-Endpoint-URL. Gehe deshalb zunächst in deinen Stape-Account unter Container Settings → Domains (Tagging Server URLs) und notiere dir deine Subdomain (z. B. tracking.example.com). Erst dann hast du alle Informationen, um den Webhook in Stripe korrekt zu konfigurieren.
Im Gegensatz zu einem Standard-Tracking-Setup, wo die Daten – unter der Bedingung eines vorhandenen dataLayers – über webGTM in GA4 (browserseitig) oder in einen GA4 Client (serverseitig) eingehen, können wir den GA4-Client nicht für Webhook-Requests verwenden. Daher musst du den Data Client von Stape installieren. Dieser kann Webhook-Requests im Server-GTM (sGTM) verarbeiten:
Lade den Stape Data Client von GitHub (diesen kannst du nicht über die GTM-Bibliothek importieren, sondern der Schritt muss manuell erfolgen).
Server Container → Templates → Client Templates → New
Drei Punkte → Import → ZIP-Datei entpacken und das .tpl-File (Template File) installieren
Save und Publish
Wichtig: Veröffentliche deinen sGTM-Container, sobald du das Template des Data Clients importiert und abgespeichert hast. Ansonsten funktioniert der Preview-Modus nicht, bzw. wirst du im Preview keine Webhooks sehen. Sobald du den Container mit dem Client einmal veröffentlicht hast, funktioniert der Preview-Mode wie gewohnt, auch für Webhooks.
Client Type: Data Client
Client Name: DC (Anm. kann jedoch frei gewählt werden, aber je kürzer, desto weniger fehleranfällig)
Additional Paths: /purchase
Save
Wichtig: Der Path /purchase muss mit deiner Webhook-Endpoint-URL übereinstimmen. Dieser kann auch einen anderen namen wie etwa /stripe haben – wichtig ist eben nur, dass dieser Pfad der exakt gleiche ist, den du in Teil 3 in deinem Stripe-Account angelegt hast.
Wir verwenden in unserem Beispiel das payment_intent.succeeded Ereignis aus der Stripe Payment Intents API. Gehe hier zunächst auf die Webhooks (dt. „Ereignisziele“) in deinem Stripe-Account. Füge hier ein neues Ziel hinzu.
Wähle im ersten Schritt das benötigte Webhook-Ereignis aus. Nachdem wir wie zuvor erwähnt auf erfolgreiche Zahlungen zugreifen wollen, tippe bei der Suche „intent“ ein und wähle anschließend payment_intent.succeeded aus.
Im zweiten Schritt wählst du „Webhook Endpoint“. Im dritten und letzten Schritt definierst du die Endpoint-URL. Wichtig: diese muss deiner Stape (Sub-)Domain entsprechen, welche du in deinem Stape-Account in den Container Settings unter „Domains (Tagging Server URLs)“ findest.
Beispiel: Wenn deine Subdomain bei Stape also „tracking“ lautet und deine Website example.com, dann muss die Endpoint URL hier https://tracking.example.com/purchase lauten. Inklusive https:// und ohne Trailing Slash („/“) am Ende. Unterscheidet sich die URL deines Stape Containers auch nur mit einem Zeichen von der Endpoint-URL von Stripe, dann funktioniert die Übergabe der Daten über den Webhook nicht.
Wenn Stripe den payment_intent.succeeded Webhook sendet, hast du nur Zugriff auf alle Daten, die Stripe im paymentIntent-Objekt selbst mitschickt. Du kannst allerdings beim Erstellen oder Aktualisieren des paymentIntent-Webhooks beliebige Key-Value-Paare wie „value“ oder „phone_number“ als Metadata anhängen.
In unserem Fall stellen wir die Payload aus dem Stripe paymentIntent und den Kundendaten zusammen. Die Funktion builtTrackingPayload() erwartet zwei Parameter:
Wichtig: Sende mit den customerData nur Parameter, die tatsächlich Daten enthalten, also die ein Kunde in deinem Checkout befüllen muss. Nachfolgend findest du ein Beispiel, wie eine solche Payload aussehen könnte:
Nachdem alle Fälle individuell sind, ist unser Tipp allerdings, dass du vorher mit deinem Entwickler(team) sprichst, wie eine solche Payload optimalerweise für deinen Shop bzw. für deinen Usecase aussehen sollte. (Pflicht-)Parameter, welche du für das Setup unbedingt benötigst, sind folgende:
Alle anderen Parameter (z.B. first_name, last_name – siehe weiter unten bei „Event Data Variablen erstellen“) werden zwar nicht für das Conversion Tracking benötigt, sind aber empfohlen für Enhanced Conversions (Google Ads) oder Advanced Matching (Meta) und würden wir daher auf alle Fälle empfehlen.
Nun kannst du im nächsten Schritt die Event Data Variablen für alle Webhook-Felder erstellen. Das sind jene Parameter, welche du über den definierten Payload von Stripe bekommst (vgl. Grafik im Bereich „Webhook-Payload):
Variables → New User-Defined Variables → Event Data:
| Variable Name | Key Path |
|---|---|
| Stripe – Transaction ID | paymentIntentId |
| Stripe – Value | value |
| Stripe – Currency | currency |
| Stripe – Email | email |
| Stripe – First Name | address.first_name |
| Stripe – Last Name | address.last_name |
| Stripe – Phone | phone_number |
| Stripe – Street | address.street |
| Stripe – City | address.city |
| Stripe – Postal Code | address.postal_code |
| Stripe – Region | address.region |
| Stripe – Country | address.country |
Wichtig bei verschachtelten Objekten: Verwende die Dot-Notation (z.B. address.city. Dies ist notwendig weil die Adresse ein JavaScript-Object ist, das aus Vorname, Nachname, Straße, Stadt, PLZ, Region und Land besteht. Sie sind also Propertys (Eigenschaften) des Objekts address.
Triggers → New → Custom Event:
Trigger Name: custom - purchase (Stripe) (Anm. so nennen wir den Trigger, du kannst ihn natürlich auch auf Basis deiner standardisierten Namensgebung benennen)
Event Name: purchase
This trigger fires on: Some Custom Events
Bedingung:
Variable: Request Path
Operator: equals
Value: /purchase
Variable: Client Name
Operator: equals
Value: DC
Wenn du die Variable Request Path initial nicht auswählen kannst, dann musst du sie zunächst aktivieren. Wenn du nur den Data Client von Stape in deinem sGTM-Container verwendest, musst du die optionalen Einstellungen (Client Name equals DC) nicht tätigen. Wenn du aber mehrere Clients (z.B. GA4, GTM) verwendest, ist diese Bedingung eine Art Sicherheitseinstellung, damit der Request auch nur von jenem Client verarbeitet wird, der damit umgehen kann.
Du benötigst zwei GA4 Tags für optimales, umfassendes Tracking. Eines für den Kauf (über Webhook) und eines für alle anderen Events.
Tag 1: GA4 – Non-Purchase Events (für Web-Traffic)
Event Name: {{Event Name}}
Trigger: custom - all events ga4 except purchase) (siehe nachfolgender Screenshot)
Wird ausgelöst für: page_view, click, scroll, etc.
Tag 2: GA4 – Purchase Event (für Webhook)
Measurement ID: Deine GA4 Measurement ID (findest du in GA4 unter Verwaltung > Datenerhebung > Datenstreams)
Event Name: purchase
custom - purchase (Stripe) (siehe oben)
Event Parameters:
transaction_id: {{Stripe - Transaction ID}}
value: {{Stripe - Value}}
currency: {{Stripe - Currency}}
payment_method: stripe
User Data from Event (Enhanced Conversions):
Mappe die Event Data Keys direkt:
| Field | Event Data Key |
|---|---|
email | |
| phone_number | phone_number |
| address_first_name | address.first_name |
| address_last_name | address.last_name |
| address_street | address.street |
| address_city | address.city |
| address_region | address.region |
| address_postal_code | address.postal_code |
| address_country | address.country |
Tags → New → Google Ads Conversion Tracking:
Conversion ID: Deine numerische Conversion ID (nur die Zahl, ohne das ‚AW-‚ Präfix. Deine Google Ads ID findest du unter Tools > Data Manager > Google Tag > Verwalten )
Conversion Label: Dein Conversion Label aus dem angelegten Zielvorhaben (Zielvorhaben > Zusammenfassung > Klick auf Kauf-Zielvorhaben > Tag-Einrichtung)
Conversion Value: {{Stripe - Value}}
Currency Code: {{Stripe - Currency}}
Transaction ID: {{Stripe - Transaction ID}}
Trigger: custom - purchase (Stripe)
Wichtig: Durch die Verknüpfung zwischen GA4 und Google Ads über den Conversion Linker fließen die für die Enhanced Conversions benötigten Parameter automatisch mit! Damit der Conversion Linker im sGTM auch bei Webhook-Requests korrekt funktioniert, benötigt er eine gültige page_location. Da Webhook-Requests keinen Browser-Kontext haben, liefert Stripe diesen Wert nicht automatisch mit.
Du musst die URL deiner Bestellbestätigungsseite daher explizit in der Payload mitsenden: „page_location“: „https://deine-domain.com/thank-you“. Fehlt dieser Wert, erhältst du im sGTM Preview die Fehlermeldung „Provided page_location is not a valid URL“ – und der Conversion Linker feuert nicht. Sobald page_location in deiner Payload vorhanden ist, erkennt der Conversion Linker den Request korrekt und die Enhanced Conversion Daten aus GA4 fließen automatisch in Google Ads mit.
Wenn du nicht nur serverseitig über die Meta Conversions API tracken, sondern zusätzlich Browser-Events über das Meta Pixel senden möchtest, musst du eine saubere Deduplizierung einrichten. Meta verwendet dafür eine eindeutige Event-ID, um doppelt eintreffende Events (Pixel + CAPI) als ein einziges Ereignis zu zählen.
Aktiviere dafür zunächst die Unique Event ID von Stape in deinem Web-GTM-Container, indem du sie in den Variablenvorlagen unter „Templates → Variable Templates“ konfigurierst und anschließend sowohl im Pixel-Event als auch im CAPI-Event als event_id mitsendest.
Anders als im webGTM, wo du die Variable importieren musst, reicht es im sGTM, wenn du eine Event-Data-Variable mit dem Key Path „event_id“ anlegst:
Erstelle nun in deinem sGTM-Container eine Regex Table Variable für eine intelligente Event ID.
Variables → New → Regex Table:
Input Variable: {{Event Name}}
Pattern & Output:
Input: purchase → Output: {{Stripe - Transaction ID}}
Input: .+ → Output: {{ed - event_id}}
Set Default Value: {{ed - event_id}}
Name: RegEx Lookup – Event ID
Wichtig: Diese Variable muss in jedem Conversion-Tag als Event ID eingetragen werden!
GA4 – Purchase Event: Füge unter „Event Parameters“ den Parameter event_id mit dem Wert {{RegEx Lookup – Event ID}} hinzu.
Google Ads Conversion Tag: Füge unter „Event Settings“ → „Event Data“ den Parameter event_id → {{RegEx Lookup – Event ID}} ein (sofern dein Template diesen unterstützt).
Meta CAPI Tag: Bereits konfiguriert unter „Server Event Data Override → Event ID“.
LinkedIn CAPI Tag: Bereits konfiguriert unter „Event Data → Event ID“ (hier wird direkt {{Stripe - Transaction ID}} verwendet — das ist für rein webhook-basierte Purchases korrekt, da kein Browser-Duplikat entsteht).
Nur wenn alle Tags dieselbe Event ID verwenden, funktioniert die plattformübergreifende Deduplizierung zuverlässig. Meta, Google Ads und GA4 erkennen: gleiche Event ID = gleicher Kauf = wird nur einmal gezählt, auch wenn Browser-Event und Webhook-Event gleichzeitig eintreffen.
Bei allen Webhook-Events, die einen Kauf betreffen, wird die Stripe Transaction ID als eindeutige Kennung mitgeschickt. Für alle anderen Events (z. B. page_view, add_to_cart usw.) wird dagegen die Unique Event ID von Stape als event_id verwendet.
Der Grund dafür: Nur das purchase‑Event verfügt über eine Transaction ID (paymentIntentId aus der Payload). Alle anderen Events haben keine solche Transaktionskennung, daher nutzt du hier konsequent die Unique Event ID von Stape als eindeutige event_id.
Tags → New → Facebook Conversions API:
Configuration:
Pixel ID: Deine Meta Pixel ID (findest du im Business Manager bzw. Events Manager)
API Access Token: CAPI Access Token (kannst du ebenfalls im Events Manager erstellen)
Event Name: Purchase
Server Event Data Override:
Event ID: {{RegEx Lookup - Event ID}}
User Data:
| Field | Variable |
|---|---|
{{Stripe - Email}} | |
| Phone | {{Stripe - Phone}} |
| First Name | {{Stripe - First Name}} |
| Last Name | {{Stripe - Last Name}} |
| City | {{Stripe - City}} |
| State | {{Stripe - Region}} |
| Zip Code | {{Stripe - Postal Code}} |
| Country | {{Stripe - Country}} |
value: {{Stripe - Value}}
currency: {{Stripe - Currency}}
transaction_id: {{Stripe - Transaction ID}}
Firing Triggers:
custom - all events ga4 except purchase (GA4 Client) – für Web-Events
custom - purchase (Stripe) für Server-Events
Wichtig: Das Meta-Template hasht User-Daten automatisch! Du musst also PII nicht manuell hashen. Die Info dazu („The tag will automatically hash parameters that need it, pre-hashed data is also accepted„) findest du auch im FB Tag im Bereich „User Data“.
LinkedIn Setup vorbereiten
LinkedIn Campaign Manager → Data → Sources
Insight Tag → Settings
Aktiviere „Enable enhanced conversion tracking“
LinkedIn CAPI Tag
Wir verwenden hierzu das Template von Stape, das du unter Templates > Tag Templates > LinkedIn Conversion API findest. Das Stape LinkedIn-Template hasht die Email automatisch (SHA256). Du kannst auch das Standard-Template von LinkedIn verwenden, dann sind die nachfolgenden Einstellungen allerdings leicht verändert. Anschließend kannst du ein Tag anlegen:
Tags → New → LinkedIn Conversion API:
Event Type: Conversion
Access Token: LinkedIn API Token (Anleitung direkt von LinkedIn)
Conversion Rule ID: Deine Conversion ID
Trigger: custom - purchase (Stripe)
Event Data:
Currency: {{Stripe - Currency}}
Amount (Conversion-Wert): {{Stripe - Value}}
Event ID: {{Stripe - Transaction ID}}
User Ids Override:
Email (SHA256): {{Stripe - Email}}
User Info Override:
First Name: {{Stripe - First Name}}
Last Name: {{Stripe - Last Name}}
Country Code: {{Stripe - Country}}
Server-GTM Preview Mode öffnen
Drei Punkte im oberen rechten Eck → Send requests manually (siehe nachfolgender Screenshot)
Kopiere den Wert des X-Gtm-Server-Preview Header (siehe nachfolgender Screenshot)
Stape.io Account → Container Settings → Preview Header Config
Header einfügen → Save (es dauert einige Sekunden, bis die Änderungen bei Stape deployed sind)
Wichtige Informationen:
⚠️ Der Preview Header ist nur wenige Tage gültig
⚠️ Daher vor jedem Test checken und den Wert ggf. aktualisieren
⚠️ Nach dem Test den HTTP Header umbedingt wieder entfernen und die Änderung bei Stape deployen
1. Führe eine Test-Zahlung mit einer Stripe Test-Karte durch
2. Im sGTM Preview Mode solltest du sehen:
Incoming HTTP Request mit Path /purchase
Client: Data Client (claimed)
Event: purchase
3. Tab „Event Data“ prüfen:
Sind alle Felder vorhanden? (paymentIntentId, value, email, etc.)
Sind die verschachtelten Objekte korrekt? (user_data -> address.city, address.postal_code, etc.)
4. Tab „Tags“ prüfen:
Welche Tags haben gefeuert?
Status: Fired? Not Fired?
Outgoing Requests prüfen (sind die User-Daten gehasht?)
Problem: „Provided page_location is not a valid URL“
Lösung: Füge page_location: 'https://deine-domain.com/thank-you' zur Payload hinzu
Problem: Ein Feld wie z.B. die Telefonnummer ist undefined
Lösung: Sende ein Feld nur, wenn es im Checkout vorhanden ist
Problem: fbp Cookie ist undefined bei Meta
Lösung: Das ist normal bei Webhooks – das Advanced Matching via Mailadresse reicht aus
Ja – jede Plattform (GA4, Google Ads, Meta, LinkedIn, TikTok) benötigt im sGTM ihr eigenes Tag mit spezifischer Konfiguration. Aber: Alle nutzen die gleichen Variablen aus deinem Checkout, welche über Stripe zur Verfügung gestellt werden.
Ja – alle modernen CAPI Templates (Meta, LinkedIn, TikTok) hashen benutzerbezogene Daten automatisch (Email, Telefonnummer, Namen → SHA256). Du musst also nichts manuell hashen.
Ja – bei Webhook-Events ist der fbp Cookie nicht verfügbar. Meta, LinkedIn, etc. nutzen stattdessen deterministisches Matching via Email, Telefonnummer und Namen. Das ist im Normalfall sogar robuster als Cookie-basiertes Matching.
Verwende die RegEx-Table mit transaction_id (purchase) bzw. event_id (alle anderen Events) als Event ID (in allen Tags!)
Meta, Google Ads, etc. erkennen dann: Gleiche Event ID = Gleicher Kauf
Auch bei mehrfachem Webhook-Call oder Page-Reload wird der Kauf Nur 1x gezählt
Das ist normal bei Server-Side Requests. Die Meldung bedeutet nur: „Dies ist ein Server-Request, daher kann ich keine Browser-Cookies setzen.“ Das ist kein Fehler – genau so soll Server-Side Tracking funktionieren, Stichwort First-Party-Data.
Mit diesem Setup kannst du ein 100% zuverlässiges, vollautomatisches, Ad-Blocker-resistentes Conversion Tracking System aufbauen, das:
Unabhängig vom Browser funktioniert
Auch in proprietären Shopsystemen oder in CMS-Shopsystemen ohne dataLayer funktioniert
Vollständige Stripe Payment Intent Daten nutzt
Enhanced Conversions für alle relevanten Online Marketing Plattformen bereitstellt
Automatisch Events dedupliziert
DSGVO-konform über deinen eigenen (Stape-)Server läuft
COO
Gerald Emprechtinger ist seit 2017 im Team von MONOBUNT und seit Februar 2022 als Agenturleiter tätig. Er hat ein Diplomstudium für Marketing und Medienmanagement an der FH Salzburg sowie ein berufsbegleitendes MSc-Studium für Digital Marketing & Analytics am MCI Innsbruck abgeschlossen. Seine Leidenschaft gilt der Suchmaschinenoptimierung und der Webanalyse. Seit 2015 beschäftigt er sich mit Google Tag Manager und hat dazu viele Blogartikel und Gastartikel verfasst. Hier geht es zu den weiteren Blogartikeln von Gerald bei MONOBUNT.

EU-Verpackungsverordnung (PPWR): Auswirkungen auf den E-Commerce
Ab 12. August 2026 gilt die EU-Verpackungsverordnung (PPWR) und bringt neue Spielregeln für den E-Commerce. Wir zeigen, welche Aufgaben diese

EU-Gewährleistungslabel & GARAN-Label: Das kommt ab 27. September 2026 auf deinen Shop zu
Ab 27. September 2026 muss beim Verkauf von Konsumgütern im Online-Shop das Gewährleistungslabel verpflichtend platziert werden. Erfahre hier, wie du

robots.txt 2026: Wie du sie konfigurierst und warum sie plötzlich wieder wichtig ist
Wer 2026 einfach alle AI-Bots blockt, verliert messbar Traffic. Wir zeigen dir wie eine differenzierte Konfiguration aussieht, was Cloudflares Managed

KI-Kennzeichnungspflicht ab 2. August 2026: Was du jetzt wissen musst
Ab 2. August 2026 gilt Art. 50 der EU-KI-Verordnung. Was du zu KI-Texten, Bildern und Deepfakes wissen musst, inkl. Checkliste