Przejdź do treści
iRoamly Shop

Powiadomienia Webhook

Używaj webhooków, aby odbierać w swojej aplikacji wyniki dostarczania kodów QR i odnowień.

Powiadomienia Webhook

Wprowadzenie

Używaj webhooków, aby odbierać w swojej aplikacji wyniki dostarczania kodów QR i odnowień.

Czym jest webhook?

iRoamly wysyła powiadomienia webhook o dostarczeniu kodów QR i wynikach odnowień. Każdy webhook korzysta z HTTPS i zawiera treść JSON. Za pomocą webhooków możesz:

  • Odbierać informacje o kodzie QR po zamianie kodu wymiany lub po zakończeniu bezpośredniego zakupu kodu QR.
  • Odbierać wyniki odnowień przez webhook: esim.renewal.success, gdy kod QR odnowienia jest gotowy, esim.renewal.failed, gdy zamówienie odnowienia u dostawcy nie powiedzie się.

Jeśli Twój endpoint nie odpowie statusem 2xx, iRoamly podejmie łącznie do 5 prób dostarczenia: pierwszą natychmiast, a kolejne po 30 sekundach, 2 minutach, 3 minutach i 5 minutach.

Jak zacząć odbierać webhooki

Aby zacząć odbierać zdarzenia w czasie rzeczywistym w aplikacji, wykonaj następujące kroki:

  • Utwórz lokalny endpoint do odbierania żądań
  • Zarejestruj endpoint webhooka w sekcji Dla programistów > Powiadomienia Webhook w panelu iRoamly Shop

1. Utwórz lokalny endpoint do odbierania żądań

W lokalnej aplikacji utwórz nową trasę przyjmującą żądania POST.

Na przykład możesz dodać trasę API w 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);
  }
};

Po odebraniu zdarzenia odpowiedz statusem HTTP 200 OK, aby zasygnalizować iRoamly, że zdarzenie zostało dostarczone.

2. Zarejestruj deweloperski endpoint webhooka

Zarejestruj publicznie dostępny URL HTTPS w panelu iRoamly Shop.

Możesz utworzyć tunel do serwera localhost za pomocą narzędzia takiego jak ngrok.

Strona Powiadomienia Webhook w panelu z otwartym panelem „Nowy webhook”: pole URL webhooka i status Włączony / Wyłączony

3. Sprawdź, czy endpoint webhooka działa poprawnie

Zamień testowy kod wymiany na kod QR lub dokonaj bezpośredniego zakupu kodu QR, aby sprawdzić, czy endpoint webhooka odbiera zdarzenie.

Powiadomienia Webhook

Typy zdarzeń

Lista obsługiwanych typów zdarzeń i ich treści.

Typ zdarzeniaWysyłane, gdyUwagi
esim.qrcodeKod wymiany został zamieniony na kod QR lub zakończono bezpośredni zakup kodu QR.Bez zmian. isrenew zawsze ma wartość 0.
esim.renewal.successOdnowienie powiodło się i kod QR kodu odnowienia jest gotowy.Nowe. Odnowienia nie wysyłają już esim.qrcode.
esim.renewal.failedOdnowienie nie powiodło się, ponieważ nie udało się złożyć zamówienia u dostawcy.Nowe. Wysyłane tylko przy niepowodzeniu zamówienia u dostawcy.

Dostarczanie

Każde zdarzenie jest dostarczane w ten sam sposób: żądanie POST z treścią JSON do każdego endpointu subskrybującego to zdarzenie. Każda odpowiedź 2xx oznacza dostarczenie; w przeciwnym razie żądanie jest ponawiane, łącznie do 5 prób (pierwsza natychmiast, kolejne po 30 sekundach, 2 minutach, 3 minutach i 5 minutach). Każde żądanie zawiera te nagłówki:

NagłówekOpisTyp
X-Webhook-EventTyp zdarzenia: esim.qrcode, esim.renewal.success lub esim.renewal.failed.String
X-Webhook-DeliveryID dostarczenia.String
X-Webhook-TimestampCzas podpisania żądania, w sekundach Unix.String
X-Webhook-Signaturesha256=, a po nim szesnastkowy HMAC-SHA256 surowej treści żądania.String
X-Webhook-Signature-V2v1=, a po nim szesnastkowy HMAC-SHA256 z "{timestamp}.{body}". Podczas rotacji sekretu zawiera kilka wartości v1= rozdzielonych przecinkami.String

Sposób sprawdzania podpisów opisano w sekcji Weryfikacja żądań webhooka.

esim.qrcode

Informacje o kodzie QR eSIM zwracane po wymianie lub zakupie kodu QR eSIM.

Przykładowa treść żądania

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

esim.renewal.success

Wysyłane, gdy odnowienie się powiedzie: gdy dostawca zwróci dane pobierania zamówienia odnowienia, system wygeneruje kod QR dla kodu odnowienia, a jego status zmieni się na 2 (wymieniony).

Nagłówki żądania

X-Webhook-Event:esim.renewal.success

Żądanie zawiera też X-Webhook-Delivery, X-Webhook-Timestamp, X-Webhook-Signature i X-Webhook-Signature-V2, tak jak każde zdarzenie (zob. Typy zdarzeń).

Przykładowa treść żądania

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

Pola

PoleOpisTyp
codeZawsze 0.Int
event_typeesim.renewal.successString
data.codeNowy kod wymiany wygenerowany dla tego odnowienia. Użyj go z Query QR Code (qrcodeQuery) lub do ponownego odnowienia.String
data.renewal_father_codePierwotny (nadrzędny) kod wymiany, który został odnowiony.String
data.renew_order_idID zamówienia odnowienia u dostawcy.String
data.plan_nameNazwa pakietu odnowienia.String
data.qrcodeURL obrazu kodu QR.String
data.qrcode_contentCiąg LPA; można go zaimportować bezpośrednio.String
data.sm_dp_addressAdres SM-DP+.String
data.activation_codeKod aktywacyjny.String
data.iccidICCID. Może być pusty.String
data.download_urlCiąg pobierania zwrócony przez dostawcę.String
data.create_atCzas utworzenia: czas serwera w formacie YYYY-MM-DD HH:mm:ss.String
data.isrenewZawsze 1.Int
data.iscouldrenewalCzy nowy kod wymiany można ponownie odnowić: 1 - można odnowić 2 - nie można odnowić 3 - wygasłInt
Powiadomienia Webhook

esim.renewal.failed

Wysyłane, gdy odnowienie się nie powiedzie: dostawca odpowie na zamówienie odnowienia kodem innym niż 0000 lub żądanie do dostawcy zakończy się błędem.

(Uwaga: brak lub opóźnienie wywołania zwrotnego od dostawcy nie powoduje tego zdarzenia. Ustaw limit czasu i w razie potrzeby odpytaj kod — zob. Obsługa zdarzeń odnowienia.)

Nagłówki żądania

X-Webhook-Event:esim.renewal.failed

Żądanie zawiera też X-Webhook-Delivery, X-Webhook-Timestamp, X-Webhook-Signature i X-Webhook-Signature-V2, tak jak każde zdarzenie (zob. Typy zdarzeń).

Przykładowa treść żądania

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

Pola

PoleOpisTyp
codeZawsze -1.Int
event_typeesim.renewal.failedString
data.codeKod odnowienia wygenerowany dla tej próby. Nie został aktywowany i nie ma kodu QR.String
data.renewal_father_codePierwotny (nadrzędny) kod wymiany, który miał zostać odnowiony.String
data.plan_nameNazwa pakietu odnowienia.String
data.error_msgBłąd zwrócony przez dostawcę, przydatny przy diagnozowaniu problemów.String
data.create_atCzas utworzenia: czas serwera w formacie YYYY-MM-DD HH:mm:ss.String
data.isrenewZawsze 1.Int
Powiadomienia Webhook

Odnowienia i esim.qrcode

Odnowienia nie są już dostarczane jako esim.qrcode; to zdarzenie jest wysyłane przy zamianach na kody QR i bezpośrednich zakupach kodów QR. W porównaniu z treścią esim.qrcode:

  • event_type i nagłówek X-Webhook-Event mają wartość esim.renewal.success lub esim.renewal.failed, a isrenew ma wartość 1.
  • data.code to nowy kod wymiany utworzony przez odnowienie; odnowiony kod to data.renewal_father_code.
  • esim.renewal.success dodaje renew_order_id, renewal_father_code, iscouldrenewal, download_url i iccid oraz nie zawiera order_id.
  • Nieudane odnowienie jest zgłaszane przez esim.renewal.failed, z code najwyższego poziomu równym -1 i błędem dostawcy w data.error_msg.
Powiadomienia Webhook

Subskrypcje zdarzeń

Nowe endpointy domyślnie subskrybują wszystkie trzy zdarzenia. Istniejące endpointy automatycznie otrzymują esim.renewal.success i esim.renewal.failed — nie trzeba niczego zmieniać.

Powiadomienia Webhook

Obsługa zdarzeń odnowienia

  • Zadbaj o idempotentność obsługi. Ponowienie może dostarczyć to samo zdarzenie więcej niż raz, więc usuwaj duplikaty według X-Webhook-Delivery lub event_type + data.code i ignoruj już przetworzone zdarzenia.
  • Stosuj limit czasu. Jeśli w rozsądnym czasie nie nadejdzie ani esim.renewal.success, ani esim.renewal.failed, odpytaj kod przez API zapytań (np. Query QR Code), zamiast zakładać, że odnowienie się nie powiodło.
  • Nie używaj esim.renewal.failed do decydowania o zwrotach. Zdarzenie informuje jedynie, że zamówienie u dostawcy się nie powiodło; o tym, czy i kiedy kredyty zostaną zwrócone, decyduje się osobno, więc nie zwracaj klientom należności na podstawie tego zdarzenia.
Powiadomienia Webhook

Weryfikacja żądań webhooka

Zweryfikuj podpis iRoamly w żądaniach webhooka.

Jak zweryfikować podpis iRoamly?

Podpis iRoamly jest wysyłany w nagłówku X-Webhook-Signature żądania webhooka jako sha256=, a po nim podpis zakodowany szesnastkowo. Podpis jest generowany algorytmem HMAC-SHA256 z sekretem webhooka jako kluczem i surową treścią żądania (dokładnie w postaci otrzymanej, przed parsowaniem JSON) jako wiadomością.

Przykładowy nagłówek webhooka

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

Sekret webhooka znajdziesz w panelu w sekcji Dla programistów > Powiadomienia Webhook.

Strona Powiadomienia Webhook w panelu: endpoint webhooka z URL i sekretem podpisu (Pokaż) oraz historia dostarczeń

Aby wygenerować podpis, możesz użyć następującego fragmentu kodu:

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

W powyższym fragmencie kodu payload to surowa treść żądania, a secret to sekret webhooka. Wystarczy porównać wygenerowany podpis (wraz z prefiksem sha256=) z wartością nagłówka X-Webhook-Signature, aby zakończyć weryfikację.

Podpis ze znacznikiem czasu (X-Webhook-Signature-V2)

Każde żądanie zawiera też X-Webhook-Signature-V2: v1=, a po nim zakodowany szesnastkowo HMAC-SHA256, z tym samym sekretem webhooka, z {timestamp}.{body} — wartości nagłówka X-Webhook-Timestamp, kropki i surowej treści żądania.

Po rotacji sekretu webhooka stary sekret pozostaje ważny przez 24 godziny. W tym czasie X-Webhook-Signature jest nadal podpisywany starym sekretem, a X-Webhook-Signature-V2 zawiera po jednej wartości dla każdego sekretu, rozdzielone przecinkami (v1=<old>,v1=<new>): zaakceptuj żądanie, jeśli pasuje dowolna wartość.