Automatizar Passaportes Digitais de Produto com Webhooks

Um Passaporte Digital de Produto não é uma página estática — cada leitura é um evento sobre o qual pode construir. Reaja a qr.scanned para análises, reposições e sinalização de recolhas, mantenha os dados do passaporte atualizados a partir do seu ERP e verifique cada payload com HMAC-SHA256. Um guia de nível profissional para programadores, com código.

por QR3 Redaktion

Automatizar Passaportes Digitais de Produto com Webhooks

A maioria das equipas trata um Passaporte Digital de Produto como uma página: criam-no, imprimem o código QR e esquecem-no. Isso deixa o sinal mais útil por aproveitar. Sempre que alguém faz a leitura do código QR num produto, isso é um evento — uma pessoa real, num país real, com uma unidade real nas mãos, num momento real. Ligue esses eventos à sua stack e o passaporte deixa de ser uma página estática para se tornar o front end de uma pipeline de automação. Este guia mostra como subscrever qr.scanned, verificar cada payload e transformar leituras e atualizações em fluxos de trabalho reais com o SDK da qr3.

Porque é que um DPP é uma fonte de eventos, e não uma página estática

O valor de um passaporte não está na página que um consumidor vê uma vez. Está no fluxo de interações à sua volta: leituras no terreno, alterações de dados a partir do seu ERP, transições de ciclo de vida. Cada uma é algo a que os seus sistemas podem reagir em tempo real.

Os webhooks invertem o habitual modelo de polling. Em vez de perguntar "aconteceu alguma coisa?" num temporizador, a qr3 chama-o a si no momento em que algo acontece. Os tipos de evento que a plataforma emite incluem qr.scanned, além de qr.created, qr.updated e qr.deleted para as alterações de ciclo de vida. O que a maioria das equipas subaproveita é qr.scanned: dispara quando um consumidor, técnico ou funcionário alfandegário faz efetivamente a leitura de um produto no mundo real.

Um payload qr.scanned transporta o contexto de que precisa para agir — incluindo o país da leitura e o dpp/code id que identifica qual a unidade lida. Isso é suficiente para impulsionar análises, reabastecimento e lógica de recolha sem intervenção humana.

Subscrever qr.scanned

Aponte um endpoint de webhook para o seu serviço e trate o evento. O SDK da qr3 inclui um verificador para que não tenha de analisar corpos de pedido em bruto manualmente:

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

O handler é deliberadamente leve: verificar, ramificar com base em event.type, confirmar rapidamente com um 200. Faça o trabalho pesado (escritas de análises, chamadas ao ERP) de forma assíncrona, para que um sistema a jusante lento nunca bloqueie a confirmação.

Verificar assinaturas (verifyWebhook, HMAC-SHA256) — faça sempre isto

Um endpoint de webhook é um URL público. Qualquer pessoa que o encontre pode fazer-lhe POST. Se confiar no corpo do pedido sem verificar quem o enviou, um atacante pode forjar "leituras", desencadear reposições falsas ou disparar sinalizações de recolha falsas. Verifique sempre a assinatura antes de agir sobre um payload.

A qr3 assina cada webhook com HMAC-SHA256 sobre o corpo do pedido, usando o segredo do seu endpoint. A assinatura chega no cabeçalho de pedido qr3-signature. verifyWebhook(body, signature, secret) recalcula o HMAC e compara-o; se não corresponder, lança uma exceção e você rejeita o pedido:

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

Três regras que mantêm isto honesto:

  • Verifique contra os bytes em bruto. Voltar a serializar o JSON pode reordenar chaves e alterar espaços em branco, o que quebra o HMAC. Capture o corpo em bruto (acima, express.raw).
  • Mantenha o segredo secreto. Vive no seu ambiente, nunca no código do cliente nem num repositório.
  • Falhe de forma segura. Sem assinatura válida → 401, sem efeitos secundários. Nunca "processe na mesma" perante uma não correspondência.

Padrões: análises / reposição / recolha

Assim que confia no evento, um punhado de padrões cobre a maior parte do que as equipas querem:

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);
}
  • Análises: agregue as leituras por país e por unidade para ver o envolvimento no mundo real — que mercados fazem efetivamente leituras e que SKUs registam mais interação pós-venda.
  • Reposição / reabastecimento: um pico de leituras numa região pode alimentar sinais de procura ou desencadear fluxos de trabalho de reabastecimento no seu ERP.
  • Recolha / segurança: se uma unidade estiver sujeita a recolha, uma leitura é uma oportunidade de chegar a quem a tem nas mãos — alerte a sua equipa ou mostre um aviso no próprio passaporte.

Nenhum destes precisa de polling nem de um lote noturno. Acontecem no instante em que o produto é lido.

Manter os dados atualizados via client.dpp.update

Reagir às leituras é metade do ciclo; a outra metade é manter o próprio passaporte rigoroso. Regulamentos como o ESPR (UE 2024/1781) e o Regulamento das Baterias (UE 2023/1542) esperam que os dados do passaporte reflitam a realidade ao longo da vida do produto — pegada de carbono recalculada, instruções de reparação atualizadas, metas de conteúdo reciclado atingidas.

Impulsione essas atualizações a partir do sistema de registo. Quando um valor muda no seu ERP, envie-o para o passaporte:

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

Como o código QR codifica um URL de resolução estável (https://qr3.app/dpp/{gtin}/{serial}, adicione ?format=jsonld para JSON-LD), nunca volta a imprimir uma etiqueta para alterar dados. A identidade mantém-se fixa; o conteúdo por trás dela mantém-se atualizado. Combine isto com qr.updated e pode disparar uma notificação sempre que um passaporte muda — fechando o ciclo entre o seu ERP, o passaporte e quem quer que esteja a observar a jusante.

Uma tabela de eventos: evento → o que automatizar

Evento Dispara quando O que automatizar
qr.scanned É feita a leitura do QR de um produto no terreno Análises por país, sinais de reabastecimento, alertas de recolha
qr.created É criado um novo passaporte Indexá-lo, sincronizar com o PIM/ERP, notificar a equipa de catálogo
qr.updated Os dados do passaporte mudam Recriar a cache da página pública, disparar notificações de alteração
qr.deleted Um passaporte é removido Marcar registos internos como tombstone, revogar referências a jusante

Comece com qr.scanned para envolvimento e sinais de terreno; acrescente os eventos de ciclo de vida à medida que sincroniza os passaportes nos seus sistemas mais amplos.

FAQ

Tenho de verificar a assinatura se o URL do meu endpoint for secreto? Sim. Um URL não é um segredo — vaza em registos, proxies e no histórico do navegador. A verificação HMAC com verifyWebhook é a única coisa que prova que um payload veio efetivamente da qr3.

O que acontece se o meu endpoint estiver em baixo quando um evento dispara? Confirme rapidamente com 200 assim que tiver verificado e faça o trabalho lento de forma assíncrona, para que problemas transitórios a jusante nunca travem a resposta. Mantenha a sua própria idempotência sobre o dpp/code id, para que uma entrega repetida não seja contada duas vezes.

Posso atualizar o GTIN ou o número de série via client.dpp.update? Não — o GTIN e o número de série são imutáveis; são a identidade estável do produto. Apenas os campos de dados são atualizáveis. É precisamente essa imutabilidade que permite que o código QR impresso permaneça válido para sempre.

Fontes

Comece gratuitamente e ligue o seu primeiro webhook de DPP: app.qr3.app/sign-up

Artigos relacionados