Automatisera digitala produktpass med webhooks

Ett digitalt produktpass är inte en statisk sida — varje skanning är en händelse du kan bygga vidare på. Reagera på qr.scanned för analys, ombeställningar och återkallelseflaggor, håll passdata aktuella från ditt affärssystem och verifiera varje payload med HMAC-SHA256. En guide på utvecklarnivå med kod.

av QR3 Redaktion

Automatisera digitala produktpass med webhooks

De flesta team behandlar ett digitalt produktpass som en sida: du skapar det, skriver ut QR-koden och glömmer bort det. Det lämnar den mest användbara signalen outnyttjad. Varje gång någon skannar QR-koden på en produkt är det en händelse — en verklig person, i ett verkligt land, som håller en verklig enhet, i ett verkligt ögonblick. Koppla in dessa händelser i din stack så slutar passet vara en statisk sida och blir i stället frontend för en automatiseringspipeline. Den här guiden visar hur du prenumererar på qr.scanned, verifierar varje payload och förvandlar skanningar och uppdateringar till verkliga arbetsflöden med qr3-SDK:t.

Varför ett DPP är en händelsekälla, inte en statisk sida

Värdet i ett pass är inte den sida en konsument ser en enda gång. Det är strömmen av interaktioner runt det: skanningar i fält, dataändringar från ditt affärssystem, livscykelövergångar. Var och en är något dina system kan reagera på i realtid.

Webhooks vänder upp och ner på den vanliga polling-modellen. I stället för att fråga "har något hänt?" med jämna mellanrum anropar qr3 dig i samma ögonblick som det sker. De händelsetyper plattformen sänder ut inkluderar qr.scanned, plus qr.created, qr.updated och qr.deleted för livscykeländringar. Den som de flesta team underutnyttjar är qr.scanned: den utlöses när en konsument, tekniker eller tulltjänsteman faktiskt skannar en produkt ute i verkligheten.

En qr.scanned-payload bär med sig den kontext du behöver för att agera — inklusive landet för skanningen och det dpp/code id som identifierar vilken enhet som skannades. Det räcker för att driva analys, påfyllning och återkallelselogik utan en människa i loopen.

Prenumerera på qr.scanned

Peka en webhook-endpoint mot din tjänst och hantera händelsen. qr3-SDK:t levereras med en verifierare så att du inte behöver tolka råa bodyn för hand:

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

Hanteraren är medvetet tunn: verifiera, förgrena på event.type, kvittera snabbt med en 200. Gör det tunga arbetet (analysskrivningar, anrop till affärssystemet) asynkront så att en långsam nedströmstjänst aldrig blockerar kvitteringen.

Verifiera signaturer (verifyWebhook, HMAC-SHA256) — gör alltid detta

En webhook-endpoint är en publik URL. Vem som helst som hittar den kan göra en POST mot den. Om du litar på bodyn utan att kontrollera vem som skickade den kan en angripare förfalska "skanningar", utlösa falska ombeställningar eller avfyra falska återkallelseflaggor. Verifiera alltid signaturen innan du agerar på en payload.

qr3 signerar varje webhook med HMAC-SHA256 över request-bodyn, med din endpoint-hemlighet. Signaturen kommer i request-headern qr3-signature. verifyWebhook(body, signature, secret) räknar om HMAC:en och jämför den; om den inte stämmer kastar den ett fel och du avvisar requesten:

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

Tre regler som håller detta ärligt:

  • Verifiera mot de råa bytena. Att serialisera om JSON kan ändra ordningen på nycklar och förändra blankstegen, vilket bryter HMAC:en. Fånga den råa bodyn (ovan, express.raw).
  • Håll hemligheten hemlig. Den lever i din miljö, aldrig i klientkod eller ett repo.
  • Fall stängt. Ingen giltig signatur → 401, inga sidoeffekter. "Bearbeta ändå" vid en avvikelse är aldrig ett alternativ.

Mönster: analys / ombeställning / återkallelse

När du väl litar på händelsen täcker en handfull mönster det mesta av vad team vill ha:

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);
}
  • Analys: aggregera skanningar per land och enhet för att se verkligt engagemang — vilka marknader som faktiskt skannar, och vilka SKU:er som ser mest interaktion efter försäljning.
  • Ombeställning / påfyllning: en topp av skanningar i en region kan mata efterfrågesignaler eller utlösa påfyllningsflöden i ditt affärssystem.
  • Återkallelse / säkerhet: om en enhet är under återkallelse är en skanning en chans att nå den som håller i den — varna ditt team, eller visa ett meddelande på själva passet.

Inget av detta kräver polling eller en nattlig batch. De sker i samma ögonblick som produkten skannas.

Håll data aktuell via client.dpp.update

Att reagera på skanningar är halva loopen; den andra halvan är att hålla själva passet korrekt. Regelverk som ESPR (EU 2024/1781) och batteriförordningen (EU 2023/1542) förväntar sig att passdata speglar verkligheten under produktens livstid — omräknat koldioxidavtryck, uppdaterade reparationsinstruktioner, uppnådda mål för återvunnet innehåll.

Driv dessa uppdateringar från det system som är källan till sanningen. När ett värde ändras i ditt affärssystem, skicka det till passet:

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

Eftersom QR-koden kodar en stabil resolver-URL (https://qr3.app/dpp/{gtin}/{serial}, lägg till ?format=jsonld för JSON-LD) behöver du aldrig skriva ut en etikett på nytt för att ändra data. Identiteten förblir fast; innehållet bakom den förblir aktuellt. Kombinera detta med qr.updated så kan du sprida ut en avisering varje gång ett pass ändras — vilket sluter loopen mellan ditt affärssystem, passet och alla som bevakar nedströms.

En händelsetabell: händelse → vad du ska automatisera

Händelse Utlöses när Vad du ska automatisera
qr.scanned En produkt-QR skannas i fält Analys per land, påfyllningssignaler, återkallelsevarningar
qr.created Ett nytt pass skapas Indexera det, synka till PIM/affärssystem, meddela katalogteamet
qr.updated Passdata ändras Cacha om den publika sidan, sprid ut ändringsaviseringar
qr.deleted Ett pass tas bort Markera interna poster som borttagna, återkalla nedströmsreferenser

Börja med qr.scanned för engagemang och fältsignaler; lägg till livscykelhändelserna allt eftersom du synkar pass in i dina bredare system.

FAQ

Måste jag verifiera signaturen om min endpoint-URL är hemlig? Ja. En URL är inte en hemlighet — den läcker i loggar, proxyservrar och webbläsarhistorik. HMAC-verifiering med verifyWebhook är det enda som bevisar att en payload faktiskt kom från qr3.

Vad händer om min endpoint är nere när en händelse utlöses? Kvittera snabbt med 200 så snart du har verifierat, och gör långsamt arbete asynkront så att tillfälliga nedströmsproblem aldrig stoppar svaret. Behåll din egen idempotens på dpp/code id så att en omförsökt leverans inte räknas dubbelt.

Kan jag uppdatera GTIN eller serienummer via client.dpp.update? Nej — GTIN och serienummer är oföränderliga; de är produktens stabila identitet. Endast datafälten är uppdaterbara. Just den oföränderligheten är vad som låter den utskrivna QR-koden förbli giltig för alltid.

Källor

Börja gratis och koppla in din första DPP-webhook: app.qr3.app/sign-up

Relaterade inlägg