La maggior parte dei team tratta un Passaporto Digitale di Prodotto come una pagina: lo crei, stampi il codice QR e te ne dimentichi. Così facendo, lasci inutilizzato il segnale più prezioso. Ogni volta che qualcuno scansiona il codice QR su un prodotto, quella è un evento: una persona reale, in un paese reale, che tiene in mano un'unità reale, in un momento reale. Collega quegli eventi al tuo stack e il passaporto smette di essere una pagina statica per diventare il front end di una pipeline di automazione. Questa guida mostra come iscriversi a qr.scanned, verificare ogni payload e trasformare scansioni e aggiornamenti in flussi di lavoro concreti con l'SDK di qr3.
Perché un DPP è una sorgente di eventi, non una pagina statica
Il valore di un passaporto non è la pagina che un consumatore vede una volta sola. È il flusso di interazioni che lo circonda: scansioni sul campo, modifiche ai dati dal tuo ERP, transizioni del ciclo di vita. Ognuna è qualcosa a cui i tuoi sistemi possono reagire in tempo reale.
I Webhook ribaltano il consueto modello di polling. Invece di chiedere "è successo qualcosa?" a intervalli regolari, qr3 chiama te nel momento esatto in cui accade. I tipi di evento che la piattaforma emette includono qr.scanned, oltre a qr.created, qr.updated e qr.deleted per le modifiche del ciclo di vita. Quello che la maggior parte dei team sfrutta meno è qr.scanned: si attiva quando un consumatore, un tecnico o un funzionario doganale scansiona davvero un prodotto sul campo.
Un payload qr.scanned trasporta il contesto di cui hai bisogno per agire, incluso il paese della scansione e l'id dpp/code che identifica quale unità è stata scansionata. È sufficiente per guidare l'analitica, il rifornimento e la logica di richiamo senza alcun intervento umano.
Iscriversi a qr.scanned
Indirizza un endpoint webhook verso il tuo servizio e gestisci l'evento. L'SDK di qr3 include un verificatore così non devi analizzare a mano i body grezzi:
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);
});
Il gestore è volutamente snello: verifica, ramifica su event.type, conferma rapidamente con un 200. Esegui il lavoro pesante (scritture analitiche, chiamate all'ERP) in modo asincrono, così un downstream lento non blocca mai la conferma.
Verificare le firme (verifyWebhook, HMAC-SHA256): fallo sempre
Un endpoint webhook è un URL pubblico. Chiunque lo trovi può inviargli una richiesta POST. Se ti fidi del body senza controllare chi l'ha inviato, un aggressore può falsificare "scansioni", innescare riordini fasulli o lanciare false segnalazioni di richiamo. Verifica sempre la firma prima di agire su un payload.
qr3 firma ogni webhook con HMAC-SHA256 sul body della richiesta, usando il tuo segreto di endpoint. La firma arriva nell'header di richiesta qr3-signature. verifyWebhook(body, signature, secret) ricalcola l'HMAC e lo confronta; se non corrisponde, solleva un'eccezione e tu rifiuti la richiesta:
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 regole che mantengono tutto onesto:
- Verifica sui byte grezzi. Riserializzare il JSON può riordinare le chiavi e cambiare gli spazi bianchi, il che rompe l'HMAC. Cattura il body grezzo (sopra,
express.raw). - Mantieni segreto il segreto. Vive nel tuo ambiente, mai nel codice client o in un repo.
- Fallisci in chiusura. Nessuna firma valida →
401, nessun effetto collaterale. Non "elaborare comunque" in caso di mancata corrispondenza.
Pattern: analitica / riordino / richiamo
Una volta che ti fidi dell'evento, una manciata di pattern copre la maggior parte di ciò che i team desiderano:
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);
}
- Analitica: aggrega le scansioni per paese e unità per vedere il coinvolgimento reale sul campo: quali mercati scansionano davvero e quali SKU registrano la maggiore interazione post-vendita.
- Riordino / rifornimento: un'impennata di scansioni in una regione può alimentare i segnali di domanda o innescare flussi di lavoro di riassortimento nel tuo ERP.
- Richiamo / sicurezza: se un'unità è soggetta a richiamo, una scansione è un'occasione per raggiungere chi la possiede: avvisa il tuo team o mostra un avviso sul passaporto stesso.
Nessuno di questi richiede polling o un batch notturno. Avvengono nell'istante in cui il prodotto viene scansionato.
Mantenere i dati aggiornati tramite client.dpp.update
Reagire alle scansioni è metà del ciclo; l'altra metà è mantenere accurato il passaporto stesso. Normative come l'ESPR (UE 2024/1781) e il Regolamento Batterie (UE 2023/1542) si aspettano che i dati del passaporto rispecchino la realtà lungo tutta la vita del prodotto: impronta di carbonio ricalcolata, istruzioni di riparazione aggiornate, obiettivi di contenuto riciclato raggiunti.
Guida questi aggiornamenti dal sistema di riferimento. Quando un valore cambia nel tuo ERP, invialo al passaporto:
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 },
});
Poiché il codice QR codifica un URL di risoluzione stabile (https://qr3.app/dpp/{gtin}/{serial}, aggiungi ?format=jsonld per il JSON-LD), non ristampi mai un'etichetta per cambiare i dati. L'identità resta fissa; il contenuto dietro di essa resta aggiornato. Abbina questo a qr.updated e potrai diramare una notifica ogni volta che un passaporto cambia, chiudendo il ciclo tra il tuo ERP, il passaporto e chiunque osservi a valle.
Una tabella degli eventi: evento → cosa automatizzare
| Evento | Si attiva quando | Cosa automatizzare |
|---|---|---|
qr.scanned |
Un codice QR di prodotto viene scansionato sul campo | Analitica per paese, segnali di rifornimento, avvisi di richiamo |
qr.created |
Viene creato un nuovo passaporto | Indicizzalo, sincronizza con PIM/ERP, avvisa il team catalogo |
qr.updated |
I dati del passaporto cambiano | Rimetti in cache la pagina pubblica, dirama notifiche di modifica |
qr.deleted |
Un passaporto viene rimosso | Marca come eliminati i record interni, revoca i riferimenti a valle |
Inizia con qr.scanned per il coinvolgimento e i segnali dal campo; aggiungi gli eventi del ciclo di vita man mano che sincronizzi i passaporti nei tuoi sistemi più ampi.
FAQ
Devo verificare la firma se l'URL del mio endpoint è segreto?
Sì. Un URL non è un segreto: trapela nei log, nei proxy e nella cronologia del browser. La verifica HMAC con verifyWebhook è l'unica cosa che dimostra che un payload provenga davvero da qr3.
Cosa succede se il mio endpoint è inattivo quando si attiva un evento?
Conferma rapidamente con 200 una volta verificato, ed esegui il lavoro lento in modo asincrono, così i problemi transitori a valle non bloccano mai la risposta. Mantieni la tua idempotenza sull'id dpp/code, così una consegna ritentata non viene conteggiata due volte.
Posso aggiornare GTIN o serial tramite client.dpp.update? No: GTIN e serial sono immutabili; sono l'identità stabile del prodotto. Solo i campi dati sono aggiornabili. È proprio questa immutabilità a permettere al codice QR stampato di rimanere valido per sempre.
Fonti
Inizia gratis e collega il tuo primo webhook DPP: app.qr3.app/sign-up