Assinaturas
Como conferir que a entrega veio de nós — em Node, Python e PHP.
Qualquer pessoa pode fazer um POST no seu endpoint. A assinatura é o que distingue uma entrega da Amivu de um pedido inventado — e conferi-la não é opcional.
Como a assinatura é feita
A Amivu calcula um HMAC-SHA-256 sobre <timestamp>.<corpo>, usando o segredo do seu endpoint, e manda o resultado no cabeçalho:
X-Amivu-Signature: t=1756240000,v1=5257a869e7ecebeda32affa62cdca3fa...
t— o instante da assinatura, em segundos.v1— o esquema. Um dia haveráv2ao lado, e quem conferev1continuará funcionando durante a transição.
Como conferir
JSON.parse. É o erro que mais aparece nesta etapa.import crypto from "node:crypto";
const TOLERANCIA_EM_SEGUNDOS = 300;
export function assinaturaValida(cabecalho, corpoBruto, segredo) {
// 1. separe o timestamp da assinatura
const partes = Object.fromEntries(
cabecalho.split(",").map((parte) => parte.trim().split("=", 2)),
);
const timestamp = Number.parseInt(partes.t, 10);
if (!Number.isFinite(timestamp) || !partes.v1) return false;
// 2. recuse o que é velho demais — é isto que impede repetição
const agora = Math.floor(Date.now() / 1000);
if (Math.abs(agora - timestamp) > TOLERANCIA_EM_SEGUNDOS) return false;
// 3. refaça a conta com o corpo BRUTO
const esperado = crypto
.createHmac("sha256", segredo)
.update(`${timestamp}.${corpoBruto}`, "utf8")
.digest();
const recebido = Buffer.from(partes.v1, "hex");
if (recebido.length !== esperado.length) return false;
// 4. compare em tempo constante
return crypto.timingSafeEqual(recebido, esperado);
}Como pegar o corpo bruto varia por framework. No Express, use express.raw({ type: "application/json" }) na rota do webhook — o express.json() global já teria consumido e reserializado o corpo.
O timestamp mata a repetição
Assinar só o corpo deixaria uma entrega capturada válida para sempre: bastaria reenviá-la. Com o timestamp dentro da conta, a cópia continua com assinatura correta e instante velho — e a janela de cinco minutos a recusa.
Rotacionar o segredo
No painel, em Desenvolvedores → Webhooks, o botão Rotacionar gera outro segredo. A entrega seguinte já assina com o novo — sem janela de convivência.
É deliberado: um segredo com dois valores válidos ao mesmo tempo continua valendo depois de ter sido rotacionado, que é o oposto do motivo de rotacionar. Atualize os dois lados no mesmo minuto, e prefira fazê-lo em horário de baixo movimento.
Continue em Reentregas.
Escrevemos sobre operação de atendimento, canais e IA no blog da Amivu.