Ir al contenido

Webhooks (Endpoints)

Los webhooks permiten a Sangho notificar a su servidor en tiempo real cuando se producen eventos importantes: pago correcto, reembolso realizado, suscripción cancelada, etc. En lugar de consultar la API periódicamente (polling), su servidor recibe una solicitud HTTP POST en cuanto se produce el evento.

Cada endpoint de webhook escucha una lista de eventos configurables y dispone de su propio secreto de firma HMAC-SHA256. Consulte la Referencia de los eventos para ver la lista completa de los tipos disponibles.

Verifique siempre la firma

Cada solicitud de webhook incluye una cabecera Sangho-Signature. Verifique sistemáticamente esta firma HMAC-SHA256 antes de procesar el evento: así se garantiza que la solicitud procede realmente de Sangho y no de un tercero malintencionado. Consulte la guía de verificación de la firma.

Eventos disponibles

EventoDesencadenante
payment_intent.succeededPaymentIntent pasado al estado succeeded.
payment_intent.failedPaymentIntent pasado al estado canceled tras un fallo.
transaction.succeededTransacción creada y completada.
refund.succeededReembolso devuelto al comprador.
refund.failedReembolso fallido en el operador.
invoice.paidFactura pagada.
invoice.payment_overdueFecha de vencimiento superada sin pago.
checkout.session.completedCheckoutSession pasada al estado complete.
subscription.createdNueva suscripción creada.
subscription.canceledSuscripción cancelada.
subscription.payment_failedIntento de renovación fallido.
customer.createdNuevo Customer creado.
customer.deletedCustomer eliminado.

Endpoints

MéthodeEndpointDescription
POST/webhooks/Crear un endpoint de webhook
GET/webhooks/Listar los endpoints
GET/webhooks/{id}/Recuperar un endpoint
PATCH/webhooks/{id}/Modificar un endpoint
DELETE/webhooks/{id}/Eliminar un endpoint
POST/webhooks/{id}/disable/Desactivar (suspender los envíos)
POST/webhooks/{id}/enable/Reactivar un endpoint desactivado
POST/webhooks/{id}/roll-secret/Regenerar el secreto de firma
POST/webhooks/{id}/test/Enviar un evento de prueba
GET/webhooks/{id}/deliveries/Registros de entrega
POST/webhooks/{id}/deliveries/{did}/retry/Reenviar una entrega fallida

Esquema del objeto

ResponseObjeto Webhook
Estructura completa devuelta por todos los endpoints de este recurso.
json
{
  "id": "wh_xxxxxxxxxxxx",
  "object": "webhook",
  "name": "Webhook production principal",
  "url": "https://monapp.com/webhooks/sangho",
  "status": "active",
  "events": [
    "payment_intent.succeeded",
    "transaction.succeeded",
    "refund.succeeded",
    "subscription.canceled"
  ],
  "security_profile": "HMAC_SHA256",
  "ssl_verification": true,
  "retry_policy": {
    "max_attempts": 5,
    "backoff_type": "exponential"
  },
  "last_delivery_at": "2026-03-01T10:05:00Z",
  "success_rate": 0.987,
  "livemode": true,
  "created_at": "2026-01-01T00:00:00Z"
}
ResponseEstructura de un evento recibido
Cuerpo de la solicitud POST enviada a su endpoint con cada evento.
json
{
  "id": "evt_xxxxxxxxxxxx",
  "object": "event",
  "type": "payment_intent.succeeded",
  "created_at": "2026-03-01T10:05:00Z",
  "livemode": true,
  "data": {
    "object": {
      "id": "pi_3Nx8mLKZ2eZvKYlo28m",
      "object": "payment_intent",
      "amount": 15000,
      "currency": "XAF",
      "status": "succeeded",
      "customer": "cust_xxxxxxxx",
      "metadata": { "order_id": "CMD-2026-042" }
    }
  }
}

Crear un endpoint de webhook

Registra una nueva URL a la que Sangho enviará los eventos seleccionados. El secreto de firma HMAC se devuelve una sola vez en la creación: almacénelo de inmediato en su gestor de secretos.

POSTCuerpo de la solicitud
nameRequis
stringex :Producción — pedidos

Nombre descriptivo del endpoint. Se muestra en su panel: utilice un nombre que identifique claramente el entorno o el uso.

Máx. 255 caracteres. Un buen nombre incluye el entorno y el ámbito funcional, por ejemplo “Producción — pagos y suscripciones” o “Staging — todos los eventos”.

urlRequis

URL de su endpoint de webhook. Debe ser accesible públicamente mediante HTTPS. Sangho realiza un ping de validación en la creación.

La URL debe responder con un código HTTP 2xx en 10 segundos para validarse. Para las pruebas en local, utilice un túnel como ngrok o localtunnel.

eventsRequis
array[string]ex :[“payment_intent.succeeded”, “refund.succeeded”]

Lista de los tipos de eventos que se escucharán en este endpoint. Utilice [“*”] para recibir todos los eventos.

Prefiera una lista explícita a “*” para reducir el volumen de solicitudes en su servidor y simplificar la depuración. Cada endpoint puede escuchar hasta 50 tipos de eventos distintos. Consulte la referencia de los eventos para ver la lista completa.

security_profileOptionnel
stringdéfaut :HMAC_SHA256

Método de firma de las solicitudes de webhook.

En savoir plus

Valores: HMAC_SHA256 (recomendado — cabecera Sangho-Signature), JWT (token JWT firmado en la cabecera Authorization), BASIC (Basic Auth — desaconsejado en producción). Consulte la guía de firma para ver los detalles de implementación.

ssl_verificationOptionnel
booleandéfaut :true

Activa la verificación del certificado SSL de su endpoint.

En savoir plus

Desactive ssl_verification únicamente en un entorno de desarrollo con un certificado autofirmado. En producción, mantenga siempre esta opción en true.

retry_policyOptionnel
object

Política de reintentos en caso de fallo de entrega (timeout, error 5xx).

En savoir plus

Objeto con dos campos: max_attempts (por defecto: 5, máx.: 10) y backoff_type (exponential o linear, por defecto: exponential). Con el backoff exponencial, los reintentos se hacen a 1 min, 5 min, 30 min, 2 h y 8 h. Con linear: cada 30 minutos.

metadataOptionnel
object

Datos libres asociados al endpoint: entorno, equipo responsable, etc.

Secreto mostrado una sola vez

El campo secret devuelto en la creación no se volverá a mostrar nunca. Almacénelo de inmediato en su gestor de secretos (variable de entorno, Vault, AWS Secrets Manager…). Si lo pierde, genere uno nuevo mediante POST /webhooks/{id}/roll-secret/.

Crear un endpoint

bash
curl -X POST https://api.sangho.ga/v1/webhooks/ \
  -H "Authorization: Bearer sk_prod_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Webhook production — commandes",
    "url": "https://monapp.com/webhooks/sangho",
    "events": [
      "payment_intent.succeeded",
      "transaction.succeeded",
      "refund.succeeded",
      "subscription.canceled"
    ],
    "security_profile": "HMAC_SHA256",
    "retry_policy": {
      "max_attempts": 5,
      "backoff_type": "exponential"
    }
  }'
Response201 Created — Secreto visible una sola vez
El endpoint se crea y está activo. El campo secret se muestra aquí y solo aquí: almacénelo de inmediato.
Después de esta respuesta, el secreto ya no es accesible mediante la API. Cualquier pérdida requiere un roll-secret.
json
{
  "id": "wh_xxxxxxxxxxxx",
  "object": "webhook",
  "name": "Webhook production — commandes",
  "url": "https://monapp.com/webhooks/sangho",
  "status": "active",
  "events": [
    "payment_intent.succeeded",
    "transaction.succeeded"
  ],
  "secret": "whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "security_profile": "HMAC_SHA256",
  "livemode": true,
  "created_at": "2026-01-01T00:00:00Z"
}

Verificar la firma

En cada envío, Sangho calcula una firma HMAC-SHA256 del cuerpo de la solicitud con su secreto y la incluye en la cabecera Sangho-Signature. Usted debe volver a calcular esta firma en el servidor y compararla con un método resistente a los timing attacks.

Utilice el cuerpo sin procesar (raw body)

La firma se calcula sobre el cuerpo sin procesar de la solicitud, antes de cualquier análisis de JSON. En Express.js, configure express.raw({ type: 'application/json' }) en la ruta del webhook: no utilice express.json(), que transformaría el body.

Gestión de las entregas

El endpoint GET /webhooks/{id}/deliveries/ devuelve el historial de intentos de entrega de un endpoint determinado. En caso de fallo, puede reenviar una entrega mediante POST /webhooks/{id}/deliveries/{did}/retry/.

Responda rápido, procese en modo asíncrono

Su endpoint debe devolver un 200 en un máximo de 10 segundos. Para los procesamientos largos (envío de correo, llamada a un servicio de terceros), encole la tarea en una cola (Celery, Bull, Sidekiq…) y responda de inmediato. Pasado ese plazo, Sangho considera la entrega fallida y activa la política de reintentos.

Verificación de la firma

python
# Vérification côté réception (Python / Django)
import hmac, hashlib, os


def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)


@app.route('/webhooks/sangho', methods=['POST'])
def handle_webhook():
    payload = request.get_data()
    sig = request.headers.get('Sangho-Signature', '')


    if not verify_webhook(payload, sig, os.environ['SANGHO_WEBHOOK_SECRET']):
        return '', 403


    event = request.json
    if event['type'] == 'payment_intent.succeeded':
        order_id = event['data']['object']['metadata']['order_id']
        fulfill_order(order_id)


    return '', 200

Registros de entrega

ResponseGET /webhooks/{id}/deliveries/
Devuelve los intentos de entrega con el estado HTTP y la respuesta de su servidor.
json
{
  "object": "list",
  "data": [
    {
      "id": "del_xxxxxxxxxx",
      "event_type": "payment_intent.succeeded",
      "status": "succeeded",
      "http_status": 200,
      "attempts": 1,
      "duration_ms": 145,
      "delivered_at": "2026-03-01T10:05:01Z"
    },
    {
      "id": "del_yyyyyyyyyy",
      "event_type": "refund.succeeded",
      "status": "failed",
      "http_status": 500,
      "attempts": 3,
      "next_retry_at": "2026-03-01T12:05:00Z",
      "error": "Connection timeout"
    }
  ]
}