Aller au contenu principal

Référence de suivi pour les développeurs : window.RTR_HOOKS

Dernière mise à jour:

Cette page s’adresse aux développeurs et aux agences qui connectent les widgets de réservation Rentware à leurs propres balises. Elle décrit le côté navigateur. Le suivi côté serveur via Rentware (GA4, Google Ads et Meta depuis notre serveur) ne nécessite aucun code : voir Suivi des conversions : que configurer, et où.

Vue d’ensemble

  • Le widget n’envoie rien aux balises du navigateur tant que la page ne définit pas window.RTR_HOOKS. L’ancien nom window.RENTWARE_HOOKS fonctionne aussi ; si les deux existent, RTR_HOOKS l’emporte.
  • RTR_HOOKS est lu à chaque déclenchement d’un événement. Il peut être défini tardivement, par exemple par une balise GTM, tant qu’il existe avant l’événement.
  • Le widget ne charge jamais de balise lui-même. gtag, fbq, umami et oaiq doivent déjà être présents sur la page ; si une fonction manque, ce canal est ignoré sans message. Seul le dataLayer est créé s’il n’existe pas.
  • Le widget ne vérifie pas le consentement pour vos balises. Ne les chargez qu’après consentement (c’est le rôle de votre bannière cookies).
  • Toutes les valeurs sont nettes : remises déduites, cautions exclues, TVA dans tax. Les montants sont des nombres en unités principales (49.5), sauf mention contraire.

Snippet

<script>
  window.RTR_HOOKS = Object.assign(window.RTR_HOOKS || {}, {
    // événements e-commerce au format GA4 dans window.dataLayer (Google Tag Manager ; fonctionne aussi sans GTM)
    enableDataLayer: true,

    // gtag('event', …) directement
    // enableGtagTracking: true,
    // gtag('event', 'conversion', …) supplémentaire lors de l’achat
    // gtagAdsSendTo: 'AW-123456789/AbCdEfGhIj',
    // gtag('set', 'user_data', …) pour les conversions améliorées
    // enableGtagUserDataTracking: true,

    // fbq('track', …) sur votre pixel Meta
    // enableMetaTracking: true,
    // en plus, fbq('init', id, {…}) avec les données client (correspondance avancée)
    // metaPixelId: '123456789012345',

    // umami.track(…)
    // enableUmamiTracking: true,
    // oaiq('measure', 'order_created', …)
    // enableOpenAiTracking: true,

    // onAddToCart: (data) => {},
    // onInitiateCheckout: (data) => {},
    // onCheckoutSuccess: (data) => {},
  })
</script>

Object.assign conserve les clés déjà définies par un autre script.

Toutes les options

Clé Type Effet
enableDataLayer boolean Pousse add_to_cart, begin_checkout, add_shipping_info et purchase dans window.dataLayer
enableGtagTracking boolean Appelle gtag('event', …) avec les mêmes quatre événements
gtagAdsSendTo string Lors de l’achat, appelle en plus gtag('event', 'conversion', {…, send_to}), par ex. 'AW-123456789/AbCdEfGhIj'
enableGtagUserDataTracking boolean À l’enregistrement des données client, appelle gtag('set', 'user_data', {…})
enableMetaTracking boolean Appelle fbq('track', …) : AddToCart, InitiateCheckout, Purchase
metaPixelId string Avec enableMetaTracking : à l’enregistrement des données client, appelle fbq('init', metaPixelId, {…}) avec les données client
enableUmamiTracking boolean Appelle umami.track(…) : add_to_cart, begin_checkout, purchase
enableOpenAiTracking boolean Lors de l’achat, appelle oaiq('measure', 'order_created', …)
onAddToCart function Appelée après l’ajout d’un article
onInitiateCheckout function Appelée à l’ouverture du tunnel de commande
onCheckoutSuccess function Appelée lorsque la réservation est finalisée

Événements par étape

Étape dataLayer / gtag Pixel Meta Umami OpenAI Se déclenche quand
Ajout au panier add_to_cart AddToCart add_to_cart – un article a été ajouté avec succès
Ouverture du tunnel de commande begin_checkout InitiateCheckout begin_checkout – le tunnel de commande s’ouvre
Données client enregistrées add_shipping_info – – – le formulaire de contact et de facturation est enregistré
Réservation finalisée purchase Purchase purchase order_created voir « Quand purchase se déclenche »

Il n’existe pas d’événement navigateur pour le choix du lieu et des dates, la consultation d’un article ou le début du paiement (add_payment_info n’existe que côté serveur). Il n’y a pas de CustomEvent DOM.

Quand purchase se déclenche

purchase se déclenche lorsque la réservation est finalisée, ce qui ne coïncide pas toujours avec le paiement :

  • Réservation, prépaiement ou virement bancaire, bon d’achat : juste après l’envoi (pas encore payé).
  • Paiement par carte dans le tunnel de commande : lorsque le paiement réussit.
  • Paiements avec redirection (PayPal, moyens de paiement qui quittent la page) : seulement lorsque le visiteur revient sur une page comportant le widget. S’il ne revient jamais, il n’y a pas de purchase navigateur. L’achat côté serveur est envoyé malgré tout.

dataLayer

Avant chaque événement, le widget pousse { ecommerce: null } pour vider l’objet ecommerce précédent, comme le recommande Google.

// add_to_cart : chaque article dont la quantité a augmenté, y compris ceux ajoutés automatiquement
{ event: 'add_to_cart', ecommerce: {
  currency: 'EUR',
  value: 59.5,                      // Σ prix × quantité
  items: [{ item_id: 'a1b2c3', item_name: 'SUP Board', price: 29.75, quantity: 2, index: 0 }]
} }

// begin_checkout et add_shipping_info : valeur nette du panier
{ 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',         // référence de commande
  currency: 'EUR',
  value: 59.5,                      // net, remises déduites, cautions exclues
  tax: 11.31,                       // TVA
  items: [{ item_id: 'a1b2c3', item_name: 'SUP Board', price: 29.75, quantity: 2 }]
} }
  • price est le prix unitaire net après remise. Les lignes de caution ne figurent jamais dans items.
  • transaction_id est la référence de commande (par ex. SNLDX1). Le serveur envoie la même valeur comme transaction_id GA4, order_id Google Ads et order_id Meta.
  • Le dataLayer ne contient ni e-mail, ni téléphone, ni ID d’événement.

gtag

Avec enableGtagTracking, le widget appelle gtag('event', name, params) avec les mêmes objets ecommerce que le dataLayer (les items de purchase portent aussi index).

Avec gtagAdsSendTo, l’achat déclenche en plus :

gtag('event', 'conversion', {
  transaction_id: 'SNLDX1', currency: 'EUR', value: 59.5, tax: 11.31,
  items: [/* comme ci-dessus */],
  send_to: 'AW-123456789/AbCdEfGhIj'
})

Avec enableGtagUserDataTracking, à l’enregistrement des données client :

gtag('set', 'user_data', {
  email: 'jane@example.com',
  phone_number: '+4915112345678',   // uniquement si E.164 valide, sinon omis
  address: { first_name: 'Jane', last_name: 'Doe', city: 'Berlin', postal_code: '10115', country: 'DE' }
})

L’adresse de livraison est utilisée si le client en a saisi une, sinon l’adresse de facturation.

Pixel Meta

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                      // nombre de lignes du panier
}, { eventID: 'purchase_SNLDX1' })
  • Les montants Meta sont des chaînes à deux décimales.
  • eventID vaut purchase_ + référence de commande, le même event_id que le Purchase de l’API Conversions côté serveur, si bien que Meta déduplique les deux.
  • Avec metaPixelId, à l’enregistrement des données client : fbq('init', metaPixelId, { em, fn, ln, ct, zp, country }) (valeurs en clair ; le pixel les hache).

Umami

Avec enableUmamiTracking et le script Umami sur la page :

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 })

Seul purchase porte revenue. Les champs vides sont omis. Umami ne dépose aucun cookie ; c’est à vous de décider si vous demandez le consentement.

Pixel OpenAI Ads

Avec enableOpenAiTracking et le pixel OpenAI (oaiq) sur la page :

oaiq('measure', 'order_created', {
  type: 'contents',
  amount: 5950,                     // unités mineures (centimes), net
  currency: 'EUR',
  contents: [{ id: 'a1b2c3', name: 'SUP Board', content_type: 'product', quantity: 2 }]
}, { event_id: 'purchase_SNLDX1' })

Vous pouvez aussi laisser l’option désactivée et appeler oaiq vous-même dans onCheckoutSuccess.

Callbacks

Les erreurs levées dans un callback sont interceptées et consignées dans la console, afin de ne pas bloquer la réservation.

onAddToCart({ productId, quantity, currency, name })

productId est l’ID de l’article, quantity la quantité ajoutée.

onInitiateCheckout({ transactionTotal, transactionId })

transactionTotal est le montant à payer (brut, cautions comprises), et non la valeur nette du panier qu’utilisent les autres événements. transactionId est la référence de commande.

onCheckoutSuccess({ ecommerceData, fbqData, eventID, price })
  • ecommerceData.purchase : l’objet purchase du dataLayer (transaction_id, currency, value, tax, items).
  • fbqData : les paramètres du Purchase Meta (sans order_id).
  • eventID : purchase_ + référence de commande.
  • price : ancien objet { gross, net, vat } en centimes, cautions comprises. Utilisez plutôt ecommerceData.

Exemple avec un pixel personnalisé :

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

  1. Ajoutez le snippet avec enableDataLayer: true, soit dans la page, soit comme balise GTM HTML personnalisé (Custom HTML) avec le déclencheur Initialisation – Toutes les pages (Initialization – All Pages).
  2. Créez des déclencheurs Événement personnalisé (Custom Event) pour add_to_cart, begin_checkout, add_shipping_info et purchase.
  3. Créez des Variables de couche de données (Data Layer Variables, version 2), par exemple ecommerce.value, ecommerce.currency, ecommerce.transaction_id, ecommerce.items.
  4. Balises d’événement GA4 : nom d’événement {{Event}} ou un nom fixe, et « Envoyer des données d’e-commerce » avec la source de données « Couche de données ».
  5. Purchase Meta via GTM : définissez l’ID d’événement sur purchase_{{DLV - ecommerce.transaction_id}}. Il correspond alors au Purchase côté serveur, et Meta déduplique les deux.

Si vous utilisez aussi le suivi côté serveur via Rentware pour la même propriété GA4, n’y envoyez pas en plus les événements du dataLayer : GA4 ne déduplique que purchase (par transaction_id), donc l’ajout au panier et les autres événements du tunnel seraient comptés deux fois.

Consentement

Le widget lit le consentement pour ce qu’il envoie au serveur Rentware (qui décide de ce qui part vers GA4, Google Ads et Meta). Il ne conditionne pas vos propres balises.

  • Il lit Google Consent Mode v2 depuis window.dataLayer : les entrées gtag('consent', 'default' | 'update', {…}) et les objets de style GTM comme { event: 'consent_update', ad_storage: 'granted', … }. Il les rejoue dans l’ordre : un update ultérieur remplace les valeurs précédentes.
  • Signaux : ad_storage, analytics_storage, ad_user_data, ad_personalization. Chacun vaut denied par défaut.
  • Si la page ne contient aucune entrée Consent Mode, la requête est marquée « aucun signal de consentement » et le journal de suivi affiche skipped: no consent signal.
  • Les entrées default propres à une région (avec region) ne peuvent pas être rapprochées de la localisation du visiteur dans le navigateur : seules leurs valeurs denied sont appliquées.
  • Le consentement tardif fonctionne : le consentement est relu à chaque requête. Un visiteur qui accepte après le chargement du widget est couvert dès la requête suivante, à condition que votre bannière pousse un update Consent Mode dans window.dataLayer.
  • Le widget ne lit que le dataLayer nommé dataLayer dans la même fenêtre. Un dataLayer renommé, ou un widget dans une iframe, signifie qu’il n’y a aucun signal de consentement.

Pour vérifier une page : acceptez la bannière, ouvrez la console et tapez dataLayer. Une entrée consent (ou un événement consent_update) doit être présente avant que le visiteur réserve.

Identifiants de clic

  • Le widget capture gclid, gbraid et wbraid depuis l’URL (gclid également depuis le paramètre d’association _gl de Google ou le cookie _gcl_aw) et fbclid depuis l’URL ou le cookie _fbc de Meta. L’URL l’emporte sur le cookie.
  • La capture n’a lieu qu’avec le consentement ad_storage. Rien n’est lu dans les cookies ni enregistré avant cela. Si le consentement arrive plus tard alors que l’identifiant de clic est encore dans l’URL, il est capturé à ce moment-là.
  • Les identifiants de clic sont conservés dans sessionStorage pour l’onglet (même onglet, même domaine, supprimés à la fermeture de l’onglet). Le premier clic l’emporte.
  • Le widget les envoie avec ses requêtes au serveur Rentware, qui les utilise pour Google Ads et Meta. Ils ne sont pas ajoutés à vos événements navigateur.
  • La page d’atterrissage et la page de réservation sont différentes ? Exécutez aussi le script du widget sur la page d’atterrissage, ou laissez votre balise Google (avec url_passthrough) ou votre pixel Meta écrire le cookie _gcl_aw / _fbc. gbraid et wbraid n’ont pas de solution de repli par cookie.

Liste de contrôle pour les tests

  1. Ajoutez RTR_HOOKS, ouvrez la page, acceptez la bannière.
  2. Ajoutez un article au panier, puis tapez dataLayer dans la console : les dernières entrées sont { ecommerce: null } et { event: 'add_to_cart', … }.
  3. Finalisez une réservation avec « réserver » ou un prépaiement et vérifiez l’entrée purchase ; son transaction_id est la référence de commande.
  4. Annulez ensuite la réservation de test dans Rentware.