Tracking-Referenz für Entwickler: window.RTR_HOOKS
Zuletzt aktualisiert:
Diese Seite richtet sich an Entwickler und Agenturen, die die Rentware-Buchungswidgets mit ihren eigenen Tags verbinden. Sie beschreibt die Browser-Seite. Serverseitiges Tracking über Rentware (GA4, Google Ads und Meta von unserem Server) braucht keinen Code: siehe Conversion-Tracking: was du wo einrichtest.
Überblick
- Das Widget sendet im Browser nichts an Tags, solange die Seite
window.RTR_HOOKSnicht definiert. Der ältere Namewindow.RENTWARE_HOOKSfunktioniert auch; gibt es beide, giltRTR_HOOKS. RTR_HOOKSwird bei jedem Ereignis neu gelesen. Es kann also spät gesetzt werden, zum Beispiel von einem GTM-Tag, solange es vor dem Ereignis existiert.- Das Widget lädt nie selbst ein Tag.
gtag,fbq,umamiundoaiqmüssen schon auf der Seite sein; fehlt eine Funktion, wird dieser Kanal stillschweigend übersprungen. Nur derdataLayerwird angelegt, wenn er nicht existiert. - Das Widget prüft keine Einwilligung für deine Tags. Lade sie erst nach der Einwilligung (Aufgabe deines Cookie-Banners).
- Alle Werte sind netto: Rabatte abgezogen, Kautionen weggelassen, MwSt. in
tax. Beträge sind Zahlen in der Hauptwährungseinheit (49.5), sofern nicht anders angegeben.
Snippet
<script>
window.RTR_HOOKS = Object.assign(window.RTR_HOOKS || {}, {
// E-Commerce-Ereignisse im GA4-Format in window.dataLayer (Google Tag Manager; funktioniert auch ohne GTM)
enableDataLayer: true,
// gtag('event', …) direkt
// enableGtagTracking: true,
// zusätzlich gtag('event', 'conversion', …) beim Kauf
// gtagAdsSendTo: 'AW-123456789/AbCdEfGhIj',
// gtag('set', 'user_data', …) für Enhanced Conversions
// enableGtagUserDataTracking: true,
// fbq('track', …) auf deinem Meta-Pixel
// enableMetaTracking: true,
// zusätzlich fbq('init', id, {…}) mit Kundendaten (erweiterter Abgleich)
// metaPixelId: '123456789012345',
// umami.track(…)
// enableUmamiTracking: true,
// oaiq('measure', 'order_created', …)
// enableOpenAiTracking: true,
// onAddToCart: (data) => {},
// onInitiateCheckout: (data) => {},
// onCheckoutSuccess: (data) => {},
})
</script>
Object.assign behält Schlüssel, die ein anderes Skript schon gesetzt hat.
Alle Optionen
| Schlüssel | Typ | Wirkung |
|---|---|---|
enableDataLayer |
boolean | Schreibt add_to_cart, begin_checkout, add_shipping_info und purchase in window.dataLayer |
enableGtagTracking |
boolean | Ruft gtag('event', …) mit denselben vier Ereignissen auf |
gtagAdsSendTo |
string | Ruft beim Kauf zusätzlich gtag('event', 'conversion', {…, send_to}) auf, z. B. 'AW-123456789/AbCdEfGhIj' |
enableGtagUserDataTracking |
boolean | Ruft beim Speichern der Kundendaten gtag('set', 'user_data', {…}) auf |
enableMetaTracking |
boolean | Ruft fbq('track', …) auf: AddToCart, InitiateCheckout, Purchase |
metaPixelId |
string | Mit enableMetaTracking: Ruft beim Speichern der Kundendaten fbq('init', metaPixelId, {…}) mit Kundendaten auf |
enableUmamiTracking |
boolean | Ruft umami.track(…) auf: add_to_cart, begin_checkout, purchase |
enableOpenAiTracking |
boolean | Ruft beim Kauf oaiq('measure', 'order_created', …) auf |
onAddToCart |
function | Wird aufgerufen, nachdem ein Artikel hinzugefügt wurde |
onInitiateCheckout |
function | Wird aufgerufen, wenn sich der Checkout öffnet |
onCheckoutSuccess |
function | Wird aufgerufen, wenn die Buchung abgeschlossen ist |
Ereignisse pro Schritt
| Schritt | dataLayer / gtag | Meta-Pixel | Umami | OpenAI | Wird ausgelöst, wenn |
|---|---|---|---|---|---|
| In den Warenkorb | add_to_cart |
AddToCart |
add_to_cart |
– | ein Artikel erfolgreich hinzugefügt wurde |
| Checkout geöffnet | begin_checkout |
InitiateCheckout |
begin_checkout |
– | sich der Checkout öffnet |
| Kundendaten gespeichert | add_shipping_info |
– | – | – | das Kontakt- und Rechnungsformular gespeichert wird |
| Buchung abgeschlossen | purchase |
Purchase |
purchase |
order_created |
siehe „Wann purchase ausgelöst wird“ |
Es gibt kein Browser-Ereignis für die Wahl von Standort und Zeitraum, für das Ansehen eines Artikels oder für den Beginn der Zahlung (add_payment_info gibt es nur serverseitig). Es gibt keine DOM-CustomEvents.
Wann purchase ausgelöst wird
purchase wird ausgelöst, wenn die Buchung abgeschlossen ist. Das ist nicht immer der Zeitpunkt der Zahlung:
- Reservierung, Vorkasse oder Überweisung, Gutschein: direkt nach dem Absenden (noch nicht bezahlt).
- Kartenzahlung im Checkout: wenn die Zahlung erfolgreich ist.
- Zahlungen mit Weiterleitung (PayPal, Zahlungsarten, die die Seite verlassen): erst, wenn der Besucher auf eine Seite mit dem Widget zurückkehrt. Kommt er nie zurück, gibt es kein
purchaseim Browser. Der serverseitige Kauf wird trotzdem gesendet.
dataLayer
Vor jedem Ereignis schreibt das Widget { ecommerce: null } in den dataLayer, um das vorherige E-Commerce-Objekt zu leeren, wie Google es empfiehlt.
// add_to_cart: jeder Artikel, dessen Menge gestiegen ist, automatisch hinzugefügte eingeschlossen
{ event: 'add_to_cart', ecommerce: {
currency: 'EUR',
value: 59.5, // Σ Preis × Menge
items: [{ item_id: 'a1b2c3', item_name: 'SUP Board', price: 29.75, quantity: 2, index: 0 }]
} }
// begin_checkout und add_shipping_info: Nettowert des Warenkorbs
{ event: 'begin_checkout', ecommerce: { currency: 'EUR', value: 59.5 } }
{ event: 'add_shipping_info', ecommerce: { currency: 'EUR', value: 59.5 } }
// purchase
{ event: 'purchase', ecommerce: {
transaction_id: 'SNLDX1', // Bestellnummer
currency: 'EUR',
value: 59.5, // netto, Rabatte abgezogen, Kautionen weggelassen
tax: 11.31, // MwSt.
items: [{ item_id: 'a1b2c3', item_name: 'SUP Board', price: 29.75, quantity: 2 }]
} }
priceist der rabattierte Netto-Stückpreis. Kautionspositionen stehen nie initems.transaction_idist die Bestellnummer (z. B.SNLDX1). Der Server sendet denselben Wert als GA4-transaction_id, Google-Ads-order_idund Meta-order_id.- Der dataLayer enthält keine E-Mail, keine Telefonnummer und keine Event-ID.
gtag
Mit enableGtagTracking ruft das Widget gtag('event', name, params) mit denselben ecommerce-Objekten wie im dataLayer auf (die items von purchase tragen zusätzlich index).
Mit gtagAdsSendTo löst der Kauf zusätzlich Folgendes aus:
gtag('event', 'conversion', {
transaction_id: 'SNLDX1', currency: 'EUR', value: 59.5, tax: 11.31,
items: [/* wie oben */],
send_to: 'AW-123456789/AbCdEfGhIj'
})
Mit enableGtagUserDataTracking, beim Speichern der Kundendaten:
gtag('set', 'user_data', {
email: 'jane@example.com',
phone_number: '+4915112345678', // nur wenn gültiges E.164, sonst weggelassen
address: { first_name: 'Jane', last_name: 'Doe', city: 'Berlin', postal_code: '10115', country: 'DE' }
})
Verwendet wird die Lieferadresse, wenn der Kunde eine eingegeben hat, sonst die Rechnungsadresse.
Meta-Pixel
fbq('track', 'AddToCart', { content_ids: ['a1b2c3'], content_type: 'product', currency: 'EUR', value: '29.75' })
fbq('track', 'InitiateCheckout', { value: '59.50', currency: 'EUR' })
fbq('track', 'Purchase', {
order_id: 'SNLDX1',
currency: 'EUR',
value: '59.50',
content_ids: ['a1b2c3'],
content_type: 'product',
contents: [{ id: 'a1b2c3', quantity: 2, price: '29.75', item_name: 'SUP Board' }],
num_items: 1 // Anzahl der Warenkorbzeilen
}, { eventID: 'purchase_SNLDX1' })
- Beträge für Meta sind Strings mit zwei Nachkommastellen.
eventIDistpurchase_+ Bestellnummer, dieselbeevent_idwie beim serverseitigen Purchase über die Conversions API, damit Meta die beiden dedupliziert.- Mit
metaPixelId, beim Speichern der Kundendaten:fbq('init', metaPixelId, { em, fn, ln, ct, zp, country })(Klartextwerte; das Pixel hasht sie).
Umami
Mit enableUmamiTracking und dem Umami-Skript auf der Seite:
umami.track('add_to_cart', { item_id: 'a1b2c3', item_name: 'SUP Board', quantity: 1, currency: 'EUR', value: 29.75 })
umami.track('begin_checkout', { value: 59.5, currency: 'EUR' })
umami.track('purchase', { revenue: 59.5, currency: 'EUR', transaction_id: 'SNLDX1', num_items: 1 })
Nur purchase trägt revenue. Leere Felder werden weggelassen. Umami setzt keine Cookies; ob du eine Einwilligung einholst, entscheidest du.
OpenAI-Ads-Pixel
Mit enableOpenAiTracking und dem OpenAI-Pixel (oaiq) auf der Seite:
oaiq('measure', 'order_created', {
type: 'contents',
amount: 5950, // kleinste Währungseinheit (Cent), netto
currency: 'EUR',
contents: [{ id: 'a1b2c3', name: 'SUP Board', content_type: 'product', quantity: 2 }]
}, { event_id: 'purchase_SNLDX1' })
Du kannst die Option auch weglassen und oaiq in onCheckoutSuccess selbst aufrufen.
Callbacks
Fehler, die in einem Callback geworfen werden, werden abgefangen und in der Konsole ausgegeben, damit sie die Buchung nicht unterbrechen.
onAddToCart({ productId, quantity, currency, name })
productId ist die Artikel-ID, quantity die hinzugefügte Menge.
onInitiateCheckout({ transactionTotal, transactionId })
transactionTotal ist der zu zahlende Betrag (brutto, inklusive Kautionen), nicht der Netto-Warenkorbwert der anderen Ereignisse. transactionId ist die Bestellnummer.
onCheckoutSuccess({ ecommerceData, fbqData, eventID, price })
ecommerceData.purchase: daspurchase-Objekt aus dem dataLayer (transaction_id,currency,value,tax,items).fbqData: die Purchase-Parameter für Meta (ohneorder_id).eventID:purchase_+ Bestellnummer.price: veraltetes Objekt{ gross, net, vat }in Cent, inklusive Kautionen. Nutze stattdessenecommerceData.
Beispiel, ein eigenes Pixel:
window.RTR_HOOKS = Object.assign(window.RTR_HOOKS || {}, {
onCheckoutSuccess: ({ ecommerceData, eventID }) => {
const p = ecommerceData.purchase
myPixel('purchase', { order: p.transaction_id, value: p.value, currency: p.currency, dedup: eventID })
},
})
Google Tag Manager
- Füge das Snippet mit
enableDataLayer: truehinzu, entweder direkt in der Seite oder als GTM-Tag vom Typ Benutzerdefiniertes HTML (Custom HTML) mit dem Trigger Initialisierung – Alle Seiten (Initialization – All Pages). - Lege Trigger vom Typ Benutzerdefiniertes Ereignis (Custom Event) für
add_to_cart,begin_checkout,add_shipping_infoundpurchasean. - Lege Variablen vom Typ Datenschichtvariable (Data Layer Variable, Version 2) an, zum Beispiel
ecommerce.value,ecommerce.currency,ecommerce.transaction_id,ecommerce.items. - GA4-Ereignis-Tags: Ereignisname
{{Event}}oder der feste Name, und „E-Commerce-Daten senden“ mit der Datenquelle „Data Layer“. - Meta-Purchase über GTM: Setze die Event-ID auf
purchase_{{DLV - ecommerce.transaction_id}}. Sie passt dann zum serverseitigen Purchase, und Meta dedupliziert die beiden.
Nutzt du für dieselbe GA4-Property auch serverseitiges Tracking über Rentware, sende die dataLayer-Ereignisse nicht zusätzlich dorthin: GA4 dedupliziert nur purchase (anhand der transaction_id), „In den Warenkorb“ und die anderen Funnel-Ereignisse würden also doppelt gezählt.
Einwilligung
Das Widget liest die Einwilligung für das, was es an den Rentware-Server sendet (der entscheidet, was an GA4, Google Ads und Meta geht). Deine eigenen Tags steuert es nicht.
- Es liest Google Consent Mode v2 aus
window.dataLayer: Einträgegtag('consent', 'default' | 'update', {…})und Objekte im GTM-Stil wie{ event: 'consent_update', ad_storage: 'granted', … }. Es spielt sie der Reihe nach ab: Ein späteresupdateüberschreibt frühere Werte. - Signale:
ad_storage,analytics_storage,ad_user_data,ad_personalization. Jedes steht standardmäßig aufdenied. - Hat die Seite gar keinen Consent-Mode-Eintrag, wird die Anfrage als „kein Einwilligungssignal“ markiert, und das Tracking-Protokoll zeigt
skipped: no consent signal. - Regionsspezifische
default-Einträge (mitregion) lassen sich im Browser nicht dem Standort des Besuchers zuordnen: Nur ihredenied-Werte werden angewendet. - Späte Einwilligung funktioniert: Die Einwilligung wird bei jeder Anfrage neu gelesen. Ein Besucher, der zustimmt, nachdem das Widget geladen hat, ist ab der nächsten Anfrage erfasst, solange dein Banner ein Consent-Mode-
updateinwindow.dataLayerschreibt. - Das Widget liest nur den dataLayer namens
dataLayerim selben Fenster. Ein umbenannter dataLayer oder ein Widget in einem iframe bedeutet: kein Einwilligungssignal.
So prüfst du eine Seite: Akzeptiere den Banner, öffne die Konsole und tippe dataLayer. Es muss einen consent-Eintrag (oder ein consent_update-Ereignis) geben, bevor der Besucher bucht.
Klick-IDs
- Das Widget erfasst
gclid,gbraidundwbraidaus der URL (gclidauch aus dem Linker-Parameter_glvon Google oder dem Cookie_gcl_aw) undfbclidaus der URL oder dem Cookie_fbcvon Meta. Die URL hat Vorrang vor dem Cookie. - Erfasst wird nur mit
ad_storage-Einwilligung. Vorher wird nichts aus Cookies gelesen und nichts gespeichert. Kommt die Einwilligung später, während die Klick-ID noch in der URL steht, wird sie dann erfasst. - Klick-IDs werden für den Tab im
sessionStoragegehalten (gleicher Tab, gleiche Domain, weg, sobald der Tab geschlossen wird). Der erste Klick gilt. - Das Widget sendet sie mit seinen Anfragen an den Rentware-Server, der sie für Google Ads und Meta nutzt. Deinen Browser-Ereignissen werden sie nicht hinzugefügt.
- Landingpage und Buchungsseite sind verschieden? Lass das Widget-Skript auch auf der Landingpage laufen, oder lass dein Google-Tag (mit
url_passthrough) oder Meta-Pixel das Cookie_gcl_aw/_fbcschreiben. Fürgbraidundwbraidgibt es keinen Cookie-Fallback.
Test-Checkliste
- Füge
RTR_HOOKShinzu, öffne die Seite, akzeptiere den Banner. - Lege einen Artikel in den Warenkorb und tippe dann
dataLayerin die Konsole: Die letzten Einträge sind{ ecommerce: null }und{ event: 'add_to_cart', … }. - Schließe eine Buchung mit „Reservieren“ oder Vorkasse ab und prüfe den
purchase-Eintrag; seinetransaction_idist die Bestellnummer. - Storniere die Testbuchung danach in Rentware.