Onde vive cada segredo

CLIENT_SECRET e WEBHOOK_SECRET nunca podem aparecer no código do frontend nem no bundle enviado ao browser. Só a PUBLISHABLE_KEY é pública.

Verificação do webhook (HMAC SHA-256)

A FaciPay assina cada webhook. O header x-facipay-content-token contém o HMAC SHA-256 do body cru calculado com o seu WEBHOOK_SECRET. A ordem dos passos é crítica.
1

Leia o body CRU antes de qualquer parser JSON

Se fizer JSON.parse primeiro, o HMAC não vai bater certo.
2

Calcule o HMAC e compare em tempo constante

Use crypto.timingSafeEqual. Se os tamanhos diferirem, devolva 401 antes de comparar.
3

Só agora faça JSON.parse e processe

Localize a ordem por externalTransactionId e deduplique por paymentId + paymentStatus. Responda 200 em < 5s.
Nomes de headers HTTP são case-insensitive. Em Node, req.headers['x-facipay-content-token'] funciona porque o runtime normaliza tudo para minúsculas.

Por framework

// app/api/facipay/webhook/route.ts
import crypto from 'node:crypto';

export async function POST(req: Request) {
  const raw = await req.text(); // body cru
  const token = req.headers.get('x-facipay-content-token') ?? '';
  const expected = crypto
    .createHmac('sha256', process.env.FACIPAY_WEBHOOK_SECRET!)
    .update(raw)
    .digest('hex');

  const a = Buffer.from(token);
  const b = Buffer.from(expected);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
    return new Response('invalid signature', { status: 401 });
  }

  const payload = JSON.parse(raw);
  // ... idempotência + atualização de estado
  return Response.json({ received: true });
}

Outras boas práticas

  • Valide a origem do popup. Ao ouvir postMessage, confirme event.origin contra o domínio oficial do checkout antes de confiar na mensagem (ver Eventos).
  • Recalcule o total no servidor. Nunca aceite o amount vindo do cliente.
  • Trate o webhook como idempotente. Reprocessar não pode duplicar fulfillment.
  • HTTPS em produção. Obrigatório para a SDK e para receber webhooks.

Próximo passo: Go-live

Checklist para passar de sandbox a produção.