Du prompt à l'achat : à quoi ressemble un parcours d'achat IA dans vos analytics

Un achat via ChatGPT laisse une chaîne de traces : ligne de flux, clic avec oppref ou référent, pixel et serveur au même identifiant, commande attribuée.

Publié le 14 min de lecture

Un parcours d’achat né dans un assistant IA écrit une chaîne d’enregistrements dans vos systèmes : une ligne de flux qui a rendu le produit recommandable, une URL de destination portant oppref ou un référent ChatGPT, des événements pixel (page_viewed, contents_viewed, items_added, checkout_started, order_created) doublés d’un unique order_created côté serveur avec le même identifiant d’événement, et une commande attribuée avec sa preuve. Cassez un maillon et la commande a toujours lieu, mais vos analytics ne peuvent plus l’expliquer.

Un acheteur hypothétique, étape par étape

Tout ce qui suit accompagne un seul acheteur inventé. Appelons cette personne Sam. Sam n’est pas une personne réelle, la boutique n’est pas une boutique réelle, et aucun des chiffres n’est une mesure ; ils sont choisis pour rendre les enregistrements lisibles. L’objectif est de suivre ce que chaque étape écrit dans vos données, parce que c’est la seule partie du parcours que vous verrez jamais.

Sam cherche une veste de pluie compressible pour aller travailler à vélo et demande à ChatGPT un modèle dont la capuche passe par-dessus un casque. Ce qui se passe ensuite dépend de choses que vous contrôlez des semaines plus tôt.

Étape 0 : le produit doit exister dans le flux

Avant que Sam ne tape quoi que ce soit, votre catalogue a déjà été livré à OpenAI sous forme d’instantané complet par SFTP, au moins une fois par jour, en parquet ou en jsonl.gz. La vue d’ensemble du dépôt de fichiers demande des « full snapshots on a predictable cadence (at least daily) » sous un nom de fichier stable, écrasé à chaque exécution.

Pour que la veste soit candidate, sa ligne doit être valide. La spécification exige neuf champs : item_id, title, description, url, brand, seller_name, image_url, availability et price. Une ligne pour la veste de Sam, en JSON Lines, pourrait ressembler à ceci :

{
  "item_id": "JKT-RAIN-M-OLIVE",
  "group_id": "JKT-RAIN",
  "title": "Packable cycling rain jacket, olive, size M",
  "description": "Waterproof 2.5-layer shell with a helmet-compatible hood, underarm vents and a stuff sack. Weight 210 g.",
  "url": "https://shop.example.com/products/rain-jacket?variant=olive-m&utm_source=chatgpt&utm_medium=feed",
  "brand": "Example Outdoor",
  "seller_name": "Example Outdoor Store",
  "image_url": "https://cdn.example.com/jkt-rain-olive-m.jpg",
  "availability": "in_stock",
  "price": "129.00 EUR",
  "variant_dict": { "color": "olive", "size": "M" },
  "is_eligible_search": true,
  "is_ads_eligible": true,
  "target_countries": ["FR", "BE"]
}

Deux détails de cette ligne compteront plus tard. Les paramètres utm_source et utm_medium dans url suivent la page de bonnes pratiques, qui suggère d’ajouter des « feed attribution parameters to url (for example utm_medium=feed) when you need feed-specific click tracking ». Et is_ads_eligible est renseigné explicitement, parce qu’une valeur omise signifie « disabled unless a feed-level Ads default applies ».

Ce que cela écrit dans vos données : une entrée dans le journal d’exécution du flux. Chez Convrail, ce sont itemsTotal, itemsValid, itemsRejected, le différentiel par rapport à l’exécution précédente et un statut de livraison. Si la ligne de la veste avait échoué à la validation (un prix écrit 129,00, une image en .webp), elle apparaîtrait comme une entrée d’erreur avec le champ et la règle, et Sam ne verrait jamais la veste. La spécification ne documente aucun rapport d’erreur par ligne du côté d’OpenAI, donc ce journal est le seul endroit où le rejet serait visible.

Ce qui casse la chaîne ici : une ligne rejetée, ou un produit absent d’un instantané. La vue d’ensemble indique qu’un enregistrement manquant persiste « for up to 14 days », donc un export cassé passe inaperçu pendant deux semaines, puis le produit disparaît.

Étape 1 : le prompt et la fiche produit

ChatGPT répond à Sam par une courte liste de vestes, chacune sous forme de fiche produit construite à partir des données du flux : titre, image, prix, vendeur. Votre veste en fait partie, soit comme résultat organique, soit comme publicité. De votre côté, rien n’est écrit à cette étape : aucun événement d’impression dans vos analytics, aucun journal de requêtes que vous pourriez lire. Ce que vous pouvez savoir, c’est si le produit était éligible : is_eligible_search valait true (la valeur par défaut quand il est omis, et la spécification ajoute qu’« Eligibility does not guarantee display »), et is_ads_eligible valait true si la fiche était une publicité. La page de bonnes pratiques décrit le texte qui aide ici : « Use concise, factual copy that helps users understand products. »

Ce que cela écrit dans vos données : rien directement. Si la fiche est une publicité, l’impression est comptée du côté d’OpenAI et apparaît plus tard dans les statistiques de l’Advertiser API que Convrail importe une fois par jour (impressions, clics, dépense, CTR, CPC, CPM, conversions).

Étape 2 : le clic, et l’identifiant qu’il transporte

Sam clique sur la fiche. Cette étape existe en deux versions, et elles laissent des empreintes différentes.

Clic publicitaire. L’URL de destination porte un paramètre oppref. La référence de la Conversions API le décrit comme « An opaque, OpenAI-provided attribution identifier. Pass the original string without modification. » La documentation du pixel explique ce qui se passe à l’atterrissage : le pixel « captures oppref from the landing page URL » et « stores oppref in a first-party __oppref cookie so later page views can reuse it ». Le pixel de Convrail conserve ce cookie 7 jours.

Clic organique. Pas d’oppref. L’URL de destination porte ce que vous avez mis dans le champ url du flux, ici utm_source=chatgpt&utm_medium=feed, et le navigateur peut envoyer un référent chatgpt.com. « Peut » est le mot important : les référents sont supprimés par certains navigateurs, certains réglages de confidentialité et certaines redirections.

L’URL de destination du clic publicitaire de Sam ressemble donc à :

https://shop.example.com/products/rain-jacket?variant=olive-m&utm_source=chatgpt&utm_medium=feed&oppref=<opaque-id>

Ce que cela écrit dans vos données : une session avec une URL de destination et, côté plateforme, ce que votre boutique enregistre de la page d’atterrissage et du référent de la visite. C’est cet enregistrement que l’attribution lira à la fin.

Ce qui casse la chaîne ici : toute redirection entre le clic et la page où le pixel se charge qui perd les paramètres de requête : une redirection géographique qui reconstruit l’URL, un saut de www vers le domaine nu qui oublie la chaîne de requête, un sélecteur de devise qui recharge sans paramètres. oppref a disparu avant que le pixel ne le voie, et le clic se dégrade en organique ou en non attribué à la fin du parcours.

Étape 3 : page_viewed et contents_viewed

La page produit se charge avec le script du pixel OAIQ depuis https://bzrcdn.openai.com/sdk/oaiq.min.js, initialisé avec votre identifiant de pixel. Deux événements se déclenchent : page_viewed pour la page elle-même, et contents_viewed pour le produit consulté. Convrail fait correspondre les événements Shopify product_viewed et collection_viewed à contents_viewed, et search_submitted à page_viewed.

Un appel contents_viewed transporte ce qui a été vu :

oaiq("measure", "contents_viewed", {
  type: "contents",
  amount: 12900,
  currency: "EUR",
  contents: [{ id: "JKT-RAIN-M-OLIVE", group_id: "JKT-RAIN", quantity: 1, amount: 12900, currency: "EUR" }]
}, { event_id: "cv_<session>_JKT-RAIN-M-OLIVE" });

Notez le montant : 12900, pas 129.00. La référence est explicite : data.amount est « an integer in the currency’s standard minor unit. For example, use 4200 for $42.00 ». L’id du contenu correspond à l’item_id du flux, et c’est ainsi que l’événement est relié à la fiche produit sur laquelle Sam a cliqué.

Ce que cela écrit dans vos données : un événement navigateur avec un horodatage, un identifiant d’événement, l’identifiant de pixel, l’oppref lu dans le cookie et les identifiants de contenu. Convrail relaie une copie de chaque événement pixel vers son propre stockage avec le même identifiant d’événement, pour que vous ayez votre propre enregistrement au lieu de dépendre de l’Ads Manager pour le décompte.

Ce qui casse la chaîne ici : le pixel qui ne se charge pas (changement de thème, politique de sécurité du contenu, bloqueur de scripts) ou un consentement refusé. La documentation du pixel indique qu’il « initializes consent to true by default unless you set it to false or the Pixel finds a stored denial », et qu’avec le consentement à false il « doesn’t send measurement-event pings ». Un refus est une fin légitime de la chaîne navigateur, et c’est pour cela que le chemin serveur de l’étape 6 existe.

Étape 4 : items_added

Sam choisit la taille M et ajoute la veste au panier. Le pixel déclenche items_added avec la même structure de contenu. Convrail y fait correspondre le product_added_to_cart de Shopify.

Ce que cela écrit dans vos données : un événement navigateur de plus dans la même session, portant toujours l’oppref du cookie alors que l’URL de la page panier ne le contient pas. C’est la valeur pratique du cookie first-party : l’identifiant suit la session sans figurer dans chaque URL.

Ce qui casse la chaîne ici : un panier hébergé sur un autre domaine, où le cookie posé sur le domaine produit n’est pas lisible. Les événements postérieurs au changement de domaine perdent oppref, sauf s’il est transmis délibérément.

Étape 5 : checkout_started

Sam passe au paiement. Le pixel déclenche checkout_started avec le total du panier. Sur Shopify, le tunnel de paiement tourne sur l’infrastructure de Shopify, et c’est une des raisons pour lesquelles Convrail installe le pixel via la Web Pixel API plutôt que dans le thème : un web pixel s’exécute aussi sur les pages de paiement, là où le code du thème ne va pas.

Ce que cela écrit dans vos données : le dernier événement navigateur avant la commande. Beaucoup de sessions avec checkout_started et sans order_created, c’est soit un abandon normal, soit un pixel cassé sur la page de remerciement ; l’étape 6 vous dit lequel.

Étape 6 : order_created, deux fois, compté une fois

Sam paie. Deux choses se produisent alors, délibérément en parallèle.

Dans le navigateur. La page de remerciement déclenche order_created via le pixel, avec le total de la commande en unités mineures et les lignes de commande en contents. Convrail y fait correspondre le checkout_completed de Shopify. L’identifiant d’événement est order_<orderId>.

Sur le serveur. Votre plateforme déclenche un webhook de commande (orders/paid sur Shopify, un hook de commande sur WooCommerce). Le serveur construit un événement Conversions API et l’envoie, groupé avec d’autres, vers POST https://bzr.openai.com/v1/events?pid=<PIXEL-ID> :

{
  "events": [
    {
      "id": "order_1001",
      "type": "order_created",
      "timestamp_ms": 1756720000000,
      "action_source": "web",
      "source_url": "https://shop.example.com/checkout/thank-you",
      "oppref": "<opaque-id>",
      "user": {
        "emails_sha256": ["<64-char lowercase hex>"],
        "countries": ["FR"]
      },
      "data": {
        "type": "contents",
        "amount": 12900,
        "currency": "EUR",
        "contents": [
          { "id": "JKT-RAIN-M-OLIVE", "group_id": "JKT-RAIN", "quantity": 1, "amount": 12900, "currency": "EUR" }
        ]
      }
    }
  ]
}

Trois contraintes de la référence façonnent cette charge utile. timestamp_ms « must be within the last 7 days and no more than 10 minutes in the future ». source_url est obligatoire pour les événements web et doit comporter un schéma et un hôte. Et l’email n’est pas un email : c’est un condensé SHA-256 de l’adresse nettoyée et mise en minuscules, sous forme de chaîne hexadécimale minuscule de 64 caractères. Convrail hashe les emails et les numéros de téléphone dès leur réception, ne les stocke jamais en clair, et fait tourner un garde-fou automatisé qui bloque toute charge utile sortante contenant des données personnelles en clair.

Pourquoi compté une fois. Le pixel a envoyé order_created avec event_id: "order_1001". Le serveur a envoyé order_created avec id: "order_1001", même identifiant de pixel. La référence indique que la déduplication porte sur « Pixel ID, event_name, and id » et qu’« OpenAI uses the first event it receives for a matching key and ignores later duplicates ». Si Sam avait bloqué le pixel, seul l’événement serveur existe et la commande est quand même comptée. Si le webhook a pris du retard, l’événement pixel est conservé et la copie serveur ignorée. Dans les deux cas, exactement une fois.

Ce que cela écrit dans vos données : deux enregistrements d’événement avec le même identifiant, l’un marqué navigateur et l’autre serveur, plus un enregistrement de lot pour l’envoi serveur (accepté, réessayé, ou placé en file des rebuts après la dernière tentative). La référence précise que « If one event in the batch fails, the full batch fails », donc un lot définitivement en échec signifie que la commande de Sam, et toutes les autres commandes de ce lot, ne sont pas dans l’Ads Manager.

Ce qui casse la chaîne ici : des identifiants d’événement différents des deux côtés (la commande compte deux fois), un lot refusé parce qu’un de ses événements était malformé (la commande compte zéro fois), ou un webhook qui ne s’est jamais déclenché.

Étape 7 : l’attribution

La commande existe dans votre boutique. La question est de savoir si vos analytics peuvent dire d’où Sam venait. Convrail applique une table de décision fixe à l’URL de destination et au référent tels qu’enregistrés par votre plateforme, la première règle qui correspond l’emporte :

Preuve sur la commandeVerdict
L’URL de destination contient oppref=<id>ChatGPT, publicité
utm_source vaut chatgpt, openai ou chatgpt.com et utm_medium vaut cpc, ppc, paid ou adsChatGPT, publicité
Même utm_source, tout autre mediumChatGPT, organique
Le référent est chatgpt.com, chat.openai.com ou openai.com (ou un sous-domaine)ChatGPT, organique
Aucun des cas ci-dessusnon attribuée

Pour le clic publicitaire de Sam, la première ligne correspond : publicité, preuve oppref. Pour la version organique du même parcours, la troisième ligne correspond sur utm_source=chatgpt&utm_medium=feed : organique, preuve UTM. Si les paramètres avaient été supprimés et que le référent avait survécu, la quatrième ligne le rattrape. Si tout a été supprimé, la commande est « non attribuée », et Convrail enregistre cela plutôt que de deviner.

Ce que cela écrit dans vos données : un enregistrement d’attribution sur la commande avec le medium (publicité ou organique), la méthode (la règle qui a correspondu) et la preuve (la valeur du paramètre ou du référent). C’est la colonne que vous rapprochez de l’Ads Manager, qui attribue de son propre côté : les conversions post-clic utilisent « the applicable configured click window », les conversions post-impression « a fixed one-day window after an eligible ad impression ».

Étape 8 : le tableau de bord

La commande de Sam apparaît maintenant dans le chiffre d’affaires attribué du jour, sous publicité ou organique. Si l’Advertiser API est connectée, dépense, clics et impressions sont importés une fois par jour par campagne, et le ROAS est calculé comme le chiffre d’affaires publicitaire attribué divisé par la dépense importée. La veste contribue à la liste des meilleurs produits, construite à partir des lignes des commandes attribuées. La commande peut être exportée en CSV avec sa colonne de preuve.

Si un maillon de la chaîne avait cassé, les moniteurs de santé le diraient : zéro événement navigateur en 24 heures alors que des événements serveur arrivent (pixel cassé), un lot en échec définitif dans la dernière heure (erreurs Conversions API), une exécution de flux non livrée en 24 heures, ou une chute de volume sous 30 % de la référence sur 7 jours. Le guide d’audit passe chacun de ces contrôles en revue à la main.

Le même achat dans un parcours de recherche classique

Mettez le parcours de Sam à côté de celui que vous connaissez déjà.

ÉtapeParcours de recherche classiqueParcours ChatGPT
DécouverteSam tape des mots-clés ; une page de résultats liste des liens et des annonces shoppingSam décrit un besoin en une phrase ; la réponse contient des fiches produit construites à partir de votre flux
Votre apportDes pages indexées, et un flux Google Shopping pour les annoncesUn flux produit validé contre la spécification OpenAI, livré en instantané quotidien
Visibilité des impressionsLa console de recherche et les rapports publicitaires montrent requêtes et impressionsAucun journal de requêtes de votre côté ; les impressions publicitaires viennent de l’Advertiser API, les impressions organiques ne sont pas exposées
Identifiant de clicgclid ou équivalent sur les clics payants ; référent sur l’organiqueoppref sur les clics payants ; vos propres UTM et le référent chatgpt.com sur l’organique
Événements sur le siteBalise d’analyse et pixel de conversionÉvénements du pixel OAIQ plus un événement serveur Conversions API, dédupliqués sur un même identifiant d’événement
AttributionCôté plateforme et dans vos analytics, sur identifiants de clic et référentsAds Manager sur oppref et fenêtres de clic ; de votre côté sur oppref, UTM, référent

La différence structurelle est en haut. Dans un parcours de recherche, la requête vous est visible et le lien est une page que vous avez écrite. Dans un parcours ChatGPT, la requête est une conversation que vous ne voyez pas, et la « page » est une fiche assemblée à partir de votre ligne de flux. Le flux fait le travail que la page indexée faisait auparavant, et c’est pourquoi une ligne rejetée n’est pas une note de bas de page technique mais un produit qui n’existe pas pour cet acheteur. Tout ce qui suit le clic est familier : un identifiant sur l’URL, un pixel, un événement serveur, une règle d’attribution. Les noms sont nouveaux ; la discipline (un seul identifiant d’événement, des identifiants hashés, la preuve stockée avec la commande) est la même que celle qui fait fonctionner le suivi côté serveur sur les autres canaux.

Erreurs fréquentes

Laisser une redirection avaler oppref. L’identifiant est sur l’URL de destination une seule fois. Si le premier saut le perd, le pixel ne le stocke jamais et le clic publicitaire finit étiqueté organique ou non attribué.

Envoyer 129.00 comme montant. Unités mineures, toujours : 12900 pour 129,00 EUR.

Générer l’identifiant d’événement au hasard sur le pixel. Le serveur ne peut pas reproduire un identifiant aléatoire. Dérivez-le de la commande (order_<orderId>) des deux côtés.

Lire « non attribuée » comme « pas ChatGPT ». Cela signifie qu’aucune preuve n’a survécu. Un acheteur qui a interrogé ChatGPT puis tapé votre URL à la main est invisible pour ces règles, comme pour toute autre méthode d’attribution.

Que faire ensuite

Lisez les règles d’attribution et leurs limites avec vos trente dernières commandes sous les yeux, et vérifiez sur quelle ligne de la table de décision chacune tomberait.

Sources

Questions fréquentes

Comment une visite venue de ChatGPT apparaît-elle dans mes analytics ?

Comme une session dont l'URL de destination porte un paramètre oppref (publicité), un utm_source tel que chatgpt (si vous avez balisé vos URL), ou un référent chatgpt.com (organique). Sans l'un de ces trois éléments, la visite ressemble à du trafic direct.

Qu'est-ce qu'oppref ?

L'identifiant de clic que ChatGPT Ads ajoute à l'URL de destination. La référence OpenAI le décrit comme un identifiant d'attribution opaque fourni par OpenAI ; le pixel le stocke dans un cookie first-party __oppref et l'attache aux événements suivants pour que la commande puisse être rapprochée du clic publicitaire.

Pourquoi ai-je besoin du pixel et de la Conversions API pour une même commande ?

Ils échouent de façons différentes. Le pixel rate les acheteurs qui bloquent les scripts ou partent avant la page de remerciement ; l'appel serveur ne rate rien de la commande mais ne sait rien du navigateur. Partager un même identifiant d'événement permet à OpenAI de garder le premier et d'écarter le doublon.

L'attribution peut-elle voir un acheteur qui a interrogé ChatGPT puis tapé mon URL à la main ?

Non. L'attribution travaille à partir des preuves first-party présentes sur la commande : identifiant de clic, paramètres UTM, référent. Une visite sans aucune de ces preuves est enregistrée comme non attribuée, et Convrail l'étiquette ainsi plutôt que de deviner.

Mesurez le canal ChatGPT dès cette semaine

Gratuit pendant l'accès anticipé, le temps d'intégrer les premières boutiques. Laissez votre email et vous recevez le lien d'installation dès qu'une place s'ouvre.

Pas de newsletter. Un seul email avec le lien d'installation, rien d'autre.