Webhooks
Los webhooks notifican a tu aplicación en tiempo real cuando ocurren eventos — pagos, cambios de suscripción, reembolsos y más. En lugar de consultar el estado de un pago una y otra vez, registrás una URL y Recurrente le hace un POST cada vez que pasa algo.
Consulta el catálogo completo de eventos para ver cuándo se emite cada webhook, su esquema y un payload de ejemplo.
Integrarte toma cuatro pasos: registrás tu endpoint, manejás el evento, verificás la firma y lo probás.
1. Registra tu endpoint
Un endpoint es una URL de tu servidor donde querés recibir las notificaciones (ej. https://tusitio.com/webhooks/recurrente).
Vía Dashboard
Dentro de tu cuenta de Recurrente, ve a Configuración → Desarrolladores y API, haz clic en “Webhooks”, y añade la URL a donde quieres que sean enviados los requests.
Vía API
Podés registrar varias URLs (producción, staging, logging); cada evento se envía a todas.
2. Maneja el evento
Cada webhook entrega un evento en formato JSON con esta estructura. Tu handler ramifica según el campo type para saber qué método de pago lo generó, y según status para saber qué pasó.
El payload tiene tres capas:
Envelope — los campos de identificación del evento:
type— el tipo de pago:payment,bank_transfer,crypto,balance,cash.event_type— el evento:intent.succeeded,intent.failed,intent.pending,intent.canceled,intent.paid.status— el estado:pending,succeeded,failed,canceled,paid. Algunos estados intermedios (p. ej. de tarjeta) se exponen comopending; el valor exacto del procesador siempre está enraw_status.raw_status,id,receipt_number,api_version,created_at.
Datos del pago — amount_in_cents, currency, customer, product, tax_invoice_url, checkout, payment.
details — campos específicos del método de pago. Para payment: comisiones, cuotas, canal, etc. Para bank_transfer: bank_reference (referencia asignada por el banco o la red de pago) y sender_comment (comentario libre que el pagador escribió en la transferencia).
Ejemplo (intent.succeeded, pago con tarjeta):
El envelope y los datos del pago son iguales para todos los tipos; solo cambian type y el contenido de details. Así, un solo handler cubre todos los métodos de pago:
También podés consultar cualquier pago por API con GET /api/intents/{id} — devuelve exactamente el mismo formato que el webhook.
3. Verifica la firma
Cada webhook incluye una firma para que verifiques que viene de Recurrente y no fue alterado. Recomendamos fuertemente verificar las firmas en producción.
Signing Secret
Cada endpoint tiene un signing secret único, con el formato whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw. Hay dos formas de obtenerlo:
- Vía API: el campo
signingSecretse devuelve en la respuesta al crear el endpoint (POST /api/webhook_endpoints). Solo se devuelve en esa respuesta de creación, así que guárdalo de forma segura. - Vía dashboard: lo puedes encontrar en cualquier momento en el dashboard de Svix — accesible desde Configuración → Desarrolladores y API → Webhooks en tu cuenta de Recurrente.
Verificar con Librerías Oficiales (Recomendado)
La forma más fácil de verificar firmas es usando las librerías de verificación de webhooks de Svix, disponibles para muchos lenguajes:
Debes usar el body crudo del request al verificar webhooks. Si parseas el JSON y lo re-serializas, la verificación de firma fallará.
Verificar Manualmente
Cada request de webhook incluye tres headers:
Paso 1. Construye el contenido firmado concatenando el svix-id, svix-timestamp, y el body crudo del request, separados por puntos:
Paso 2. Decodifica la porción en base64 de tu signing secret (todo después de whsec_) y úsalo como llave para un hash HMAC-SHA256 del contenido firmado:
Paso 3. Compara tu firma calculada con la del header svix-signature. El valor del header tiene el prefijo v1, — quita ese prefijo antes de comparar. Usa una comparación de tiempo constante para prevenir ataques de timing.
Paso 4. Opcionalmente, verifica que el svix-timestamp esté dentro de unos minutos del tiempo actual de tu servidor para prevenir ataques de replay.
4. Pruébalo
El modo test envía webhooks simulados sin mover dinero. Pagar un checkout de prueba con la tarjeta 4242 4242 4242 4242 envía payment_intent.succeeded e intent.succeeded (type: payment) solo a los endpoints registrados con llaves TEST.
También puedes abrir el dashboard de webhooks y usar el tab Testing para enviar a tu endpoint un ejemplo de cualquiera de los eventos del catálogo. El mensaje muestra el payload, los intentos y si la entrega fue exitosa. Los pagos de prueba solo simulan tarjeta; para ejercitar el procesamiento real de otros métodos, usa el ambiente correspondiente.
Tipos de eventos
Eventos de pago (intent.*)
Un mismo cobro con balance dispara dos webhooks independientes: intent.succeeded (type: balance) a la cuenta del comercio y intent.paid a la cuenta pagadora.
Eventos de suscripción
Nota: en una suscripción, cuando un pago falla, Recurrente intenta cobrarlo de nuevo 3 y 5 días después. Si ambos re-intentos son fallidos, en ese momento se cancela la suscripción.
Otros eventos
Eventos de movimiento de dinero
Los eventos withdrawal.* y swap.* incluyen una llave transfer con la misma forma unificada que devuelve GET /api/transfers/{id} (los transfer.* ya la usan como forma principal). Si integras con el endpoint unificado, lee siempre esa llave — ver la guía Mover dinero.
Reintentos
Si tu endpoint no responde con un código 2xx, Recurrente reintentará enviar el webhook:
- Inmediatamente después del primer fallo
- 1 minuto después
- 5 minutos después
- 30 minutos después
- 2 horas después
- 6 horas después
Mejores Prácticas
- Retorna 2xx rápidamente — Confirma la recepción antes de hacer procesamiento pesado
- Maneja duplicados — Los webhooks pueden ser entregados más de una vez; usa el ID del evento para idempotencia
- Verifica la fuente — Valida las firmas de los webhooks como se describe arriba
- Procesa de forma asíncrona — Usa una cola para procesamiento pesado después de confirmar recepción
¿Integraste antes de junio 2026 con los eventos por tipo (payment_intent.*, bank_transfer_intent.*, etc.)? Siguen funcionando sin cambios — ver Eventos legacy o la guía para migrar al formato unificado.

