Automatiser les passeports numériques de produits avec les Webhooks

Un passeport numérique de produit n'est pas une page statique — chaque scan est un événement sur lequel vous pouvez bâtir. Réagissez à qr.scanned pour l'analytique, le réapprovisionnement et les alertes de rappel, gardez les données du passeport à jour depuis votre ERP, et vérifiez chaque charge utile avec HMAC-SHA256. Un guide de niveau développeur, avec du code.

par QR3 Redaktion

Automatiser les passeports numériques de produits avec les Webhooks

La plupart des équipes considèrent un passeport numérique de produit comme une page : vous le créez, vous imprimez le QR code, puis vous l'oubliez. Cela laisse de côté le signal le plus utile. Chaque fois que quelqu'un scanne le QR code d'un produit, il s'agit d'un événement — une personne réelle, dans un pays réel, tenant une unité réelle, à un moment réel. Reliez ces événements à votre stack et le passeport cesse d'être une page statique pour devenir le point d'entrée d'un pipeline d'automatisation. Ce guide montre comment s'abonner à qr.scanned, vérifier chaque charge utile et transformer les scans et les mises à jour en véritables workflows grâce au SDK qr3.

Pourquoi un DPP est une source d'événements, et non une page statique

La valeur d'un passeport ne réside pas dans la page que le consommateur consulte une seule fois. Elle réside dans le flux d'interactions qui l'entourent : les scans sur le terrain, les changements de données issus de votre ERP, les transitions de cycle de vie. Chacun de ces éléments est quelque chose auquel vos systèmes peuvent réagir en temps réel.

Les Webhooks inversent le modèle de polling habituel. Au lieu de demander « s'est-il passé quelque chose ? » à intervalles réguliers, qr3 vous appelle dès que cela se produit. Les types d'événements émis par la plateforme incluent qr.scanned, ainsi que qr.created, qr.updated et qr.deleted pour les changements de cycle de vie. Celui que la plupart des équipes sous-exploitent est qr.scanned : il se déclenche lorsqu'un consommateur, un technicien ou un agent des douanes scanne réellement un produit sur le terrain.

Une charge utile qr.scanned transporte le contexte nécessaire pour agir — y compris le pays du scan et l'identifiant dpp/code qui indique quelle unité a été scannée. Cela suffit à piloter l'analytique, le réapprovisionnement et la logique de rappel sans intervention humaine.

S'abonner à qr.scanned

Faites pointer un point de terminaison de Webhook vers votre service et traitez l'événement. Le SDK qr3 fournit un vérificateur pour que vous n'ayez pas à analyser les corps bruts à la main :

import express from "express";
import { verifyWebhook } from "@qr3/sdk";

const app = express();
const secret = process.env.QR3_WEBHOOK_SECRET!;

// Use the raw body so the signature matches the exact bytes qr3 signed.
app.post("/webhooks/qr3", express.raw({ type: "application/json" }), (req, res) => {
  const event = verifyWebhook(req.body, req.headers["qr3-signature"], secret);

  if (event.type === "qr.scanned") {
    // event payload includes fields like the scan country and the dpp/code id
    handleScan(event);
  }

  res.sendStatus(200);
});

Le gestionnaire est volontairement minimaliste : vérifiez, branchez sur event.type, accusez réception rapidement avec un 200. Effectuez le gros du travail (écritures analytiques, appels à l'ERP) de manière asynchrone afin qu'un service en aval lent ne bloque jamais l'accusé de réception.

Vérifier les signatures (verifyWebhook, HMAC-SHA256) — faites-le toujours

Un point de terminaison de Webhook est une URL publique. Quiconque la trouve peut y envoyer une requête POST. Si vous faites confiance au corps sans vérifier qui l'a envoyé, un attaquant peut falsifier des « scans », déclencher de faux réapprovisionnements ou émettre de fausses alertes de rappel. Vérifiez toujours la signature avant d'agir sur une charge utile.

qr3 signe chaque Webhook avec HMAC-SHA256 sur le corps de la requête, en utilisant votre secret de point de terminaison. La signature arrive dans l'en-tête de requête qr3-signature. verifyWebhook(body, signature, secret) recalcule le HMAC et le compare ; si la correspondance échoue, il lève une exception et vous rejetez la requête :

import { verifyWebhook } from "@qr3/sdk";

app.post("/webhooks/qr3", express.raw({ type: "application/json" }), (req, res) => {
  try {
    const event = verifyWebhook(req.body, req.headers["qr3-signature"], secret);
    process(event);
    res.sendStatus(200);
  } catch {
    // signature mismatch → not from qr3 (or body was altered in transit)
    res.sendStatus(401);
  }
});

Trois règles pour garder ce mécanisme fiable :

  • Vérifiez sur les octets bruts. Re-sérialiser le JSON peut réordonner les clés et modifier les espaces, ce qui casse le HMAC. Capturez le corps brut (ci-dessus, express.raw).
  • Gardez le secret secret. Il vit dans votre environnement, jamais dans le code client ni dans un dépôt.
  • Échouez en mode fermé. Pas de signature valide → 401, aucun effet de bord. Ne « traitez jamais quand même » en cas de non-correspondance.

Modèles : analytique / réapprovisionnement / rappel

Une fois que vous faites confiance à l'événement, une poignée de modèles couvrent l'essentiel de ce que veulent les équipes :

function handleScan(event: { type: string; data: { country?: string; dpp_id?: string } }) {
  // 1) Analytics — where and how often are products scanned?
  metrics.increment("dpp.scan", { country: event.data.country });

  // 2) Re-order — a scan can signal consumption or field activity
  if (event.data.country) maybeReplenish(event.data.dpp_id, event.data.country);

  // 3) Recall flag — scans of a flagged unit alert your team
  if (isRecalled(event.data.dpp_id)) alertRecall(event.data.dpp_id, event.data.country);
}
  • Analytique : agrégez les scans par pays et par unité pour observer l'engagement réel — quels marchés scannent effectivement, et quelles références (SKU) connaissent le plus d'interactions après la vente.
  • Réapprovisionnement : une vague de scans dans une région peut alimenter des signaux de demande ou déclencher des workflows de réassort dans votre ERP.
  • Rappel / sécurité : si une unité fait l'objet d'un rappel, un scan est l'occasion d'atteindre la personne qui la détient — alertez votre équipe, ou affichez un avis sur le passeport lui-même.

Aucun de ces cas ne nécessite de polling ni de traitement par lot nocturne. Ils se produisent à l'instant même où le produit est scanné.

Garder les données à jour via client.dpp.update

Réagir aux scans n'est que la moitié de la boucle ; l'autre moitié consiste à maintenir le passeport lui-même exact. Des réglementations telles que l'ESPR (UE 2024/1781) et le règlement sur les batteries (UE 2023/1542) exigent que les données du passeport reflètent la réalité tout au long de la vie du produit — empreinte carbone recalculée, instructions de réparation mises à jour, objectifs de contenu recyclé atteints.

Pilotez ces mises à jour depuis le système de référence. Lorsqu'une valeur change dans votre ERP, poussez-la vers le passeport :

import { QR3 } from "@qr3/sdk";

const client = new QR3({ apiKey: process.env.QR3_API_KEY! });

// GTIN and serial are immutable; data fields are updatable.
await client.dpp.update(dppId, {
  battery_data: { carbon_footprint_kg: 58, recycled_content_pct: 16 },
});

Comme le QR code encode une URL de résolveur stable (https://qr3.app/dpp/{gtin}/{serial}, ajoutez ?format=jsonld pour du JSON-LD), vous n'avez jamais à réimprimer une étiquette pour modifier les données. L'identité reste fixe ; le contenu qui se trouve derrière reste à jour. Associez cela à qr.updated et vous pourrez diffuser une notification chaque fois qu'un passeport change — bouclant la boucle entre votre ERP, le passeport et toute personne qui observe en aval.

Un tableau des événements : événement → quoi automatiser

Événement Se déclenche quand Quoi automatiser
qr.scanned Un QR code produit est scanné sur le terrain Analytique par pays, signaux de réapprovisionnement, alertes de rappel
qr.created Un nouveau passeport est créé L'indexer, le synchroniser avec le PIM/ERP, notifier l'équipe catalogue
qr.updated Les données du passeport changent Remettre en cache la page publique, diffuser des notifications de changement
qr.deleted Un passeport est supprimé Marquer les enregistrements internes comme supprimés, révoquer les références en aval

Commencez par qr.scanned pour l'engagement et les signaux de terrain ; ajoutez les événements de cycle de vie au fur et à mesure que vous synchronisez les passeports dans vos systèmes plus larges.

FAQ

Dois-je vérifier la signature si l'URL de mon point de terminaison est secrète ? Oui. Une URL n'est pas un secret — elle fuite dans les journaux, les proxys et l'historique du navigateur. La vérification HMAC avec verifyWebhook est la seule chose qui prouve qu'une charge utile provient réellement de qr3.

Que se passe-t-il si mon point de terminaison est hors service au moment où un événement se déclenche ? Accusez réception rapidement avec un 200 une fois la vérification effectuée, et effectuez les tâches lentes de manière asynchrone afin que des problèmes transitoires en aval ne bloquent jamais la réponse. Conservez votre propre idempotence sur l'identifiant dpp/code afin qu'une livraison réessayée ne soit pas comptée deux fois.

Puis-je mettre à jour le GTIN ou le numéro de série via client.dpp.update ? Non — le GTIN et le numéro de série sont immuables ; ils constituent l'identité stable du produit. Seuls les champs de données sont modifiables. C'est précisément cette immuabilité qui permet au QR code imprimé de rester valide indéfiniment.

Sources

Commencez gratuitement et connectez votre premier Webhook DPP : app.qr3.app/sign-up

Articles liés