Skip to main content
Los webhooks te permiten recibir notificaciones en tiempo real sobre payouts, depósitos, onboarding/verificación de customers y transacciones de tarjeta. Cuando ocurre un evento, enviamos una solicitud POST firmada al endpoint de webhook que configuraste, con el cuerpo del evento.

Configuración del endpoint

Tu endpoint debe ser accesible públicamente por HTTPS y responder con cualquier código de estado 2xx. Configura su URL con tu contacto de Meru o desde el dashboard. Al crearlo recibes un secreto de firma (con prefijo whsec_) — guárdalo de forma segura; lo necesitas para verificar las firmas.

Estructura del evento

Todos los cuerpos de entrega tienen la misma forma de nivel superior:
string
El tipo de evento (ver los eventos más abajo).
string
Marca de tiempo ISO 8601 de cuándo se emitió el evento.
object
El cuerpo del evento. Su forma depende de type.

Eventos

Las cuentas virtuales no tienen eventos de ciclo de vida

No existe un evento virtual_account.created, virtual_account.activated ni virtual_account.deactivated. La creación de una cuenta virtual, y su activación o desactivación, no generan un webhook. La única señal asociada a una cuenta virtual es el depósito en sí: cuando llegan los fondos recibes un payin.updated. Si necesitas su estado actual, consulta los endpoints de cuentas en la API.

Migración de nombres de eventos

Estamos estandarizando algunos nombres de eventos. Durante la transición, se entregan tanto el nombre nuevo como el heredado para el mismo evento, así no se pierde nada mientras migras. Cada evento incluye un data.eventId estable —idéntico entre el nombre nuevo y el heredado—, con el que puedes deduplicar el par. Los nombres heredados se eliminarán el 15 de noviembre de 2026. Apunta tus handlers a los nombres nuevos antes de esa fecha.

Versionado y deprecación

Los eventos de webhook se versionan por tipo de evento, no por un header ni por un campo del payload. Tu endpoint se suscribe a tipos de evento específicos, así que mantener la versión en el nombre es lo que te permite elegir qué versión recibes.

Qué se considera un cambio incompatible

Agregar un campo opcional nuevo a data no es incompatible, y lo publicamos sin una versión nueva: se anuncia en el changelog. Tu handler debe ignorar los campos que no reconozca. Los cambios incompatibles son eliminar o renombrar un campo, cambiar su tipo o cambiar el significado de un valor. Nunca los aplicamos sobre un tipo de evento existente: en su lugar publicamos uno nuevo con un sufijo de versión —por ejemplo payin.updated.v2— y entregamos ambos en paralelo durante la ventana de deprecación.

Política de deprecación

Cuando deprecamos un tipo de evento o un campo:
  • Lo anunciamos con al menos 90 días de anticipación, a través del changelog, un aviso en la página de referencia del evento con la fecha de eliminación, y un correo a los suscriptores del evento afectado.
  • El evento deprecado y su reemplazo se entregan en paralelo durante toda la ventana, ambos con el mismo data.eventId para que puedas deduplicar el par.
  • No eliminamos un evento deprecado hasta que sus suscriptores hayan migrado.

Headers de entrega

Cada solicitud incluye estos headers:

Verificación de firmas

Cada solicitud se firma con HMAC-SHA256 para que puedas confirmar que viene de nosotros. El contenido firmado es el string {webhook-id}.{webhook-timestamp}.{cuerpoCrudo}, con clave en tu secreto de firma (decodificado de base64 tras quitar el prefijo whsec_), y el resultado se codifica en base64 dentro del header webhook-signature. Para verificar: recalcula la firma sobre el cuerpo crudo de la solicitud (antes de cualquier parseo de JSON) y compárala contra el header en tiempo constante. Rechaza las entregas cuyo webhook-timestamp tenga más de 5 minutos.

Idempotencia

El mismo evento puede entregarse más de una vez. Usa el header webhook-id como clave de idempotencia: guarda los IDs procesados y descarta los duplicados.

Reintentos

Si tu endpoint no devuelve un estado 2xx (o agota el tiempo de espera), reintentamos la entrega automáticamente con backoff exponencial a lo largo de varias horas, respetando Retry-After en respuestas de error. Confirma rápido (en pocos segundos) y procesa el trabajo pesado de forma asíncrona. Los endpoints que fallan de forma persistente pueden quedar deshabilitados.

Buenas prácticas

  • Verifica siempre la firma contra el cuerpo crudo antes de procesar.
  • Responde rápido con un 2xx y procesa de forma asíncrona.
  • Sé idempotente usando webhook-id.
  • No asumas orden — apóyate en state/previousState y updatedAt, no en el orden de entrega.
  • Registra el webhook-id, el type y el data de cada entrega.

Ejemplo de handler

Pruebas

Expón tu servidor local con un túnel (por ejemplo, ngrok) y registra la URL pública como tu endpoint de webhook:

Solución de problemas

  • Firma inválida: verifica contra el cuerpo crudo (no un JSON re-serializado), usa el secreto whsec_ correcto y lee los headers webhook-id/webhook-timestamp/webhook-signature tal cual.
  • Eventos duplicados: deduplica usando webhook-id.
  • Eventos perdidos: asegúrate de que tu endpoint devuelva 2xx rápido; las respuestas non-2xx y los timeouts se reintentan, pero las fallas persistentes pueden deshabilitar la entrega.
  • Errores de SSL: tu endpoint necesita un certificado TLS válido.
Para ayuda con una entrega específica, contacta a soporte con el webhook-id.