Webhook — garantías de orden y entrega
Emisión del webhook
Sección titulada «Emisión del webhook»Confirmado contra el código del backend (merchants/consumers.py):
- Síncrono dentro del request que cambia el estado. El signal
payment_merchantse dispara dentro delPayment.update(), y el handler corre en el mismo hilo que hace la llamada. - Un único intento —
session.send(request)sintimeout=ni retry loop. - Si el merchant devuelve
HTTP > 204o cae, el webhook se pierde (queda logueado como error del lado backend; no se reintenta).
Orden de entrega
Sección titulada «Orden de entrega»Patrón de deduplicación
Sección titulada «Patrón de deduplicación»async function handleWebhook(body) { const existing = await db.orders.findByB4bitId(body.identifier);
if (existing && new Date(body.edited_at) <= new Date(existing.last_update)) { // webhook viejo, ya tenemos info más reciente. logger.debug('Webhook obsoleto, ignorando', { identifier: body.identifier }); return 200; }
await db.orders.upsertStatus({ b4bit_id: body.identifier, status: body.status, last_update: body.edited_at, raw: body, });
return 200;}Reintentos
Sección titulada «Reintentos»Cómo recuperar estados perdidos
Sección titulada «Cómo recuperar estados perdidos»- Reconciliación diaria: job que corre cada madrugada y llama a
GET /orders/?start=AYER&end=HOY&page=1&items_per_page=100, itera todas las páginas y cruza con su base. Para cada pago cuyoedited_athaya avanzado, actualice. - Consulta puntual: si detecta una orden “huérfana” (existe en su checkout pero nunca recibió webhook), consulte
GET /orders/info/{identifier}para el estado autoritativo. - Alta disponibilidad del endpoint: reverse proxy con mínimo 2 workers, healthcheck, alertas de downtime.
- Respuesta async:
HTTP 200inmediato + cola interna (Redis, SQS, Celery) para procesar la lógica pesada sin bloquear el ACK.
Idempotencia
Sección titulada «Idempotencia»Su handler debe tolerar el mismo (identifier, status) llegando más de una vez:
- Use el
identifier+edited_atcomo clave única de dedupe. - No ejecute side effects (enviar emails, actualizar inventario) más de una vez por estado.
- Persista el hecho de que “ya procesé este estado” antes de ejecutar el side effect.