CONFIABILIDADE DE PAGAMENTOS

Webhook e idempotência em uma integração PIX ↔ stablecoin

O identificador impede duplicidade; o webhook reduz espera; a consulta reconcilia. Os três precisam existir juntos. Um timeout não prova que a criação falhou, um webhook pode se repetir e um evento pode chegar depois de uma consulta.
external_idHMAC SHA-256timestamp anti-replayretry controladoconsulta de status

A regra de ouro

1. gere external_id no seu banco
2. persista o pedido como "creating"
3. chame a Lunium com o mesmo external_id
4. em timeout, repita exatamente a mesma chamada
5. aceite webhook repetido sem repetir efeito
6. reconcilie por consulta quando houver dúvida

Consumidor de webhook

Leia o corpo bruto

A assinatura foi calculada sobre os bytes recebidos. Validar um JSON reserializado pode produzir outra sequência.

Valide timestamp e assinatura

Rejeite assinatura inválida e janela antiga. Compare o HMAC em tempo constante.

Persista por identificador do evento

Uma restrição única torna o consumo idempotente. Evento repetido deve responder sucesso sem aplicar o efeito outra vez.

Aplique transição válida

Não retroceda uma operação concluída porque um evento anterior chegou atrasado.

Responda 2xx depois do commit

Se a persistência falhar, responda erro para permitir nova entrega. Não confirme antes de salvar.

Pseudocódigo seguro

const raw = await request.rawBody()
verifyLuniumSignature(request.headers, raw)
const event = JSON.parse(raw)

await db.transaction(async tx => {
  if (await tx.events.exists(event.event_id)) return
  await tx.events.insert(event.event_id, event)
  await tx.orders.applyForwardTransition(event.data)
})

return response.status(204)

Como interpretar falhas

Timeout na criação

Repita com o mesmo external_id. Não crie um identificador novo.

Webhook repetido

Responda 2xx depois de confirmar que o evento já foi persistido.

Webhook atrasado

Valide a transição; não sobrescreva um estado terminal mais novo.

Webhook perdido

Use consulta de status e histórico de entregas para reconciliar.

Teste antes de produção

Configure uma URL HTTPS pública na chave e use POST /webhooks/test. Depois valide retry, assinatura errada, evento repetido e indisponibilidade temporária do seu endpoint.

Abrir quickstartVer contrato vivo

Quer revisar seu consumidor antes do primeiro PIX?

Envie somente a estrutura do fluxo e um request_id de teste — nunca a chave, CPF, carteira ou payload com segredo.