إشعارات Webhook
استخدم Webhooks لاستقبال نتائج تسليم رموز QR والتجديد في تطبيقك.
مقدمة
استخدم Webhooks لاستقبال نتائج تسليم رموز QR والتجديد في تطبيقك.
ما هو Webhook؟
يرسل iRoamly إشعارات Webhook بنتائج تسليم رموز QR والتجديد. يستخدم كل Webhook بروتوكول HTTPS ويتضمن حمولة JSON. استخدم Webhooks من أجل:
- استقبال معلومات رمز QR بعد تحويل رمز استرداد أو إتمام شراء رمز QR مباشرةً.
- استقبال نتائج التجديد عبر Webhook:
esim.renewal.successعندما يصبح رمز QR للتجديد جاهزًا، وesim.renewal.failedعند فشل طلب التجديد لدى المزوّد.
إذا لم تستجب نقطة النهاية بحالة 2xx، يجري iRoamly ما يصل إلى 5 محاولات تسليم إجمالًا: الأولى فورًا، ثم إعادة المحاولة بعد 30 ثانية، ودقيقتين، و3 دقائق، و5 دقائق.
خطوات استقبال Webhook
يمكنك البدء في استقبال الأحداث في الوقت الفعلي في تطبيقك باتباع الخطوات التالية:
- أنشئ نقطة نهاية محلية لاستقبال الطلبات
- سجّل نقطة نهاية Webhook ضمن المطوّرون > إشعارات Webhook في لوحة تحكم iRoamly Shop
1. أنشئ نقطة نهاية محلية لاستقبال الطلبات
في تطبيقك المحلي، أنشئ مسارًا جديدًا يمكنه قبول طلبات POST.
على سبيل المثال، يمكنك إضافة مسار API في 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);
}
};عند استقبال حدث، يجب أن تستجيب بـ HTTP 200 OK لإبلاغ iRoamly بأن الحدث قد سُلّم بنجاح.
2. سجّل نقطة نهاية Webhook للتطوير
سجّل عنوان HTTPS URL المتاح للعامة في لوحة تحكم iRoamly Shop.
يمكنك إنشاء نفق إلى خادم localhost باستخدام أداة مثل ngrok.

3. اختبر أن نقطة نهاية Webhook تعمل بشكل صحيح
حوّل رمز استرداد تجريبيًا إلى رمز QR، أو اشترِ رمز QR مباشرةً، للتحقق من أن نقطة نهاية Webhook تستقبل الحدث.
أنواع الأحداث
قائمة بأنواع الأحداث المدعومة وحمولاتها.
التسليم
يُسلَّم كل حدث بالطريقة نفسها: طلب POST بنص JSON إلى كل نقطة نهاية مشتركة في الحدث. تُعد أي استجابة 2xx تسليمًا ناجحًا؛ وإلا تُعاد المحاولة، بما يصل إلى 5 محاولات إجمالًا (الأولى فورًا، ثم إعادة المحاولة بعد 30 ثانية، ودقيقتين، و3 دقائق، و5 دقائق). يحمل كل طلب الترويسات التالية:
راجع التحقق من طلبات Webhook لمعرفة كيفية التحقق من التوقيعات.
esim.qrcode
المعلومات المتعلقة برمز QR لـ eSIM التي تُرجع بعد استرداد رمز QR لـ eSIM أو شرائه.
نموذج لنص الطلب
{
"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
يُرسَل عند نجاح التجديد: بعد أن يُرجع المزوّد تفاصيل التنزيل لطلب التجديد، يُنشئ النظام رمز QR لرمز التجديد، وتصبح قيمة status الخاصة به 2 (تم الاسترداد).
ترويسات الطلب
esim.renewal.successيحمل الطلب أيضًا X-Webhook-Delivery وX-Webhook-Timestamp وX-Webhook-Signature وX-Webhook-Signature-V2، كما هو الحال في كل حدث (راجع أنواع الأحداث).
نموذج لنص الطلب
{
"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"
}الحقول
esim.renewal.failed
يُرسل عند فشل التجديد: عندما يردّ المزوّد على طلب التجديد برمز غير 0000، أو عند فشل الطلب المرسل إلى المزوّد.
(ملاحظة: لا يؤدي غياب الاستدعاء من المزوّد أو تأخره إلى إطلاق هذا الحدث. اضبط مهلة زمنية وارجع إلى الاستعلام عن الرمز — راجع التعامل مع أحداث التجديد.)
ترويسات الطلب
esim.renewal.failedيحمل الطلب أيضًا X-Webhook-Delivery وX-Webhook-Timestamp وX-Webhook-Signature وX-Webhook-Signature-V2، كما هو الحال في كل حدث (راجع أنواع الأحداث).
نموذج لنص الطلب
{
"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"
}الحقول
عمليات التجديد وesim.qrcode
لم تعد عمليات التجديد تُسلَّم كـ esim.qrcode؛ إذ يُرسل هذا الحدث لعمليات التحويل إلى رمز QR وعمليات شراء رموز QR المباشرة. مقارنةً بحمولة esim.qrcode:
- قيمة
event_typeوترويسةX-Webhook-Eventهيesim.renewal.successأوesim.renewal.failed، وقيمةisrenewهي1. data.codeهو رمز الاسترداد الجديد الذي أنشأه التجديد؛ والرمز الذي تم تجديده هوdata.renewal_father_code.- يضيف
esim.renewal.successالحقولrenew_order_idوrenewal_father_codeوiscouldrenewalوdownload_urlوiccid، ولا يحتوي علىorder_id. - يُبلَّغ عن التجديد الفاشل عبر
esim.renewal.failed، معcodeفي المستوى الأعلى بقيمة-1وخطأ المزوّد فيdata.error_msg.
الاشتراك في الأحداث
تُشترك نقاط النهاية الجديدة في الأحداث الثلاثة جميعها افتراضيًا. وتستقبل نقاط النهاية الحالية esim.renewal.success وesim.renewal.failed تلقائيًا — دون الحاجة إلى أي تغيير.
التعامل مع أحداث التجديد
- اجعل المعالج متساوي القوة (idempotent). قد تؤدي إعادة المحاولة إلى تسليم الحدث نفسه أكثر من مرة، لذا أزل التكرار حسب
X-Webhook-Deliveryأو حسبevent_type+data.code، وتجاهل الأحداث التي عالجتها بالفعل. - استخدم آلية احتياطية بمهلة زمنية. إذا لم يصل
esim.renewal.successولاesim.renewal.failedخلال وقت معقول، فاستعلم عن الرمز باستخدام واجهة الاستعلام (مثل Query QR Code) بدلًا من افتراض فشل التجديد. - لا تعتمد على
esim.renewal.failedلتقرير عمليات الاسترداد. فهو يُبلغ فقط بفشل الطلب لدى المزوّد؛ أما إعادة الرصيد وتوقيتها فيُقرَّران بشكل منفصل، لذا لا تُعِد المبالغ إلى عملائك بناءً على هذا الحدث.
التحقق من طلبات Webhook
تحقّق من توقيع iRoamly على طلبات Webhook.
كيف تتحقق من توقيع iRoamly؟
يُرسل توقيع iRoamly في ترويسة X-Webhook-Signature لطلب Webhook، على شكل sha256= متبوعة بالتوقيع المرمّز بالنظام الست عشري. يُنشأ التوقيع باستخدام خوارزمية HMAC-SHA256 مع سر Webhook كمفتاح، ونص الطلب الخام (كما استُلم تمامًا، قبل أي تحليل لـ JSON) كرسالة.
نموذج لترويسة Webhook
{
'X-Webhook-Signature': 'sha256=dd7bdd2cf1f6bac6e171c6c508c157b7cd3cc1fd196394277fb59ba0bdd9b87b'
}يمكنك العثور على سر Webhook ضمن المطوّرون > إشعارات Webhook في لوحة التحكم.

لإنشاء التوقيع، يمكنك استخدام مقتطف التعليمات البرمجية التالي:
import * as crypto from 'crypto';
generateSignature(payload: string, secret: string): string {
const computedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return 'sha256=' + computedSignature;
}في مقتطف التعليمات البرمجية أعلاه، payload هو نص الطلب الخام، وsecret هو سر Webhook. ما عليك سوى مقارنة التوقيع المُنشأ (بما في ذلك البادئة sha256=) بقيمة ترويسة X-Webhook-Signature لإكمال عملية التحقق.
التوقيع المختوم زمنيًا (X-Webhook-Signature-V2)
يحمل كل طلب أيضًا X-Webhook-Signature-V2: v1= متبوعة بقيمة HMAC-SHA256 المرمّزة بالنظام الست عشري، باستخدام سر Webhook نفسه، لـ {timestamp}.{body} — أي قيمة ترويسة X-Webhook-Timestamp، ثم نقطة، ثم نص الطلب الخام.
بعد تدوير سر Webhook، يظل السر القديم صالحًا لمدة 24 ساعة. خلال تلك الفترة، يظل X-Webhook-Signature موقّعًا بالسر القديم، ويحمل X-Webhook-Signature-V2 قيمة واحدة لكل سر، مفصولة بفواصل (v1=<old>,v1=<new>): اقبل الطلب إذا تطابقت أي قيمة.