# Webhooks

> Um POST no seu servidor a cada verificação genuína, assinado com HMAC.

## Configurar

Os webhooks configuram-se no [painel](https://api.payapp.ferreirakorp.com/painel). O PayApp faz um
`POST` no seu servidor a cada verificação genuína.

## Cabeçalhos

```bash
x-payapp-timestamp: 1786060400
x-payapp-signature: v1=<hex>
```

## Corpo

```json
{
  "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`):

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

---
Fonte: https://payapp-ao.com/docs/webhooks
