FIABILIDAD DE LOS PAGOS

Webhooks e idempotencia en una integración PIX ↔ stablecoins

El identificador evita duplicados; el webhook reduce la espera; la consulta concilia. Los tres deben existir juntos. Un timeout no demuestra que la creación haya fallado, un webhook puede repetirse y un evento puede llegar después de una consulta.
external_idHMAC SHA-256marca de tiempo contra ataques de repeticiónreintento controladoconsulta de estado

La regla de oro

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 webhooks

Lee el cuerpo sin procesar

La firma se ha calculado sobre los bytes recibidos. Validar un JSON serializado de nuevo puede producir otra secuencia.

Valida la marca de tiempo y la firma

Rechaza las firmas no válidas y las marcas de tiempo fuera de la ventana permitida. Compara el HMAC en tiempo constante.

Guarda de forma persistente por identificador de evento

Una restricción de unicidad hace que el procesamiento sea idempotente. Un evento repetido debe recibir una respuesta de éxito sin volver a aplicar su efecto.

Aplica una transición válida

No hagas retroceder una operación completada porque haya llegado tarde un evento anterior.

Responde con 2xx después del commit

Si falla el almacenamiento persistente, responde con un error para permitir otra entrega. No confirmes antes de guardar.

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)

Cómo interpretar los fallos

Timeout al crear

Repite con el mismo external_id. No crees un identificador nuevo.

Webhook repetido

Responde con 2xx después de confirmar que el evento ya se ha guardado de forma persistente.

Webhook retrasado

Valida la transición; no sobrescribas un estado terminal más reciente.

Webhook perdido

Usa la consulta de estado y el historial de entregas para conciliar.

Prueba antes de producción

Configura una URL HTTPS pública en la clave y usa POST /webhooks/test. Después valida los reintentos, las firmas incorrectas, los eventos repetidos y la falta temporal de disponibilidad de tu endpoint.

Abrir guía rápidaVer el contrato actualizado

¿Quieres revisar tu consumidor antes del primer PIX?

Envía solo la estructura del flujo y un request_id de prueba, nunca la clave, CPF, billetera ni un cuerpo que contenga secretos.