Skip to Content
Pilotage à la marge

Piloter vos campagnes d’acquisition à la marge en Server-Side

Pourquoi piloter à la marge (et non au chiffre d’affaires)

Aujourd’hui, les algorithmes publicitaires sont de plus en plus performants, à condition de leur fournir les bonnes données. Mais c’est surtout la hausse des coûts publicitaires (CPC, CPM en augmentation constante) qui pousse les annonceurs à accorder une attention accrue à la rentabilité de leurs campagnes.

Il devient donc indispensable d’adopter une approche plus rationnelle et orientée performance, en repensant les indicateurs utilisés pour piloter vos investissements média.

Traditionnellement, les campagnes d’acquisition sont optimisées à partir de KPIs comme le chiffre d’affaires (CA) ou le ROAS (Return On Ad Spend). Mais cette approche peut être trompeuse, car elle ne prend pas en compte les coûts réels : production, logistique, retours, etc.

La marge (ou le profit) est un indicateur bien plus pertinent pour évaluer la véritable performance économique d’une campagne.

ROAS vs POAS : quelles différences ?

  • ROAS (Return On Ad Spend) = chiffre d’affaires / dépenses publicitaires
  • POAS (Profit On Ad Spend) = profit / dépenses publicitaires

Prenons un exemple simple. Imaginons que vous ayez investi le même montant en publicité Google Ads pour deux produits distincts. Google Ads vous indique que chaque publicité a généré une conversion, dont voici les résultats :

Piloter à la marge et non au chiffre d'affaires

En se basant uniquement sur le ROAS, Google favoriserait le produit A, car il génère plus de chiffre d’affaires. Mais c’est le produit B qui est en réalité le plus rentable !

En pilotant avec le POAS, vous placez la rentabilité réelle au centre de votre stratégie. Cela permet d’optimiser vos campagnes sur la base de votre marge, indépendamment du chiffre d’affaires généré.

Quels résultats peut-on attendre ?

Notre client Maisons du Monde a mis en place une stratégie de pilotage à la marge pour ses campagnes Google Ads. L’impact post-implémentation est significatif :

  • +5,7 % de part du chiffre d’affaires générée par les produits à forte marge
  • +12 % de volume d’affaires global sur les campagnes

👉 Découvrez le cas client complet ici : Maisons du Monde x Addingwell

2 solutions pour mettre en place le pilotage à la marge en Server-Side

Attention, l’envoi de la marge côté client (dans le dataLayer) est fortement déconseillé, car ces informations sont sensibles et pourraient être exposées (notamment à vos concurrents).

Le Server-Side permet justement de contourner cette limite, en enrichissant les données sans jamais exposer la marge côté navigateur.

Il existe aujourd’hui deux solutions pour mettre en place un pilotage à la marge en Server-Side. Le choix dépendra principalement de votre architecture technique, du volume de produits et du niveau de complexité que vous souhaitez gérer.

Solution 1 : DataLayer enrichi avec chiffrement des données

Cette approche consiste à envoyer la marge chiffrée depuis le client, puis à la déchiffrer côté Server-Side. Le chiffrement AES permet de protéger des données commerciales sensibles (comme la marge) en les rendant illisibles dans le navigateur. Les données voyagent chiffrées dans le dataLayer et sont déchiffrées uniquement côté sGTM, grâce à une clé secrète partagée. La donnée étant chiffrée, elle est ainsi inutilisable si elle est interceptée côté client.

Datalayer enrichi avec marge encryptée

Impact sur les coûts : chaque appel au déchiffrement côté Server-Side correspond à 1 requête. Le coût dépend donc directement du nombre d’événements envoyés (ex. : nombre de purchase). Cette solution est relativement simple à mettre en place, mais nécessite l’intervention de vos développeurs front-end.

Étape 1 : Générer la clé et l’IV

La clé de chiffrement et l’IV doivent être générés une seule fois. Utilisez le module crypto intégré à Node.js pour les obtenir :

const crypto = require('crypto'); // ENC_KEY : exactement 32 caractères console.log(crypto.randomBytes(16).toString('hex')); // IV : exactement 16 caractères console.log(crypto.randomBytes(8).toString('hex'));

Conservez les valeurs générées en variable d’environnement, par exemple :

# .env.local ENC_KEY=d8e24ac9aa9eb3981007cc2b8fb185c4 IV=12cf31ecd57909fc

Étape 2 : Créer le module de chiffrement

Créez le fichier lib/encrypt.js dans votre projet. Ce fichier s’exécute exclusivement côté serveur.

// lib/encrypt.js 'use strict'; const crypto = require('crypto'); const ENC_KEY = process.env.ENC_KEY; // 32 caractères const IV = process.env.IV; // 16 caractères function encryptValue(val) { let cipher = crypto.createCipheriv('aes-256-cbc', ENC_KEY, IV); let encrypted = cipher.update(String(val), 'utf8', 'base64'); encrypted += cipher.final('base64'); return encrypted; } module.exports = { encryptValue };

Étape 3 : Chiffrer et pousser dans le dataLayer

Sur les pages où vous souhaitez envoyer la marge (ex. : page de confirmation de paiement), utilisez la fonction encryptValue précédemment créée pour chiffrer la marge côté serveur.

La valeur chiffrée est transmise en prop au composant client qui gère le push dataLayer. La marge en clair ne doit jamais quitter le serveur.

Exemple :

// pages/confirmation.jsx import { encryptValue } from '../lib/encrypt'; import PurchaseTracker from '../components/PurchaseTracker'; export async function getServerSideProps() { const order = { transaction_id: 'T-98765', value: 149.90, margin: 42.50, // jamais transmis au client en clair currency: 'EUR', items: [{ item_id: 'SKU-001', item_name: 'Produit A', price: 149.90, quantity: 1 }], }; const margin = encryptValue(order.margin); return { props: { order: { transaction_id: order.transaction_id, value: order.value, // en clair currency: order.currency, items: order.items, margin, // chiffrée }, }, }; } export default function ConfirmationPage({ order }) { return <PurchaseTracker order={order} />; }
// components/PurchaseTracker.jsx import { useEffect } from 'react'; export default function PurchaseTracker({ order }) { useEffect(() => { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ ecommerce: null }); // reset GA4 window.dataLayer.push({ event: 'purchase', ecommerce: { transaction_id: order.transaction_id, value: order.value, currency: order.currency, items: order.items, margin: order.margin, // base64 }, }); }, []); return null; }

Étape 4 : Configurer la variable sGTM

Dans votre conteneur sGTM, créez une nouvelle variable en utilisant le template personnalisé Decrypt AES. Récupérez d’abord cette variable ici en cliquant sur l’icône de téléchargement.

Télécharger template decrypte AES Addingwell sur Github

Depuis votre GTM Server, cliquez sur le menu Templates à gauche, puis sur New dans la rubrique « Variable templates ».

Importer template variable decrypt AES Server Side

Cliquez ensuite sur les trois points en haut à droite et sélectionnez Import.

Importer template variable decrypt AES Server Side

Sélectionnez le fichier template.tpl précédemment téléchargé, puis cliquez sur Save.

Fermez cette fenêtre et cliquez sur l’onglet Variables dans le menu de gauche, puis sur New dans l’onglet User-defined variables.

Creer la variable decrypt AES Server Side

Cliquez dans Variable Configuration et choisissez le modèle Decrypt AES by Addingwell.

Choisir le template de variable decrypt AES Server Side by Addingwell

Il ne vous reste plus qu’à mapper les trois paramètres de la façon suivante :

Setup de la variable decrypt AES Server Side by Addingwell
Paramètre du templateVariable sGTM à associer
1. To be decryptedVariable « Event Data » → margin (dynamique)
2. IVVariable « Constant » : votre IV
3. KeyVariable « Constant » : votre ENC_KEY

Attention : la clé et l’IV doivent correspondre exactement aux valeurs de votre .env.local. Un seul caractère de différence entraîne un retour silencieux de null lors du déchiffrement.

Nommez votre variable net_revenue_value et cliquez sur “Save”.

Étape 5 : Tester le déchiffrement

Avant de passer en production, vérifiez que la chaîne complète fonctionne via le mode preview de sGTM.

Assurez-vous en amont que l’événement GA4 côté GTM pousse bien le paramètre de marge (margin dans notre exemple) au Server-Side. Le cas échéant, ajoutez ce paramètre dans le tag d’événement purchase.

  1. Ouvrir le mode preview sGTM. Dans votre conteneur GTM Server, cliquez sur Preview et connectez votre onglet navigateur.
Preview pour vérifier le fonctionnement de la variable decrypt AES Server Side by Addingwell
  1. Déclencher un événement avec la marge chiffrée. Pour cela, accédez au site sur un nouvel onglet et exécutez un push manuel dans la console de développement.

Faites un clic droit sur votre site, puis cliquez sur Inspecter et ouvrez la console de développement.

Renseignez un push dataLayer comme ci-dessous, avec dans le paramètre margin votre marge précédemment chiffrée :

window.dataLayer = window.dataLayer || []; window.dataLayer.push({ ecommerce: null }); window.dataLayer.push({ event: 'purchase', ecommerce: { transaction_id: 'T-98765', value: 149.90, currency: 'EUR', margin: '7iMDN/iKeb1CcaQchL39KQ==', items: [{ item_id: 'SKU-001', item_name: 'Produit A', price: 149.90, quantity: 1 }], }, });
  1. Vérifier la valeur dans sGTM. Dans le panneau preview, sélectionnez l’événement purchase et consultez l’onglet Variables. La variable net_revenue_value doit retourner la marge en clair.
Verifier la marge déchifrée coté Server Side via la variable decrypt AES Server Side by Addingwell

Ici, dans notre exemple, nous avons bien la valeur déchiffrée côté sGTM : 42,50.

Vous pouvez ensuite utiliser cette donnée de marge déchiffrée dans vos tags (voir section Envoyer la marge aux plateformes média).

Solution 2 : Enrichissement via une base de données Firestore

Cette approche consiste à ne pas envoyer la marge depuis le client, mais à l’ajouter côté serveur via une base de données. Cette solution nécessite donc une gestion de base de données de votre côté.

Datalayer enrichi via un Firestore

Impact sur les coûts :

  • Lecture : ~0,1 requête par appel → dépend du nombre de produits (1 appel par produit)
  • Écriture : ~0,33 requête par mise à jour produit → ajout ou modification de marge.

Étape 1 : Créer et alimenter la base

Votre base de données Firestore peut être hébergée par Addingwell. Contactez notre équipe support via [email protected] pour en faire la demande.

La base doit contenir au minimum :

  • Une collection regroupant toutes vos données (produit et marge associée). Dans l’exemple ci-dessous, le nom de notre collection est products.
  • Une clé correspondant à chacun de vos item_id. Dans notre exemple, une clé est surlignée et a l’identifiant 1531847245879 : cela correspond à un item_id pour un article en vente sur notre site.
  • Une valeur de marge associée, ou un taux de marge associé à chaque produit. Dans notre exemple, nous renseignons la marge dans le champ que nous avons intitulé margin, et ce champ est associé à une valeur pour chaque item_id (valeur de marge de 6,5 pour l’article de notre exemple).
Exemple de fichier Firestore pour envoyer la marge vers votre GTM Server

Étape 2 : Synchroniser les données produits

  • Ajout des nouveaux produits
  • Mise à jour des marges existantes

Cette étape est essentielle pour garantir la qualité des données. Attention cependant à ne pas re-synchroniser l’intégralité de la base à chaque passage, mais uniquement les nouveaux produits ou les produits dont la marge a évolué. La fréquence de cette synchronisation est également à prévoir en amont, selon vos besoins.

Étape 3 : Récupérer la marge dans le Server GTM

  1. Téléchargez notre template dédié pour interroger votre base de données Firestore ici.
Template de variable Addingwell pour interroger Firestore sur la marge produits
  1. Importez ensuite ce template en cliquant sur l’onglet Templates de votre GTM serveur, puis, dans la section Variable templates, cliquez sur New
Importer le Template de variable Addingwell pour interroger Firestore sur la marge produits

Cliquez ensuite sur les trois petits points en haut à droite, puis sur Import. Choisissez le fichier template.tpl que vous avez précédemment téléchargé.

Importer le template de variable Addingwell pour Firestore sur la marge produits

Une fois le template chargé, cliquez sur Save et fermez cet onglet.

Enregistrer le template de variable Addingwell pour Firestore sur la marge produits
  1. Cliquez ensuite sur l’onglet Variables dans le menu de gauche, puis sur New dans l’onglet User-defined variables.
Enregistrer le template de variable Addingwell pour Firestore sur la marge produits

Sélectionnez ensuite le modèle de variable Firestore - Cart margin value by Addingwell.

Enregistrer le template de variable Addingwell pour Firestore sur la marge produits
  1. Paramétrez ensuite la variable.

Nommez la variable net_revenue_value. Puis paramétrez les 3 champs ci-dessous :

Paramétrer la variable de marge Firestore
ParamètreDescription
1. GCP Project IDRenseignez l’ID du projet fourni par Addingwell.
2. Data SourceChoisissez Other.
3. Firestore Collection IDRenseignez ici le nom de la collection Firestore qui contient vos données de produits. Dans notre exemple, le nom de la collection est products et correspond bien au nom que nous avions renseigné sur Firestore en étape 1.

Dans le menu Override default values, paramétrez les champs comme ci-dessous :

Récuperer les bons champs de votre DatalaYer pour la variable d emarge Firestore dans votre GTM Server
ParamètreDescription
1. CalculationChoisissez Value si vous souhaitez simplement envoyer la valeur de marge de votre fichier Firestore pour chaque item_id de votre panier. Vous enverrez ainsi : (margin x quantity) - discount. Si votre fichier Firestore ne contient pas l’info de marge en tant que valeur, mais un taux de marge, choisissez Return Rate. Vous enverrez ainsi : (price x return_rate x quantity) - discount.
2. ValueRenseignez ici le nom de la clé Firestore utilisée pour envoyer votre marge, ou bien la clé utilisée pour votre taux de marge. Dans notre exemple, nous utilisons la clé margin qui correspond à ce que nous avions renseigné sur notre Firestore en étape 1.
3. Item fieldsVous pouvez ici mapper les champs issus de votre dataLayer. Par défaut, les champs renseignés sont ceux de la nomenclature Google pour l’objet items, mais vous pouvez les adapter si besoin.
4. Fallback ValueDans le cas où votre fichier Firestore est vide pour un item_id donné, une valeur de marge sera appliquée par défaut. Vous pouvez ici renseigner votre taux de marge moyen.

Cliquez ensuite sur Save.

Une requête vers votre Firestore est effectuée pour chaque item_id de votre panier. Pour un panier multi-produits : une requête par produit sera donc effectuée.

  1. Vérifiez la valeur dans sGTM. Dans le panneau preview, sélectionnez l’événement purchase et consultez l’onglet Variables. La variable net_revenue_value doit retourner la marge correspondant au(x) article(s) de votre panier d’achat.
Verifier la marge coté Server Side via la variable Firestore margin by Addingwell

Ici, dans notre exemple, nous avons bien la valeur de marge du panier d’un montant de 42,50 dans la variable net_revenue_value.

Envoyer la marge aux plateformes média

Une fois la marge disponible côté Server-Side, vous pouvez l’exploiter dans vos tags média, et notamment dans :

  • Google Ads - conversion
  • Meta (Conversions API)

Vous pouvez ensuite choisir d’optimiser vos campagnes publicitaires en vous basant sur la rentabilité réelle, et non plus uniquement sur le chiffre d’affaires !

Envoi de la marge à Google Ads

Si vous souhaitez envoyer la marge à Google Ads, vous devez utiliser le paramètre value du tag Google Ads - conversion afin d’y transmettre votre marge, et non plus la valeur totale du panier. La valeur globale du panier ne sera donc plus envoyée à Google Ads, puisqu’elle sera remplacée par la valeur de marge.

Vous pouvez tout à fait envoyer à Google Ads à la fois la valeur totale d’achat et la valeur de marge. Il suffit de créer un second tag de conversion (par exemple “Google Ads - purchase margin”) en plus de votre tag existant “Google Ads - purchase”. Ce dernier reste inchangé et continue d’envoyer la valeur totale du panier. Le nouveau tag, déclenché sur le même événement purchase, enverra la valeur de marge.

Setup du tag

Nous allons nous concentrer ici uniquement sur l’envoi de la marge. Le setup du reste du tag est détaillé dans notre documentation dédiée.

Ajoutez simplement la variable net_revenue_value créée précédemment dans le champ Conversion Value.

Envoi de la marge à Google Ads via le champ Conversion Value

Cliquez sur “Save” et publiez cette version.

Envoi de la marge à Meta

Le template de tag Meta by Addingwell dispose d’un champ dédié pour envoyer la marge à Meta via CAPI, mais ne transfère pas cette information au pixel Meta, car la marge serait alors exposée côté navigateur. Voilà le schéma de ce flux de données :

Envoi de la marge à Meta CAPI coté Server Side via le template Addingwell

Assurez-vous d’avoir la dernière version de notre tag Meta CAPI by Addingwell, disponible ici. Cette version est la seule permettant d’ajouter directement depuis le tag l’envoi de la marge via le paramètre net_revenue.

Setup du tag

Nous allons nous concentrer ici uniquement sur l’envoi de la marge. Le setup du reste du tag est détaillé dans notre documentation dédiée.

Cliquez sur l’onglet dépliant Custom Data Override, puis ajoutez un champ net_revenue. Dans le champ Property value, cliquez sur l’icône d’ajout de variable + et choisissez la variable contenant votre valeur de marge (dans notre exemple, la variable net_revenue_value créée précédemment).

Envoi de la marge à Meta CAPI via le champ dédié net_revenue

Cliquez sur “Save” et publiez cette version.

Félicitations

Vous avez terminé la configuration de l’envoi de la valeur de marge à vos partenaires média.

Si vous avez rencontré le moindre problème durant ces étapes, n’hésitez pas à contacter notre équipe support