Langsung ke konten
iRoamly Shop

Notifikasi Webhook

Gunakan webhook untuk menerima hasil pengiriman kode QR dan perpanjangan di aplikasi Anda.

Notifikasi Webhook

Pendahuluan

Gunakan webhook untuk menerima hasil pengiriman kode QR dan perpanjangan di aplikasi Anda.

Apa itu webhook?

iRoamly mengirimkan notifikasi webhook untuk hasil pengiriman kode QR dan perpanjangan. Setiap webhook menggunakan HTTPS dan menyertakan payload JSON. Gunakan webhook untuk:

  • Menerima informasi kode QR setelah kode penukaran dikonversi atau pembelian kode QR langsung selesai.
  • Terima hasil perpanjangan melalui webhook: esim.renewal.success saat kode QR perpanjangan siap, esim.renewal.failed saat pesanan perpanjangan di penyedia hulu gagal.

Jika endpoint Anda tidak merespons dengan status 2xx, iRoamly melakukan hingga 5 kali percobaan pengiriman secara total: yang pertama segera, lalu dicoba ulang setelah 30 detik, 2 menit, 3 menit, dan 5 menit.

Langkah-langkah menerima webhook

Anda dapat mulai menerima event secara real-time di aplikasi Anda dengan langkah-langkah berikut:

  • Buat endpoint lokal untuk menerima permintaan
  • Daftarkan endpoint webhook Anda di Developer > Notifikasi Webhook pada Dasbor iRoamly Shop

1. Buat endpoint lokal untuk menerima permintaan

Di aplikasi lokal Anda, buat route baru yang dapat menerima permintaan POST.

Misalnya, Anda dapat menambahkan API route di 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);
  }
};

Saat menerima event, Anda harus merespons dengan HTTP 200 OK untuk memberi tahu iRoamly bahwa event berhasil dikirim.

2. Daftarkan endpoint webhook pengembangan Anda

Daftarkan URL HTTPS Anda yang dapat diakses publik di Dasbor iRoamly Shop.

Anda dapat membuat tunnel ke server localhost menggunakan alat seperti ngrok.

Halaman Notifikasi Webhook di Dasbor dengan panel “Webhook baru” terbuka: kolom URL webhook dan status Aktif / Nonaktif

3. Uji apakah endpoint webhook Anda berfungsi dengan baik

Konversi kode penukaran uji menjadi kode QR, atau lakukan pembelian kode QR langsung, untuk memastikan endpoint webhook Anda menerima event.

Notifikasi Webhook

Jenis Event

Daftar jenis event yang didukung beserta payload-nya.

Jenis eventDikirim saatCatatan
esim.qrcodeKode penukaran telah dikonversi menjadi kode QR, atau pembelian kode QR langsung telah selesai.Tidak berubah. isrenew selalu 0.
esim.renewal.successPerpanjangan berhasil dan kode QR dari kode perpanjangan sudah siap.Baru. Perpanjangan tidak lagi mengirim esim.qrcode.
esim.renewal.failedPerpanjangan gagal karena pesanan di penyedia hulu tidak dapat dibuat.Baru. Hanya dikirim untuk kegagalan pesanan di penyedia hulu.

Pengiriman

Setiap event dikirim dengan cara yang sama: permintaan POST dengan body JSON ke setiap endpoint yang berlangganan event tersebut. Respons 2xx apa pun dianggap terkirim; jika tidak, permintaan dicoba ulang, hingga total 5 kali percobaan (yang pertama segera, lalu dicoba ulang setelah 30 detik, 2 menit, 3 menit, dan 5 menit). Setiap permintaan membawa header berikut:

HeaderDeskripsiTipe
X-Webhook-EventJenis event: esim.qrcode, esim.renewal.success, atau esim.renewal.failed.String
X-Webhook-DeliveryID pengiriman.String
X-Webhook-TimestampWaktu permintaan ditandatangani, dalam detik Unix.String
X-Webhook-Signaturesha256= diikuti HMAC-SHA256 heksadesimal dari body permintaan mentah.String
X-Webhook-Signature-V2v1= diikuti HMAC-SHA256 heksadesimal dari "{timestamp}.{body}". Selama rotasi secret, header ini memuat beberapa nilai v1= yang dipisahkan koma.String

Lihat Verifikasi Permintaan Webhook untuk cara memeriksa tanda tangan.

esim.qrcode

Informasi terkait kode QR eSIM yang dikembalikan setelah penukaran atau pembelian kode QR eSIM.

Contoh Body Permintaan

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

esim.renewal.success

Dikirim saat perpanjangan berhasil: setelah penyedia hulu mengembalikan detail unduhan pesanan perpanjangan, sistem membuat kode QR untuk kode penukaran perpanjangan dan status-nya menjadi 2 (Sudah ditukarkan).

Header Permintaan

X-Webhook-Event:esim.renewal.success

Permintaan ini juga membawa X-Webhook-Delivery, X-Webhook-Timestamp, X-Webhook-Signature, dan X-Webhook-Signature-V2, seperti setiap event lainnya (lihat Jenis Event).

Contoh Body Permintaan

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

Field

FieldDeskripsiTipe
codeSelalu 0.Int
event_typeesim.renewal.successString
data.codeKode penukaran baru yang dibuat untuk perpanjangan ini. Gunakan dengan Kueri Kode QR (qrcodeQuery), atau untuk memperpanjang lagi.String
data.renewal_father_codeKode penukaran asli (induk) yang diperpanjang.String
data.renew_order_idID pesanan perpanjangan di penyedia hulu.String
data.plan_nameNama paket perpanjangan.String
data.qrcodeURL gambar kode QR.String
data.qrcode_contentString LPA; dapat diimpor langsung.String
data.sm_dp_addressAlamat SM-DP+.String
data.activation_codeKode aktivasi.String
data.iccidICCID. Dapat kosong.String
data.download_urlString unduhan yang dikembalikan oleh penyedia hulu.String
data.create_atWaktu pembuatan: waktu server, dalam format YYYY-MM-DD HH:mm:ss.String
data.isrenewSelalu 1.Int
data.iscouldrenewalApakah kode penukaran baru dapat diperpanjang lagi: 1 - dapat diperpanjang 2 - tidak dapat diperpanjang 3 - kedaluwarsaInt
Notifikasi Webhook

esim.renewal.failed

Dikirim saat perpanjangan gagal: penyedia hulu menjawab pesanan perpanjangan dengan kode selain 0000, atau permintaan ke penyedia gagal.

(Catatan: Callback dari penyedia hulu yang tidak ada atau terlambat tidak memicu event ini. Tetapkan batas waktu dan beralih ke kueri kode — lihat Menangani Event Perpanjangan.)

Header Permintaan

X-Webhook-Event:esim.renewal.failed

Permintaan ini juga membawa X-Webhook-Delivery, X-Webhook-Timestamp, X-Webhook-Signature, dan X-Webhook-Signature-V2, seperti setiap event lainnya (lihat Jenis Event).

Contoh Body Permintaan

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

Field

FieldDeskripsiTipe
codeSelalu -1.Int
event_typeesim.renewal.failedString
data.codeKode perpanjangan yang dibuat untuk percobaan ini. Kode ini tidak diprovisikan dan tidak memiliki kode QR.String
data.renewal_father_codeKode penukaran asli (induk) yang akan diperpanjang.String
data.plan_nameNama paket perpanjangan.String
data.error_msgKesalahan yang dikembalikan oleh penyedia hulu, untuk pemecahan masalah.String
data.create_atWaktu pembuatan: waktu server, dalam format YYYY-MM-DD HH:mm:ss.String
data.isrenewSelalu 1.Int
Notifikasi Webhook

Perpanjangan dan esim.qrcode

Perpanjangan tidak lagi dikirim sebagai esim.qrcode; event tersebut dikirim untuk konversi kode QR dan pembelian kode QR langsung. Dibandingkan dengan payload esim.qrcode:

  • event_type dan header X-Webhook-Event bernilai esim.renewal.success atau esim.renewal.failed, dan isrenew bernilai 1.
  • data.code adalah kode penukaran baru yang dibuat oleh perpanjangan; kode yang diperpanjang adalah data.renewal_father_code.
  • esim.renewal.success menambahkan renew_order_id, renewal_father_code, iscouldrenewal, download_url, dan iccid, serta tidak memiliki order_id.
  • Perpanjangan yang gagal dilaporkan oleh esim.renewal.failed, dengan code tingkat atas -1 dan kesalahan dari penyedia hulu di data.error_msg.
Notifikasi Webhook

Langganan Event

Endpoint baru secara default berlangganan ketiga event. Endpoint yang sudah ada menerima esim.renewal.success dan esim.renewal.failed secara otomatis — tidak perlu perubahan apa pun.

Notifikasi Webhook

Menangani Event Perpanjangan

  • Buat handler Anda idempoten. Percobaan ulang dapat mengirim event yang sama lebih dari sekali, jadi hapus duplikat berdasarkan X-Webhook-Delivery atau event_type + data.code, dan abaikan event yang sudah Anda proses.
  • Gunakan cadangan batas waktu. Jika esim.renewal.success maupun esim.renewal.failed tidak tiba dalam waktu yang wajar, kueri kode tersebut dengan API kueri (misalnya Kueri Kode QR) alih-alih menganggap perpanjangan gagal.
  • Jangan gunakan esim.renewal.failed untuk memutuskan pengembalian dana. Event ini hanya melaporkan bahwa pesanan di penyedia hulu gagal; apakah dan kapan kredit dikembalikan diputuskan secara terpisah, jadi jangan mengembalikan dana pelanggan Anda berdasarkan event ini.
Notifikasi Webhook

Verifikasi Permintaan Webhook

Verifikasi tanda tangan iRoamly pada permintaan webhook.

Bagaimana cara memverifikasi tanda tangan iRoamly?

Tanda tangan iRoamly dikirim di header X-Webhook-Signature pada permintaan webhook, sebagai sha256= diikuti tanda tangan berenkode heksadesimal. Tanda tangan dibuat menggunakan algoritma HMAC-SHA256 dengan webhook secret sebagai kunci, dan body permintaan mentah (persis seperti yang diterima, sebelum parsing JSON apa pun) sebagai pesan.

Contoh Header Webhook

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

Anda dapat menemukan webhook secret di Developer > Notifikasi Webhook pada Dasbor.

Halaman Notifikasi Webhook di Dasbor: endpoint webhook dengan URL dan signing secret-nya (Tampilkan), serta riwayat pengiriman

Untuk membuat tanda tangan, Anda dapat menggunakan cuplikan kode berikut:

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

Pada cuplikan kode di atas, payload adalah body permintaan mentah, dan secret adalah webhook secret. Cukup bandingkan Signature yang dihasilkan (termasuk awalan sha256=) dengan nilai header X-Webhook-Signature untuk menyelesaikan proses verifikasi.

Tanda tangan bertimestamp (X-Webhook-Signature-V2)

Setiap permintaan juga membawa X-Webhook-Signature-V2: v1= diikuti HMAC-SHA256 berenkode heksadesimal, dengan webhook secret yang sama, dari {timestamp}.{body} — nilai header X-Webhook-Timestamp, sebuah titik, dan body permintaan mentah.

Setelah Anda merotasi webhook secret, secret lama tetap berlaku selama 24 jam. Selama periode tersebut, X-Webhook-Signature masih ditandatangani dengan secret lama, dan X-Webhook-Signature-V2 memuat satu nilai per secret, dipisahkan koma (v1=<old>,v1=<new>): terima permintaan jika ada nilai yang cocok.