Majoritatea echipelor tratează un pașaport digital al produsului ca pe o pagină: îl creezi, tipărești codul QR și îl uiți. Astfel rămâne neexploatat cel mai util semnal. De fiecare dată când cineva scanează codul QR de pe un produs, aceasta este un eveniment — o persoană reală, dintr-o țară reală, ținând în mână o unitate reală, într-un moment real. Conectează aceste evenimente la stack-ul tău și pașaportul încetează să fie o pagină statică și devine front-end-ul unui pipeline de automatizare. Acest ghid arată cum să te abonezi la qr.scanned, cum să verifici fiecare payload și cum să transformi scanările și actualizările în fluxuri de lucru reale cu SDK-ul qr3.
De ce un DPP este o sursă de evenimente, nu o pagină statică
Valoarea unui pașaport nu este pagina pe care un consumator o vede o singură dată. Este fluxul de interacțiuni din jurul lui: scanări pe teren, modificări de date din ERP-ul tău, tranziții ale ciclului de viață. Fiecare dintre acestea este ceva la care sistemele tale pot reacționa în timp real.
Webhook-urile inversează modelul obișnuit de polling. În loc să întrebi „s-a întâmplat ceva?" la intervale regulate, qr3 te apelează pe tine în momentul în care se întâmplă. Tipurile de evenimente pe care le emite platforma includ qr.scanned, plus qr.created, qr.updated și qr.deleted pentru modificările ciclului de viață. Cel pe care majoritatea echipelor îl subutilizează este qr.scanned: se declanșează atunci când un consumator, un tehnician sau un agent vamal scanează efectiv un produs în lumea reală.
Un payload qr.scanned transportă contextul de care ai nevoie pentru a acționa — inclusiv țara scanării și dpp/code id-ul care identifică ce unitate a fost scanată. Acest lucru este suficient pentru a alimenta analiza, reaprovizionarea și logica de rechemare fără implicarea unui om.
Abonarea la qr.scanned
Îndreaptă un endpoint de webhook către serviciul tău și gestionează evenimentul. SDK-ul qr3 include un verificator, astfel încât să nu parsezi manual corpurile brute:
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);
});
Handler-ul este deliberat subțire: verifică, ramifică pe event.type, confirmă rapid cu un 200. Fă munca grea (scrieri de analiză, apeluri ERP) asincron, astfel încât un downstream lent să nu blocheze niciodată confirmarea.
Verificarea semnăturilor (verifyWebhook, HMAC-SHA256) — fă asta întotdeauna
Un endpoint de webhook este o adresă URL publică. Oricine îl găsește poate face POST către el. Dacă ai încredere în corp fără să verifici cine l-a trimis, un atacator poate falsifica „scanări", poate declanșa recomenzi false sau poate emite semnalări false de rechemare. Verifică întotdeauna semnătura înainte de a acționa pe baza unui payload.
qr3 semnează fiecare webhook cu HMAC-SHA256 peste corpul cererii, folosind secretul endpoint-ului tău. Semnătura ajunge în header-ul cererii qr3-signature. verifyWebhook(body, signature, secret) recalculează HMAC-ul și îl compară; dacă nu se potrivește, aruncă o eroare și respingi cererea:
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);
}
});
Trei reguli care păstrează lucrurile corecte:
- Verifică pe baza octeților bruți. Reserializarea JSON poate reordona cheile și schimba spațierea, ceea ce strică HMAC-ul. Capturează corpul brut (mai sus,
express.raw). - Păstrează secretul secret. Stă în mediul tău, niciodată în codul clientului sau într-un repo.
- Eșuează închis (fail closed). Nicio semnătură validă →
401, niciun efect secundar. Niciodată „procesează oricum" la o nepotrivire.
Tipare: analiză / recomandă / rechemare
Odată ce ai încredere în eveniment, câteva tipare acoperă majoritatea a ceea ce își doresc echipele:
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);
}
- Analiză: agregă scanările pe țară și unitate pentru a vedea implicarea din lumea reală — care piețe scanează efectiv și ce SKU-uri văd cea mai multă interacțiune post-vânzare.
- Recomandă / reaprovizionare: o serie intensă de scanări într-o regiune poate alimenta semnale de cerere sau poate declanșa fluxuri de lucru de reaprovizionare în ERP-ul tău.
- Rechemare / siguranță: dacă o unitate face obiectul unei rechemări, o scanare este o ocazie de a ajunge la oricine o deține — alertează-ți echipa sau afișează un anunț chiar pe pașaport.
Niciuna dintre acestea nu necesită polling sau un batch nocturn. Se întâmplă în clipa în care produsul este scanat.
Menținerea datelor actualizate prin client.dpp.update
Reacția la scanări este jumătate din buclă; cealaltă jumătate este menținerea pașaportului în sine corect. Reglementări precum ESPR (EU 2024/1781) și Regulamentul privind bateriile (EU 2023/1542) așteaptă ca datele pașaportului să reflecte realitatea pe parcursul vieții produsului — amprenta de carbon recalculată, instrucțiunile de reparație actualizate, țintele de conținut reciclat atinse.
Conduce aceste actualizări din sistemul de evidență. Când o valoare se schimbă în ERP-ul tău, împinge-o către pașaport:
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 },
});
Deoarece codul QR codifică o adresă URL stabilă de resolver (https://qr3.app/dpp/{gtin}/{serial}, adaugă ?format=jsonld pentru JSON-LD), nu retipărești niciodată o etichetă pentru a schimba datele. Identitatea rămâne fixă; conținutul din spatele ei rămâne actualizat. Combină asta cu qr.updated și poți distribui o notificare ori de câte ori un pașaport se schimbă — închizând bucla dintre ERP-ul tău, pașaport și oricine urmărește în aval.
Un tabel de evenimente: eveniment → ce să automatizezi
| Eveniment | Se declanșează când | Ce să automatizezi |
|---|---|---|
qr.scanned |
Un cod QR al unui produs este scanat pe teren | Analiză pe țară, semnale de reaprovizionare, alerte de rechemare |
qr.created |
Se creează un pașaport nou | Indexează-l, sincronizează-l cu PIM/ERP, anunță echipa de catalog |
qr.updated |
Datele pașaportului se schimbă | Recache-uiește pagina publică, distribuie notificări de modificare |
qr.deleted |
Un pașaport este eliminat | Marchează (tombstone) înregistrările interne, revocă referințele din aval |
Începe cu qr.scanned pentru implicare și semnale de teren; adaugă evenimentele de ciclu de viață pe măsură ce sincronizezi pașapoartele în sistemele tale mai largi.
Întrebări frecvente
Trebuie să verific semnătura dacă adresa URL a endpoint-ului meu este secretă?
Da. O adresă URL nu este un secret — se scurge în log-uri, proxy-uri și istoricul browserului. Verificarea HMAC cu verifyWebhook este singurul lucru care dovedește că un payload a venit cu adevărat de la qr3.
Ce se întâmplă dacă endpoint-ul meu este inactiv când se declanșează un eveniment?
Confirmă rapid cu 200 odată ce ai verificat și fă munca lentă asincron, astfel încât problemele tranzitorii din aval să nu blocheze niciodată răspunsul. Păstrează-ți propria idempotență pe dpp/code id, astfel încât o livrare reîncercată să nu fie numărată de două ori.
Pot actualiza GTIN sau seria prin client.dpp.update? Nu — GTIN-ul și seria sunt imutabile; ele reprezintă identitatea stabilă a produsului. Doar câmpurile de date pot fi actualizate. Această imutabilitate este exact ceea ce permite codului QR tipărit să rămână valid pentru totdeauna.
Surse
Începe gratuit și conectează primul tău webhook DPP: app.qr3.app/sign-up