Notificaciones Webhook
Usa webhooks para recibir en tu aplicación los resultados de entrega de códigos QR y de renovaciones.
Introducción
Usa webhooks para recibir en tu aplicación los resultados de entrega de códigos QR y de renovaciones.
¿Qué es un webhook?
iRoamly envía notificaciones de webhook con los resultados de entrega de códigos QR y de renovaciones. Cada webhook usa HTTPS e incluye un payload JSON. Usa los webhooks para:
- Recibir la información del código QR tras convertir un código de canje o completar una compra directa de código QR.
- Recibir los resultados de las renovaciones por webhook:
esim.renewal.successcuando el código QR de la renovación está listo yesim.renewal.failedcuando falla el pedido de renovación con el proveedor.
Si tu endpoint no responde con un estado 2xx, iRoamly realiza hasta 5 intentos de entrega en total: el primero de inmediato y los reintentos a los 30 segundos, 2 minutos, 3 minutos y 5 minutos.
Pasos para recibir un webhook
Puedes empezar a recibir eventos en tiempo real en tu aplicación con estos pasos:
- Crea un endpoint local para recibir las solicitudes
- Registra tu endpoint de webhook en Desarrolladores > Notificaciones Webhook en el Panel de iRoamly Shop
1. Crea un endpoint local para recibir las solicitudes
En tu aplicación local, crea una nueva ruta que acepte solicitudes POST.
Por ejemplo, puedes añadir una ruta de API en Next.js:
import type { NextApiRequest, NextApiResponse } from 'next';
export default (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'POST') {
const payload = req.body;
console.log(payload);
res.status(200);
}
};Al recibir un evento, debes responder con HTTP 200 OK para indicar a iRoamly que el evento se entregó correctamente.
2. Registra tu endpoint de webhook de desarrollo
Registra tu URL HTTPS de acceso público en el Panel de iRoamly Shop.
Puedes crear un túnel hacia tu servidor localhost con una herramienta como ngrok.

3. Comprueba que tu endpoint de webhook funciona correctamente
Convierte un código de canje de prueba en código QR, o haz una compra directa de código QR, para comprobar que tu endpoint de webhook recibe el evento.
Tipos de evento
Lista de los tipos de evento admitidos y sus payloads.
Entrega
Todos los eventos se entregan de la misma forma: una solicitud POST con un body JSON a cada endpoint suscrito al evento. Cualquier respuesta 2xx cuenta como entregada; si no, se reintenta, hasta 5 intentos en total (el primero de inmediato y los reintentos a los 30 segundos, 2 minutos, 3 minutos y 5 minutos). Cada solicitud incluye estos headers:
Consulta Verificar las solicitudes de webhook para saber cómo comprobar las firmas.
esim.qrcode
Información del código QR de la eSIM que se devuelve tras canjear o comprar el código QR de la eSIM.
Body de solicitud de ejemplo
{
"code": 0,
"data": {
"activation_code": "CD112885573C49DDA42F64C905B925F4",
"code": "UtTpoKCe769u2tt",
"create_at": "2025-09-01 11:34:30",
"isrenew": 0,
"order_id": "ESIM202509021134343282",
"plan_name": "Japan-eSIM-3GB-15 Days-Daily",
"qrcode": "https://www.iroamly.com/qrcode/20250901/xSQfryvOWo0QUhsGcbpeTm9wWYfGu9BQ.png",
"qrcode_content": "LPA:1$rsp1.cmlink.com$CD352885573C49DDA42F64C905B925F4",
"sm_dp_address": "rsp1.cmlink.com"
},
"event_type": "esim.qrcode"
}esim.renewal.success
Se envía cuando una renovación se completa: en cuanto el proveedor devuelve los datos de descarga del pedido de renovación, se genera el código QR del código de renovación y su status pasa a 2 (Canjeado).
Headers de la solicitud
esim.renewal.successLa solicitud también incluye X-Webhook-Delivery, X-Webhook-Timestamp, X-Webhook-Signature y X-Webhook-Signature-V2, como todos los eventos (consulta Tipos de evento).
Body de solicitud de ejemplo
{
"code": 0,
"data": {
"activation_code": "CD112885573C49DDA42F64C905B925F4",
"code": "RnB7xTq2Lm9pQaZ",
"create_at": "2026-10-28 09:12:41",
"download_url": "LPA:1$rsp1.cmlink.com$CD352885573C49DDA42F64C905B925F4",
"iccid": "8944501234567890123",
"iscouldrenewal": 1,
"isrenew": 1,
"plan_name": "Japan-eSIM-3GB-15 Days-Daily",
"qrcode": "https://www.iroamly.com/qrcode/20261028/xSQfryvOWo0QUhsGcbpeTm9wWYfGu9BQ.png",
"qrcode_content": "LPA:1$rsp1.cmlink.com$CD352885573C49DDA42F64C905B925F4",
"renew_order_id": "TG202610280912410001",
"renewal_father_code": "UtTpoKCe769u2tt",
"sm_dp_address": "rsp1.cmlink.com"
},
"event_type": "esim.renewal.success"
}Campos
esim.renewal.failed
Se envía cuando una renovación falla: el proveedor responde al pedido de renovación con un código distinto de 0000, o la solicitud al proveedor falla.
(Nota: si el proveedor no envía la respuesta o la envía tarde, este evento no se activa. Define un tiempo de espera y, como alternativa, consulta el código: consulta Gestionar los eventos de renovación.)
Headers de la solicitud
esim.renewal.failedLa solicitud también incluye X-Webhook-Delivery, X-Webhook-Timestamp, X-Webhook-Signature y X-Webhook-Signature-V2, como todos los eventos (consulta Tipos de evento).
Body de solicitud de ejemplo
{
"code": -1,
"data": {
"code": "RnB7xTq2Lm9pQaZ",
"create_at": "2026-10-28 09:12:41",
"error_msg": "TuGe_RenewOrderEx RespCode: 9999",
"isrenew": 1,
"plan_name": "Japan-eSIM-3GB-15 Days-Daily",
"renewal_father_code": "UtTpoKCe769u2tt"
},
"event_type": "esim.renewal.failed"
}Campos
Renovaciones y esim.qrcode
Las renovaciones ya no se entregan como esim.qrcode; ese evento se envía para las conversiones en código QR y las compras directas de código QR. En comparación con el payload de esim.qrcode:
event_typey el headerX-Webhook-Eventsonesim.renewal.successoesim.renewal.failed, eisrenewes1.data.codees el nuevo código de canje creado por la renovación; el código que se renovó esdata.renewal_father_code.esim.renewal.successañaderenew_order_id,renewal_father_code,iscouldrenewal,download_urleiccid, y no incluyeorder_id.- Una renovación fallida se notifica con
esim.renewal.failed, concodede nivel superior-1y el error del proveedor endata.error_msg.
Suscripciones a eventos
Los endpoints nuevos se suscriben por defecto a los tres eventos. Los endpoints existentes reciben esim.renewal.success y esim.renewal.failed automáticamente: no hace falta ningún cambio.
Gestionar los eventos de renovación
- Haz que tu handler sea idempotente. Un reintento puede entregar el mismo evento más de una vez, así que elimina duplicados por
X-Webhook-Deliveryo porevent_type+data.code, e ignora los eventos que ya hayas procesado. - Usa un tiempo de espera como alternativa. Si no llega ni
esim.renewal.successniesim.renewal.faileden un tiempo razonable, consulta el código con la API de consulta (por ejemplo, Query QR Code) en lugar de suponer que la renovación falló. - No uses
esim.renewal.failedpara decidir reembolsos. Solo indica que falló el pedido con el proveedor; si se devuelven los créditos y cuándo se decide por separado, así que no abones importes a tus clientes en función de este evento.
Verificar las solicitudes de webhook
Verifica la firma de iRoamly en las solicitudes de webhook.
¿Cómo verificar la firma de iRoamly?
La firma de iRoamly se envía en el header X-Webhook-Signature de la solicitud del webhook, como sha256= seguido de la firma codificada en hexadecimal. La firma se genera con el algoritmo HMAC-SHA256, usando el secreto del webhook como clave y el body sin procesar de la solicitud (tal como se recibe, antes de cualquier análisis JSON) como mensaje.
Header de webhook de ejemplo
{
'X-Webhook-Signature': 'sha256=dd7bdd2cf1f6bac6e171c6c508c157b7cd3cc1fd196394277fb59ba0bdd9b87b'
}Encontrarás el secreto de tu webhook en Desarrolladores > Notificaciones Webhook en el Panel.

Para generar la firma, puedes usar el siguiente fragmento de código:
import * as crypto from 'crypto';
generateSignature(payload: string, secret: string): string {
const computedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return 'sha256=' + computedSignature;
}En el fragmento de código anterior, payload es el body sin procesar de la solicitud y secret es el secreto del webhook. Basta con comparar la firma generada (incluido el prefijo sha256=) con el valor del header X-Webhook-Signature para completar la verificación.
Firma con marca de tiempo (X-Webhook-Signature-V2)
Cada solicitud también incluye X-Webhook-Signature-V2: v1= seguido del HMAC-SHA256 codificado en hexadecimal, con el mismo secreto del webhook, de {timestamp}.{body}: el valor del header X-Webhook-Timestamp, un punto y el body sin procesar de la solicitud.
Después de rotar el secreto del webhook, el secreto anterior sigue siendo válido durante 24 horas. Durante ese periodo, X-Webhook-Signature se sigue firmando con el secreto anterior y X-Webhook-Signature-V2 incluye un valor por secreto, separados por comas (v1=<old>,v1=<new>): acepta la solicitud si alguno de los valores coincide.