Ir al contenido

Referencia de los eventos

Cada evento es un objeto JSON que contiene un tipo, un ID único y los datos de el recurso afectado. Suscríbase a estos eventos al crear un endpoint de webhook.

Los eventos se emiten en modo livemode: true en producción y livemode: false en el sandbox. Un mismo endpoint solo recibe los eventos del modo correspondiente a su clave API.

Idempotencia — procese cada evento una sola vez

En caso de reintento, el mismo evento puede entregarse varias veces con el mismo id. Almacene los ID de los eventos ya procesados e ignore los duplicados para garantizar la idempotencia de su handler.

Eventos de Pagos

EventoDesencadenante
payment_intent.createdPaymentIntent creado.
payment_intent.succeededPago correcto: activar la entrega.
payment_intent.payment_failedPago fallido tras el último intento.
payment_intent.canceledPaymentIntent cancelado manualmente.
checkout_session.completedSesión de checkout en estado complete.
checkout_session.expiredSesión caducada sin pago.
transaction.succeededTransacción finalizada en el operador.
transaction.failedTransacción fallida en el operador.
refund.createdReembolso iniciado.
refund.succeededReembolso devuelto al comprador.
refund.failedReembolso fallido en el operador.
payment_link.paidEnlace de pago utilizado correctamente.

Eventos de Clientes

EventoDesencadenante
customer.createdNuevo Customer creado.
customer.updatedDatos del cliente modificados.
customer.deletedCustomer anonimizado (cumplimiento del RGPD).
payment_method.attachedMétodo de pago añadido al cliente.
payment_method.detachedMétodo de pago retirado del cliente.

Eventos de Suscripciones

EventoDesencadenante
subscription.createdNueva suscripción creada.
subscription.updatedSuscripción modificada (plan, cantidad…).
subscription.renewedRenovación correcta: factura pagada.
subscription.past_dueFallo de renovación: activar el recordatorio.
subscription.canceledCancelación efectiva.
subscription.trial_will_end3 días antes del fin del período de prueba.
invoice.createdFactura generada automáticamente.
invoice.finalizedFactura finalizada y enviada al cliente.
invoice.paidFactura pagada.
invoice.payment_failedFallo de pago de la factura.

Eventos de la Cuenta

EventoDesencadenante
kyc.submittedExpediente KYC enviado para su validación.
kyc.approvedKYC validado: cuenta plenamente operativa.
kyc.rejectedKYC rechazado: se requiere una acción del comerciante.
payout.createdTransferencia a la cuenta bancaria iniciada.
payout.paidTransferencia realizada correctamente.
payout.failedTransferencia fallida: compruebe los datos bancarios.

Estructura de un evento

ResponseObjeto Event
Estructura común a todos los eventos de Sangho.
json
{
  "id": "evt_xxxxxxxxxxxx",
  "object": "event",
  "type": "payment_intent.succeeded",
  "api_version": "v1",
  "created_at": "2026-03-01T10:05:00Z",
  "livemode": true,
  "data": {
    "object": {
      "id": "pi_xxxxxxxxxxxx",
      "object": "payment_intent",
      "amount": 15000,
      "currency": "XAF",
      "status": "succeeded",
      "customer": "cust_xxxx"
    }
  }
}

Implementar un handler

Su handler de webhook debe responder con un código HTTP 2xx en un máximo de 10 segundos. Para los procesamientos largos, encole la tarea en una cola asíncrona y responda de inmediato.

Empiece siempre verificando la firma Sangho-Signature antes de cualquier procesamiento. Consulte la guía de verificación de la firma para ver los ejemplos completos por lenguaje.

Gestión de los eventos desconocidos

Su handler debe ignorar silenciosamente los tipos de eventos que no reconozca y devolver un 200. Sangho puede emitir nuevos tipos de eventos sin previo aviso: un handler que devuelva un error ante un tipo desconocido se reintentará innecesariamente.

Evento de prueba

Utilice POST /webhooks/{id}/test/ para enviar un evento ficticio a su endpoint y validar su integración sin desencadenar un pago real. El evento de prueba tiene livemode: false sea cual sea el entorno.

Gestor de Webhooks

javascript
// Node.js / Express
app.post(
  '/webhook',
  express.raw({ type: 'application/json' }),
  async (req, res) => {
    const sig = req.headers['sangho-signature'];
    let event;


    try {
      event = sangho.webhooks.constructEvent(
        req.body,
        sig,
        process.env.WEBHOOK_SECRET,
      );
    } catch (err) {
      return res.status(400).send(`Signature invalide: ${err.message}`);
    }


    switch (event.type) {
      case 'payment_intent.succeeded':
        await fulfillOrder(event.data.object.metadata.order_id);
        break;
      case 'subscription.past_due':
        await sendDunningEmail(event.data.object.customer);
        break;
      case 'refund.succeeded':
        await notifyCustomerRefund(event.data.object);
        break;
      default:
        // Type inconnu — ignorer silencieusement
        break;
    }


    res.json({ received: true });
  },
);