Skip to main content
ZoPay Connect mantiene un log de eventos como registro canónico de cada efecto colateral visible para el partner. Cada evento es un objeto durable e inmutable, consultable vía API. Los webhooks son la entrega push de esos eventos; el log de eventos es la entrega pull. Úsalos juntos: el webhook es notificación; el log es auditoría, fuente de verdad y herramienta de recuperación.

Dos superficies, una fuente de verdad

La fila del evento se escribe dentro de la misma transacción de base de datos que la transición de estado subyacente (el payment intent pasando a completed, la dirección recibiendo un depósito). Existe haya o no webhook configurado — partners sin URL configurada igual pueden hacer GET /events y recuperar todo lo registrado.

Forma del objeto

Tipos de evento

payment_intent.completed

Un payment intent llegó al estado completed — los depósitos acumulados igualaron o superaron el monto solicitado.
  • related_to_kind: payment_intent
  • related_to: UUID del intent
  • Webhook wire name: payment.completed (legacy; el tipo canónico para filtrar en GET /events?type=… es payment_intent.completed).
  • Dispara exactamente una vez por intent, en la transición terminal.
  • data: ver forma arriba.

payment_intent.payment_received

Un depósito aterrizó en una dirección del intent — dispara en cada crédito, incluyendo parciales. Distinto de payment_intent.completed: Este evento es aditivo — integraciones existentes que sólo manejan payment.completed siguen funcionando sin cambios. Suscríbete a payment.received si quieres notificaciones per-depósito (p. ej. barras de progreso de pago parcial o detección de carritos abandonados).
  • related_to_kind: payment_intent
  • related_to: UUID del intent
  • Webhook wire name: payment.received (canónico: payment_intent.payment_received).
  • data agrega tres campos cumulativos encima del base per-depósito:
Ramifica por partial_payment para decidir qué renderizar:
En el depósito que completa, los dos eventos disparan — primero payment.received con partial_payment=false, después payment.completed. Cada uno carga su propio event_id así que la deduplicación receiver-side (sobre X-ZoPay-Event-Id) los maneja correctamente.

address.deposit.received (próximamente)

Un depósito aterrizó en una dirección estándar provisionada con POST /addresses (no asociada a un intent). Es la señal de wallet whitelabel: tu usuario depositó crypto en la dirección que minteaste para él y necesitas acreditar su balance interno.
  • related_to_kind: address
  • related_to: UUID de la dirección
  • Webhook wire name: address.deposit.received
Regla de precedencia: si el depósito cae en una dirección de payment intent → payment_intent.payment_received (y payment_intent.completed en el que cierra). Si cae en una dirección estándar sin intent → address.deposit.received. Nunca ambos paths para el mismo depósito. Tu handler debe rutear por type, no por la URL — así estará listo cuando este tipo se active.

Operaciones

  • Listar eventosGET /events con filtros por type, related_to, livemode, from/to, cursor, limit.
  • Consultar un eventoGET /events/{event_id}.
  • Replicar un eventoPOST /events/{event_id}/replay encola una nueva entrega webhook con el mismo evt_….

Receta: “Mi handler nunca recibió el webhook del evento X”

  1. Encuentra el evento con GET /events?related_to=<intent-id> o por rango temporal ?from=…&to=….
  2. Inspecciona el evento (GET /events/{id}). Si falta entero, el problema está aguas arriba del log — abre ticket con el hash on-chain.
  3. Revisa el estado de entrega en el dashboard (delivery rows asociadas).
  4. Arregla lo que sea (servidor caído, secreto rotado, endpoint deshabilitado, etc.).
  5. Replay: POST /events/{id}/replay con Idempotency-Key. El X-ZoPay-Event-Id será el mismo, así que tu deduplicación lo reconocerá.
  6. Confirma en el dashboard que la entrega nueva llegó a delivered.
Para recuperación masiva (ventana de outage), lista por rango temporal y replica en bucle — el rate limit por clave pacea naturalmente.