Webhooks
Um POST no seu servidor a cada verificação genuína, assinado com HMAC.
Configurar
Os webhooks configuram-se no painel. O PayApp faz um
POST no seu servidor a cada verificação genuína.
Cabeçalhos
x-payapp-timestamp: 1786060400
x-payapp-signature: v1=<hex>Corpo
{
"evento": "comprovativo.verificado",
"autentico": true,
"valor": 45000,
"txn": "0912847361",
"nome": "Ana Miguel",
"em": "2026-08-07T09:14:22.000Z"
}Validar a assinatura
A assinatura é HMAC-SHA256(segredo_do_webhook, timestamp + "." + corpo_cru).
Valide sempre
confirme a assinatura antes de confiar no conteúdo e rejeite timestamps com mais de 5 minutos. É isso que impede alguém de forjar um aviso de pagamento.
Exemplo em Node.js, a partir da fórmula acima (use o corpo cru, antes de qualquer JSON.parse):
import crypto from "node:crypto";
export function avisoValido(segredo, cabecalhos, corpoCru) {
const ts = cabecalhos["x-payapp-timestamp"];
const recebida = cabecalhos["x-payapp-signature"] ?? "";
// rejeita avisos com mais de 5 minutos
if (!ts || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const esperada = "v1=" + crypto
.createHmac("sha256", segredo)
.update(`${ts}.${corpoCru}`)
.digest("hex");
// comparação em tempo constante
return recebida.length === esperada.length &&
crypto.timingSafeEqual(Buffer.from(recebida), Buffer.from(esperada));
}