إنتقل إلى المحتوى الرئيسي

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.hashhash المعاملة على السلسلة
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 في المشروع. لتفاديها اتخذ الخطوات الآتية:

  1. غيّر كود معالج الـ webhook لديك بحيث يعيد رمزًا من فئة 2xx، عادة 200، عند نجاح معالجة الدفع. اختبره بأي محاكٍ، مثلًا Postman.
  2. تواصل مع الدعم الفني لتصحيح الإعدادات.
  3. أعد تفعيل Webhook URL في إعدادات المشروع واحفظ المشروع.