Vai al contenuto
iRoamly Shop

Notifiche Webhook

Usa i webhook per ricevere nella tua applicazione i risultati di consegna dei codici QR e dei rinnovi.

Notifiche Webhook

Introduzione

Usa i webhook per ricevere nella tua applicazione i risultati di consegna dei codici QR e dei rinnovi.

Che cos’è un webhook?

iRoamly invia notifiche webhook per la consegna dei codici QR e i risultati dei rinnovi. Ogni webhook usa HTTPS e include un payload JSON. Con i webhook puoi:

  • Ricevere le informazioni del codice QR dopo la conversione di un codice di riscatto o il completamento di un acquisto diretto di codice QR.
  • Ricevere l’esito dei rinnovi tramite webhook: esim.renewal.success quando il codice QR del rinnovo è pronto, esim.renewal.failed quando l’ordine di rinnovo presso il fornitore non riesce.

Se il tuo endpoint non risponde con uno stato 2xx, iRoamly effettua fino a 5 tentativi di consegna in totale: il primo subito, poi nuovi tentativi dopo 30 secondi, 2 minuti, 3 minuti e 5 minuti.

Passaggi per ricevere un webhook

Puoi iniziare a ricevere eventi in tempo reale nella tua app con questi passaggi:

  • Crea un endpoint locale per ricevere le richieste
  • Registra il tuo endpoint webhook in Sviluppatori > Notifiche Webhook nella Dashboard di iRoamly Shop

1. Crea un endpoint locale per ricevere le richieste

Nella tua applicazione locale, crea una nuova route in grado di accettare richieste POST.

Ad esempio, puoi aggiungere una route API in 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);
  }
};

Alla ricezione di un evento, rispondi con HTTP 200 OK per segnalare a iRoamly che l’evento è stato consegnato correttamente.

2. Registra il tuo endpoint webhook di sviluppo

Registra il tuo URL HTTPS accessibile pubblicamente nella Dashboard di iRoamly Shop.

Puoi creare un tunnel verso il tuo server localhost con uno strumento come ngrok.

Pagina Notifiche Webhook della Dashboard con il pannello “Nuovo webhook” aperto: campo URL del webhook e stato Attivo / Disattivato

3. Verifica che l’endpoint webhook funzioni correttamente

Converti un codice di riscatto di prova in codice QR, oppure effettua un acquisto diretto di codice QR, per verificare che il tuo endpoint webhook riceva l’evento.

Notifiche Webhook

Tipi di evento

Elenco dei tipi di evento supportati e dei relativi payload.

Tipo di eventoInviato quandoNote
esim.qrcodeUn codice di riscatto è stato convertito in codice QR, oppure è stato completato un acquisto diretto di codice QR.Invariato. isrenew è sempre 0.
esim.renewal.successUn rinnovo è riuscito e il codice QR del codice di rinnovo è pronto.Nuovo. I rinnovi non inviano più esim.qrcode.
esim.renewal.failedUn rinnovo non è riuscito perché non è stato possibile effettuare l’ordine presso il fornitore.Nuovo. Inviato solo in caso di errore dell’ordine presso il fornitore.

Consegna

Ogni evento viene consegnato allo stesso modo: una richiesta POST con corpo JSON a ciascun endpoint iscritto all’evento. Qualsiasi risposta 2xx vale come consegna; altrimenti la richiesta viene ritentata, fino a 5 tentativi in totale (il primo subito, poi nuovi tentativi dopo 30 secondi, 2 minuti, 3 minuti e 5 minuti). Ogni richiesta contiene questi header:

HeaderDescrizioneTipo
X-Webhook-EventTipo di evento: esim.qrcode, esim.renewal.success o esim.renewal.failed.String
X-Webhook-DeliveryID della consegna.String
X-Webhook-TimestampMomento in cui la richiesta è stata firmata, in secondi Unix.String
X-Webhook-Signaturesha256= seguito dall’HMAC-SHA256 esadecimale del corpo grezzo della richiesta.String
X-Webhook-Signature-V2v1= seguito dall’HMAC-SHA256 esadecimale di "{timestamp}.{body}". Durante una rotazione del segreto contiene più valori v1= separati da virgole.String

Vedi Verifica delle richieste webhook per sapere come controllare le firme.

esim.qrcode

Informazioni sul codice QR dell’eSIM restituite dopo il riscatto o l’acquisto del codice QR dell’eSIM.

Corpo della richiesta di esempio

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"
	}
Notifiche Webhook

esim.renewal.success

Inviato quando un rinnovo riesce: quando il fornitore restituisce i dati di download dell’ordine di rinnovo, il sistema genera il codice QR del codice di rinnovo e il suo status diventa 2 (Riscattato).

Header della richiesta

X-Webhook-Event:esim.renewal.success

La richiesta contiene anche X-Webhook-Delivery, X-Webhook-Timestamp, X-Webhook-Signature e X-Webhook-Signature-V2, come ogni evento (vedi Tipi di evento).

Corpo della richiesta di esempio

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"
}

Campi

CampoDescrizioneTipo
codeSempre 0.Int
event_typeesim.renewal.successString
data.codeIl nuovo codice di riscatto generato per questo rinnovo. Usalo con Query QR Code (qrcodeQuery) o per rinnovare di nuovo.String
data.renewal_father_codeIl codice di riscatto originale (padre) che è stato rinnovato.String
data.renew_order_idID dell’ordine di rinnovo presso il fornitore.String
data.plan_nameNome del piano di rinnovo.String
data.qrcodeURL dell’immagine del codice QR.String
data.qrcode_contentStringa LPA; può essere importata direttamente.String
data.sm_dp_addressIndirizzo SM-DP+.String
data.activation_codeCodice di attivazione.String
data.iccidICCID. Può essere vuoto.String
data.download_urlStringa di download restituita dal fornitore.String
data.create_atData di creazione: ora del server, nel formato YYYY-MM-DD HH:mm:ss.String
data.isrenewSempre 1.Int
data.iscouldrenewalIndica se il nuovo codice di riscatto può essere rinnovato di nuovo: 1 - può essere rinnovato 2 - non può essere rinnovato 3 - scadutoInt
Notifiche Webhook

esim.renewal.failed

Inviato quando un rinnovo non riesce: il fornitore risponde all’ordine di rinnovo con un codice diverso da 0000, oppure la richiesta al fornitore non riesce.

(Nota: un callback del fornitore mancante o in ritardo non attiva questo evento. Imposta un timeout e ripiega sull’interrogazione del codice: vedi Gestione degli eventi di rinnovo.)

Header della richiesta

X-Webhook-Event:esim.renewal.failed

La richiesta contiene anche X-Webhook-Delivery, X-Webhook-Timestamp, X-Webhook-Signature e X-Webhook-Signature-V2, come ogni evento (vedi Tipi di evento).

Corpo della richiesta di esempio

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"
}

Campi

CampoDescrizioneTipo
codeSempre -1.Int
event_typeesim.renewal.failedString
data.codeIl codice di rinnovo generato per questo tentativo. Non è stato attivato e non ha un codice QR.String
data.renewal_father_codeIl codice di riscatto originale (padre) che doveva essere rinnovato.String
data.plan_nameNome del piano di rinnovo.String
data.error_msgErrore restituito dal fornitore, utile per la risoluzione dei problemi.String
data.create_atData di creazione: ora del server, nel formato YYYY-MM-DD HH:mm:ss.String
data.isrenewSempre 1.Int
Notifiche Webhook

Rinnovi ed esim.qrcode

I rinnovi non vengono più consegnati come esim.qrcode; questo evento viene inviato per le conversioni in codice QR e gli acquisti diretti di codici QR. Rispetto al payload di esim.qrcode:

  • event_type e l’header X-Webhook-Event valgono esim.renewal.success o esim.renewal.failed, e isrenew vale 1.
  • data.code è il nuovo codice di riscatto creato dal rinnovo; il codice rinnovato è data.renewal_father_code.
  • esim.renewal.success aggiunge renew_order_id, renewal_father_code, iscouldrenewal, download_url e iccid, e non contiene order_id.
  • Un rinnovo non riuscito viene segnalato da esim.renewal.failed, con code di primo livello -1 e l’errore del fornitore in data.error_msg.
Notifiche Webhook

Iscrizioni agli eventi

I nuovi endpoint sono iscritti per impostazione predefinita a tutti e tre gli eventi. Gli endpoint esistenti ricevono automaticamente esim.renewal.success ed esim.renewal.failed: non serve alcuna modifica.

Notifiche Webhook

Gestione degli eventi di rinnovo

  • Rendi idempotente il tuo gestore. Un nuovo tentativo può consegnare lo stesso evento più di una volta, quindi deduplica in base a X-Webhook-Delivery o a event_type + data.code e ignora gli eventi già elaborati.
  • Prevedi un timeout di riserva. Se né esim.renewal.success né esim.renewal.failed arrivano entro un tempo ragionevole, interroga il codice con l’API di interrogazione (ad esempio Query QR Code) invece di presumere che il rinnovo non sia riuscito.
  • Non usare esim.renewal.failed per decidere i rimborsi. Segnala solo che l’ordine presso il fornitore non è riuscito; se e quando i crediti vengono restituiti è deciso separatamente, quindi non rimborsare i tuoi clienti in base a questo evento.
Notifiche Webhook

Verifica delle richieste webhook

Verifica la firma di iRoamly sulle richieste webhook.

Come verificare la firma di iRoamly?

La firma di iRoamly viene inviata nell’header X-Webhook-Signature della richiesta webhook, come sha256= seguito dalla firma codificata in esadecimale. La firma è generata con l’algoritmo HMAC-SHA256, usando il segreto del webhook come chiave e il corpo grezzo della richiesta (esattamente come ricevuto, prima di qualsiasi parsing JSON) come messaggio.

Header webhook di esempio

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

Trovi il segreto del webhook in Sviluppatori > Notifiche Webhook nella Dashboard.

Pagina Notifiche Webhook della Dashboard: endpoint webhook con il suo URL e il segreto di firma (Mostra), e la cronologia delle consegne

Per generare la firma, puoi usare il seguente frammento di codice:

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

Nel frammento di codice qui sopra, payload è il corpo grezzo della richiesta e secret è il segreto del webhook. Confronta semplicemente la firma generata (incluso il prefisso sha256=) con il valore dell’header X-Webhook-Signature per completare la verifica.

Firma con timestamp (X-Webhook-Signature-V2)

Ogni richiesta contiene anche X-Webhook-Signature-V2: v1= seguito dall’HMAC-SHA256 codificato in esadecimale, con lo stesso segreto del webhook, di {timestamp}.{body}, ovvero il valore dell’header X-Webhook-Timestamp, un punto e il corpo grezzo della richiesta.

Dopo la rotazione del segreto del webhook, il vecchio segreto resta valido per 24 ore. In quel periodo X-Webhook-Signature è ancora firmato con il vecchio segreto e X-Webhook-Signature-V2 contiene un valore per ogni segreto, separati da virgole (v1=<old>,v1=<new>): accetta la richiesta se uno qualsiasi dei valori corrisponde.