Pular para o conteúdo
iRoamly Shop

Notificações Webhook

Use webhooks para receber em sua aplicação os resultados de envio de QR codes e de renovações.

Notificações Webhook

Introdução

Use webhooks para receber em sua aplicação os resultados de envio de QR codes e de renovações.

O que é um webhook?

A iRoamly envia notificações de webhook com os resultados de envio de QR codes e de renovações. Cada webhook usa HTTPS e inclui um payload JSON. Use webhooks para:

  • Receber as informações do QR code após a conversão de um código de resgate ou a conclusão de uma compra direta de QR code.
  • Receber os resultados de renovação via webhook: esim.renewal.success quando o QR code da renovação estiver pronto, esim.renewal.failed quando o pedido de renovação no fornecedor falhar.

Se seu endpoint não responder com um status 2xx, a iRoamly faz até 5 tentativas de entrega no total: a primeira imediatamente e as demais após 30 segundos, 2 minutos, 3 minutos e 5 minutos.

Passos para receber um webhook

Você pode começar a receber eventos em tempo real no seu app seguindo estes passos:

  • Crie um endpoint local para receber requisições
  • Registre seu endpoint de webhook em Desenvolvedores > Notificações Webhook no Painel da iRoamly Shop

1. Crie um endpoint local para receber requisições

Na sua aplicação local, crie uma nova rota que aceite requisições POST.

Por exemplo, você pode adicionar uma rota de API no Next.js:

typescript
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);
  }
};

Ao receber um evento, responda com HTTP 200 OK para sinalizar à iRoamly que o evento foi entregue com sucesso.

2. Registre seu endpoint de webhook de desenvolvimento

Registre sua URL HTTPS de acesso público no Painel da iRoamly Shop.

Você pode criar um túnel para seu servidor localhost com uma ferramenta como o ngrok.

Página Notificações Webhook do Painel com o painel “Novo webhook” aberto: campo URL do webhook e status Ativado / Desativado

3. Teste se seu endpoint de webhook está funcionando corretamente

Converta um código de resgate de teste em QR code, ou faça uma compra direta de QR code, para verificar se seu endpoint de webhook recebe o evento.

Notificações Webhook

Tipos de evento

Lista dos tipos de evento compatíveis e seus payloads.

Tipo de eventoEnviado quandoObservações
esim.qrcodeUm código de resgate foi convertido em QR code, ou uma compra direta de QR code foi concluída.Sem alterações. isrenew é sempre 0.
esim.renewal.successUma renovação foi concluída e o QR code do código de renovação está pronto.Novo. As renovações não enviam mais esim.qrcode.
esim.renewal.failedUma renovação falhou porque não foi possível fazer o pedido no fornecedor.Novo. Enviado apenas em falhas de pedido no fornecedor.

Entrega

Todos os eventos são entregues da mesma forma: uma requisição POST com corpo JSON para cada endpoint inscrito no evento. Qualquer resposta 2xx conta como entregue; caso contrário, há novas tentativas, até 5 no total (a primeira imediatamente e as demais após 30 segundos, 2 minutos, 3 minutos e 5 minutos). Cada requisição inclui estes headers:

HeaderDescriçãoTipo
X-Webhook-EventTipo de evento: esim.qrcode, esim.renewal.success ou esim.renewal.failed.String
X-Webhook-DeliveryID da entrega.String
X-Webhook-TimestampMomento em que a requisição foi assinada, em segundos Unix.String
X-Webhook-Signaturesha256= seguido do HMAC-SHA256 em hexadecimal do corpo bruto da requisição.String
X-Webhook-Signature-V2v1= seguido do HMAC-SHA256 em hexadecimal de "{timestamp}.{body}". Durante uma rotação de segredo, contém vários valores v1= separados por vírgulas.String

Veja Verificar requisições de webhook para saber como conferir as assinaturas.

esim.qrcode

Informações do QR code da eSIM retornadas após o resgate ou a compra do QR code da eSIM.

Exemplo de corpo da requisição

json
{
	"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"
	}
Notificações Webhook

esim.renewal.success

Enviado quando uma renovação é concluída: assim que o fornecedor retorna os dados de download do pedido de renovação, o QR code do código de renovação é gerado e seu status passa a ser 2 (Resgatado).

Headers da requisição

X-Webhook-Event:esim.renewal.success

A requisição também inclui X-Webhook-Delivery, X-Webhook-Timestamp, X-Webhook-Signature e X-Webhook-Signature-V2, como todos os eventos (veja Tipos de evento).

Exemplo de corpo da requisição

json
{
	"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

CampoDescriçãoTipo
codeSempre 0.Int
event_typeesim.renewal.successString
data.codeO novo código de resgate gerado para esta renovação. Use-o com Consultar QR code (qrcodeQuery) ou para renovar novamente.String
data.renewal_father_codeO código de resgate original (pai) que foi renovado.String
data.renew_order_idID do pedido de renovação no fornecedor.String
data.plan_nameNome do plano de renovação.String
data.qrcodeURL da imagem do QR code.String
data.qrcode_contentString LPA; pode ser importada diretamente.String
data.sm_dp_addressEndereço SM-DP+.String
data.activation_codeCódigo de ativação.String
data.iccidICCID. Pode estar vazio.String
data.download_urlString de download retornada pelo fornecedor.String
data.create_atData de criação: horário do servidor, no formato YYYY-MM-DD HH:mm:ss.String
data.isrenewSempre 1.Int
data.iscouldrenewalSe o novo código de resgate pode ser renovado novamente: 1 - pode ser renovado 2 - não pode ser renovado 3 - expiradoInt
Notificações Webhook

esim.renewal.failed

Enviado quando uma renovação falha: o fornecedor responde ao pedido de renovação com um código diferente de 0000, ou a requisição ao fornecedor falha.

(Observação: um callback ausente ou atrasado do fornecedor não dispara este evento. Defina um tempo limite e, como alternativa, consulte o código — veja Tratamento de eventos de renovação.)

Headers da requisição

X-Webhook-Event:esim.renewal.failed

A requisição também inclui X-Webhook-Delivery, X-Webhook-Timestamp, X-Webhook-Signature e X-Webhook-Signature-V2, como todos os eventos (veja Tipos de evento).

Exemplo de corpo da requisição

json
{
	"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

CampoDescriçãoTipo
codeSempre -1.Int
event_typeesim.renewal.failedString
data.codeO código de renovação gerado nesta tentativa. Ele não foi provisionado e não tem QR code.String
data.renewal_father_codeO código de resgate original (pai) que seria renovado.String
data.plan_nameNome do plano de renovação.String
data.error_msgErro retornado pelo fornecedor, para diagnóstico.String
data.create_atData de criação: horário do servidor, no formato YYYY-MM-DD HH:mm:ss.String
data.isrenewSempre 1.Int
Notificações Webhook

Renovações e esim.qrcode

As renovações não são mais entregues como esim.qrcode; esse evento é enviado para conversões em QR code e compras diretas de QR code. Em comparação com o payload de esim.qrcode:

  • event_type e o header X-Webhook-Event são esim.renewal.success ou esim.renewal.failed, e isrenew é 1.
  • data.code é o novo código de resgate criado pela renovação; o código que foi renovado é data.renewal_father_code.
  • esim.renewal.success adiciona renew_order_id, renewal_father_code, iscouldrenewal, download_url e iccid, e não tem order_id.
  • Uma renovação com falha é informada por esim.renewal.failed, com code de nível superior -1 e o erro do fornecedor em data.error_msg.
Notificações Webhook

Inscrições em eventos

Novos endpoints são inscritos nos três eventos por padrão. Endpoints existentes recebem esim.renewal.success e esim.renewal.failed automaticamente — nenhuma alteração é necessária.

Notificações Webhook

Tratamento de eventos de renovação

  • Torne seu handler idempotente. Uma nova tentativa pode entregar o mesmo evento mais de uma vez; por isso, elimine duplicatas por X-Webhook-Delivery ou por event_type + data.code e ignore os eventos já processados.
  • Use um tempo limite como alternativa. Se nem esim.renewal.success nem esim.renewal.failed chegar em um prazo razoável, consulte o código pela API de consulta (por exemplo, Consultar QR code) em vez de presumir que a renovação falhou.
  • Não use esim.renewal.failed para decidir reembolsos. Ele informa apenas que o pedido no fornecedor falhou; se e quando os créditos serão devolvidos é decidido à parte, portanto não reembolse seus clientes com base neste evento.
Notificações Webhook

Verificar requisições de webhook

Verifique a assinatura da iRoamly nas requisições de webhook.

Como verificar a assinatura da iRoamly?

A assinatura da iRoamly é enviada no header X-Webhook-Signature da requisição de webhook, como sha256= seguido da assinatura em hexadecimal. A assinatura é gerada com o algoritmo HMAC-SHA256, usando o segredo do webhook como chave e o corpo bruto da requisição (exatamente como recebido, antes de qualquer parsing de JSON) como mensagem.

Exemplo de header de webhook

json
{
'X-Webhook-Signature': 'sha256=dd7bdd2cf1f6bac6e171c6c508c157b7cd3cc1fd196394277fb59ba0bdd9b87b'
}

Você encontra o segredo do webhook em Desenvolvedores > Notificações Webhook no Painel.

Página Notificações Webhook do Painel: endpoint de webhook com sua URL e o segredo de assinatura (Revelar), e o histórico de entregas

Para gerar a assinatura, você pode usar o seguinte trecho de código:

typescript
import * as crypto from 'crypto';

  generateSignature(payload: string, secret: string): string {
    const computedSignature = crypto
      .createHmac('sha256', secret)
      .update(payload)
      .digest('hex');
    return 'sha256=' + computedSignature;
  }

No trecho de código acima, payload é o corpo bruto da requisição e secret é o segredo do webhook. Basta comparar a assinatura gerada (incluindo o prefixo sha256=) com o valor do header X-Webhook-Signature para concluir a verificação.

Assinatura com timestamp (X-Webhook-Signature-V2)

Cada requisição também inclui X-Webhook-Signature-V2: v1= seguido do HMAC-SHA256 em hexadecimal, com o mesmo segredo do webhook, de {timestamp}.{body} — o valor do header X-Webhook-Timestamp, um ponto e o corpo bruto da requisição.

Depois que você faz a rotação do segredo do webhook, o segredo antigo continua válido por 24 horas. Durante esse período, X-Webhook-Signature continua sendo assinado com o segredo antigo, e X-Webhook-Signature-V2 contém um valor por segredo, separados por vírgulas (v1=<old>,v1=<new>): aceite a requisição se qualquer valor corresponder.