Webhook URL
نظرة عامة
توصل هذه الميزة بيانات الفاتورة المدفوعة إلى خادم التاجر. وهي موجودة كي يعالج متجر التاجر الدفع تلقائيًا ويسلّم المنتج أو الخدمة إلى مشتريك.
يُحدد Webhook URL لكل مشروع على حدة ويشير إلى نصوص معالج الدفع داخل متجر التاجر. يجب أن يستخدم العنوان HTTPS واسم نطاق: لا تُقبل عناوين IP، وتتحقق الخدمة من الشهادة عند كل تسليم.
في كل مرة تتغير فيها حالة الفاتورة إلى مدفوعة (Paid)، ترسل الخدمة طلب POST إلى هذا الرابط بالصيغة الآتية:
{
"wallet":{
"id":"47aa71e2-07a0-482e-9172-7114d7376ba0",
"name":"usdt-tron",
"blockchain":"tron",
"cryptocurrency":"usdt",
"address":"TKbstUwMzLrfTAGL4erYb7gc7ghmHQ9zG7"
},
"project":{
"id":"9deea1e2-0c08-41a3-bdc2-a34eada3892d",
"name":"My project",
"commissionPayer":"seller",
"commissionRate":1
},
"invoice":{
"id":"a4c9e2ee-9a03-43e5-a1a1-00caf679d16a",
"uid":"AFhygKX21ecd",
"createDatetime":"2024-02-26 13:29:24",
"timeToPayDatetime":"2024-02-27 01:29:24",
"commissionFiatUSD":0.05,
"amountFiatUSD":5.02,
"amountFiat":5,
"calcAmountFiat":5.02,
"currencyFiat":"USD",
"description":null,
"serviceData":null,
"status":"paid"
},
"payment":{
"id":"f986ad8d-2298-473d-982a-efbc817b975d",
"amount":5.02,
"hash":"74763b65e43bcc9492a6ce9a7f26fbfdbd7635aecd3454420b5e9534cba50ee6",
"transactionDatetime":"2024-02-26 13:32:57"
}
}
يُرسل الإشعار عند كل انتقال إلى الحالة مدفوعة — سواء وجدت الخدمة الدفعة تلقائيًا أو ربط التاجر الدفعة بالفاتورة يدويًا.
معطيات الطلب
| المعطى | الوصف |
|---|---|
wallet.id | معرّف المحفظة بصيغة UUID |
wallet.name | اسم المحفظة |
wallet.blockchain | بلوكتشين المحفظة المشفرة |
wallet.cryptocurrency | العملة المشفرة للمحفظة |
wallet.address | عنوان المحفظة المشفرة |
project.id | معرّف المشروع بصيغة UUID |
project.name | اسم المشروع |
project.commissionPayer | من يدفع عمولة الخدمة |
project.commissionRate | التعرفة بالنسبة المئوية |
invoice.id | معرّف الفاتورة بصيغة UUID |
invoice.uid | معرّف الفاتورة (للمشتري) |
invoice.createDatetime | تاريخ ووقت إنشاء الفاتورة (UTC) |
invoice.timeToPayDatetime | التاريخ والوقت اللذان تبقى الفاتورة صالحة للمشتري حتى حلولهما (UTC). يستمر البحث عن الدفعات ساعة إضافية بعد هذه العلامة — مراعاةً للشبكات البطيئة. لذلك قد يصل إشعار عن فاتورة كانت تُعرض بالفعل منتهية الصلاحية |
invoice.commissionFiatUSD | مبلغ عمولة الخدمة. يُحسب من المبلغ invoice.amountFiatUSD |
invoice.amountFiatUSD | المبلغ بـ USD. عند إنشاء الفاتورة يُحسب من invoice.amountFiat بسعر الصرف الحالي. وعند الدفع تستبدله الخدمة بالمبلغ المستلم فعليًا محوَّلًا إلى USD بسعر تلك اللحظة. وتُحسب العمولة في invoice.commissionFiatUSD من جديد بناءً عليه أيضًا |
invoice.amountFiat | مبلغ الفاتورة الأصلي بالعملة الورقية. لا يتغير |
invoice.calcAmountFiat | المبلغ المحسوب بعملة invoice.currencyFiat بسعر صرف العملة المشفرة لحظة الدفع. قد يختلف عن invoice.amountFiat لأن المشتري ربما دفع الفاتورة بعد إنشائها بوقت لا فورًا. وخلال ذلك الوقت قد يتحرك سعر العملة المشفرة مقابل invoice.currencyFiat في أي اتجاه |
invoice.currencyFiat | العملة الورقية |
invoice.description | الوصف المحدد عند إنشاء الفاتورة |
invoice.serviceData | البيانات الخدمية المحددة عند إنشاء الفاتورة |
invoice.status | حالة الفاتورة |
payment.id | معرّف الدفعة بصيغة UUID |
payment.amount | مبلغ الدفعة بالعملة المشفرة |
payment.hash | hash المعاملة على السلسلة |
payment.transactionDatetime | تاريخ ووقت المعاملة على السلسلة (UTC) |
توقيع الإشعار
يُوقَّع كل طلب بالمفتاح السري للـ Webhook. ينتقل التوقيع في الترويستين X-Timestamp وX-Signature ويتيح لك التأكد من أن الإشعار جاء من الخدمة، لا من غريب عرف عنوان معالجك.
تحقق من التوقيع قبل معالجة الطلب. الآلية والأمثلة الجاهزة في قسم التحقق من توقيع الـ Webhook.
توصيات المعالجة
لا ترفض إشعارًا لأن مهلة الدفع انقضت. تحقق مثل «الفاتورة منتهية الصلاحية، فالدفعة باطلة» يبدو منطقيًا لكنه يقطع حصة من الدفعات الحقيقية: على الشبكات البطيئة قد تتأكد المعاملة بعد المهلة، ويستطيع التاجر ربط دفعة بفاتورة منتهية الصلاحية يدويًا. الإشعار نفسه يؤكد الدفع.
تحقق من المبلغ مقابل الحقل الأصلي invoice.amountFiat. هذا هو مبلغ الفاتورة كما صدرت، وهو لا يتغير. أما الحقل amountFiatUSD فيعكس المبلغ المستلم فعليًا وقد يختلف عن الصادر — بسبب حركة سعر الصرف وبسبب الربط اليدوي للدفعات معًا.
حلّل المبالغ كأرقام. تُحذف الأصفار الأخيرة: المبلغ 10.00 يصل بالشكل 10؛ فنسّقه من جهتك للعرض. والمبالغ الأدنى من 0.0001 تصل بالترميز الأسي، مثلًا 1.0e-6 — تحليل JSON القياسي يعيد الرقم الصحيح؛ ولا ينكسر إلا التحليل اليدوي للسلاسل النصية.
عالج الإشعارات بشكل idempotent. قد يصل الإشعار نفسه مرة أخرى — مثلًا إذا عالج نصك الدفع بنجاح لكنه أعاد رمزًا غير 2xx. قبل تسليم الطلب تحقق مما إذا كان هذا invoice.id قد عولج بالفعل.
هرّب القيم عند الإخراج. يعود الحقلان invoice.description وinvoice.serviceData تمامًا كما أرسلهما التاجر. فإذا عرضتهما في HTML، فهرّبهما من جهتك.
جدول التسليم
يجب أن يستجيب الخادم على Webhook URL برمز HTTP من فئة 2xx. أي رمز آخر أو انتهاء مهلة أو انقطاع اتصال يُعد تسليمًا فاشلًا.
لا تتبع الخدمة عمليات إعادة التوجيه: الاستجابة 301 أو 302 تسليم فاشل، لا قفزة إلى العنوان الجديد. حدّد العنوان النهائي للمعالج.
يُسمح للاتصال بـ 5 ثوانٍ، وللطلب كاملًا بـ 10 ثوانٍ. وإذا لم يكتف المعالج بذلك، يُعد التسليم فاشلًا.
بعد تسليم فاشل تعيد الخدمة المحاولة على الجدول الآتي:
- بعد 5 دقائق من آخر تسليم فاشل
- بعد 15 دقيقة
- بعد 30 دقيقة
- بعد ساعة
- بعد 3 ساعات
- بعد 6 ساعات
- بعد 12 ساعة
- بعد 24 ساعة
بعد ذلك تتوقف محاولات التسليم.
تعطيل Webhook URL
أحيانًا يعالج نص الـ webhook في المتجر الدفع معالجة صحيحة لكنه يعيد رمز HTTP غير 2xx. يؤدي هذا إلى إعادة محاولات متكررة من خادمنا على الجدول أعلاه، فيضع حملًا إضافيًا على خادمنا وخادمك معًا.
لمنع هذه الحالات لدينا آلية تعطّل Webhook URL في المشروع. لتفاديها اتخذ الخطوات الآتية:
- غيّر كود معالج الـ webhook لديك بحيث يعيد رمزًا من فئة 2xx، عادة 200، عند نجاح معالجة الدفع. اختبره بأي محاكٍ، مثلًا Postman.
- تواصل مع الدعم الفني لتصحيح الإعدادات.
- أعد تفعيل Webhook URL في إعدادات المشروع واحفظ المشروع.