ربط API الدفع بالعملات الرقمية: الفواتير والتواقيع والـ Webhooks

شرح عملي للمطورين: طلب واحد موقّع لإنشاء فاتورة، ونقطة webhook واحدة لاستقبال الحالة، وتفاصيل الأمان التي تجعل التكامل جديرًا بالثقة.

تم التحديث: قراءة 5 دقائق
ربط API الدفع بالعملات الرقمية: طلب POST موقّع ينشئ فاتورة واستجابة webhook

يحتاج ربط API الدفع بالعملات الرقمية إلى جزأين: طلب من جهة الخادم ينشئ فاتورة لكل طلب شراء ويعيد رابط صفحة الدفع، ونقطة webhook تستقبل تحديثات حالة موقّعة عندما تُرصد الدفعة وتتأكد على البلوكشين. في mistKET كلاهما مجرد HTTPS وJSON، موقّعان بـ HMAC-SHA256، دون الحاجة إلى أي SDK.

يشرح هذا الدليل المسار الكامل مع أمثلة كود، ثم يتناول تفاصيل الأمان والموثوقية التي تفصل بين نسخة تجريبية ونظام جاهز للإنتاج.

البنية في صورة واحدة

كل عملية ربط لـ API الدفع بالعملات الرقمية تتبع الحلقة نفسها المكوّنة من خمس خطوات:

  1. إنشاء الطلب — يستدعي الخادم الخلفي لديك POST /api/v1/invoices مع المبلغ والعملة ورقم الطلب ورابط الـ callback.
  2. التحويل — توجّه العميل إلى checkout_url المُعاد.
  3. الدفع — يختار العميل الشبكة ويدفع في الصفحة المستضافة؛ ويُثبَّت سعر الصرف طوال مدة صلاحية الفاتورة.
  4. الـ Webhook — يرسل mistKET طلب POST يحمل invoice.paid أو invoice.confirmed أو حدثًا استثنائيًا إلى رابط الـ callback لديك.
  5. التنفيذ — تتحقق من التوقيع، وتعلّم الطلب بأنه مدفوع، وتسلّم المنتج.

يُصدر مفتاح الـ API وسرّ الـ API وسرّ الـ webhook في لوحة التاجر بعد الموافقة على حسابك. والمرجع الكامل موجود في اللوحة ضمن قسم API.

الخطوة 1: وقّع طلب الفاتورة وأرسله

يحمل كل طلب API ثلاث ترويسات (headers). التوقيع هو HMAC-SHA256 بصيغة hex للسلسلة {timestamp}.{raw body} باستخدام سرّ الـ API لديك:

POST /api/v1/invoices
X-Api-Key: mp_live_…
X-Api-Timestamp: 1760000000
X-Api-Signature: hex(hmac_sha256("{ts}.{body}", secret))

{
  "amount": "184.50",
  "currency": "USD",
  "order_id": "2041",
  "callback_url": "https://yourstore.com/webhooks/mistket"
}

هكذا تبدو نسخة PHP مختصرة:

$body = json_encode([
  'amount' => '184.50', 'currency' => 'USD',
  'order_id' => '2041',
  'callback_url' => 'https://yourstore.com/webhooks/mistket',
]);
$ts  = (string) time();
$sig = hash_hmac('sha256', $ts . '.' . $body, $apiSecret);
// send $body with X-Api-Key, X-Api-Timestamp, X-Api-Signature

وقّع البايتات نفسها تمامًا التي ترسلها. إعادة ترميز JSON بعد التوقيع (بمسافات مختلفة أو ترتيب مفاتيح مختلف) هي السبب الأول لأخطاء التوقيع.

الخطوة 2: التحويل إلى صفحة الدفع المستضافة

عند نجاح الاستدعاء تحصل على 201 Created مع معرّف UUID للفاتورة وحالتها (new) ورابط checkout_url. خزّن الـ UUID مع طلبك ثم وجّه العميل. تعرض الصفحة المستضافة المبلغ الدقيق ورمز QR وعدّادًا تنازليًا والحالة المباشرة، وتعمل على الهاتف. يختار العملاء الشبكة هناك — USDT على TRON أو BNB Smart Chain أو Ethereum أو Arbitrum، إضافة إلى TRX وBNB وETH — ما لم تثبّت الشبكة في استدعاء الـ API.

إلى جانب إنشاء الفواتير، يتيح لك الـ API عرض قائمتها وجلب تفاصيلها وإلغاءها، وهذا مفيد عندما تتغير سلة الشراء أو يتخلى العميل عن الطلب.

الخطوة 3: استقبال الـ Webhooks والتحقق منها

عندما تتغير الحالة، يرسل mistKET طلب POST يحمل JSON إلى رابط الـ callback لديك مع هذه الترويسات:

الترويسةالغرض
X-Mistket-Eventاسم الحدث، مثل invoice.confirmed
X-Mistket-Timestampوقت Unix المستخدم في التوقيع
X-Mistket-Signaturesha256= + توقيع HMAC-SHA256 للسلسلة {timestamp}.{raw body} باستخدام سرّ الـ webhook
X-Mistket-Deliveryمعرّف التسليم، مفيد للتسجيل في السجلات

التحقق بلغة PHP:

$raw = file_get_contents('php://input');
$ts  = $_SERVER['HTTP_X_MISTKET_TIMESTAMP'] ?? '';
$got = $_SERVER['HTTP_X_MISTKET_SIGNATURE'] ?? '';
$exp = 'sha256=' . hash_hmac('sha256', $ts . '.' . $raw, $webhookSecret);
if (!hash_equals($exp, $got) || abs(time() - (int) $ts) > 300) {
  http_response_code(401); exit;
}
$event = json_decode($raw, true);

استخدم مقارنة ثابتة الزمن (hash_equals في PHP، وhmac.compare_digest في Python، وcrypto.timingSafeEqual في Node.js)، وارفض الطوابع الزمنية القديمة لمنع هجمات إعادة الإرسال. وللاطلاع على خلفية هذه الآلية، راجع RFC 2104 (HMAC).

الخلاصة: الـ webhook — لا عودة متصفح العميل إلى موقعك — هو مصدر الحقيقة. لا تعلّم أي طلب بأنه مدفوع دون توقيع صالح.

مثال على محتوى الـ Webhook

تصل الدفعة المؤكدة كمستند JSON مختصر. الحقول التي ستستخدمها أكثر من غيرها هي الحدث ورقم طلبك والحالة والمبلغان المتوقع والمستلم:

POST https://yourstore.com/webhooks/mistket
X-Mistket-Event: invoice.confirmed
X-Mistket-Signature: sha256=…

{ "event": "invoice.confirmed", "data": {
  "order_id": "2041", "status": "confirmed",
  "pay_amount": "184.5", "paid_amount": "184.5",
  "pay_currency": "USDT", "network": "TRC20" } }

خزّن pay_currency وnetwork مع الطلب، فهما مفيدان للمحاسبة ولمحادثات الدعم لاحقًا.

التحقق في Node.js وPython

الفحص نفسه بلغتين شائعتين أخريين:

// Node.js (Express with express.raw for this route)
const exp = 'sha256=' + crypto.createHmac('sha256', secret)
  .update(ts + '.' + rawBody).digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(exp), Buffer.from(sig));

# Python
exp = 'sha256=' + hmac.new(secret.encode(), f'{ts}.{raw}'.encode(),
                           hashlib.sha256).hexdigest()
ok = hmac.compare_digest(exp, sig)

في الحالتين، تأكد من قراءة جسم الطلب الخام. كثير من أطر العمل تحلّل JSON تلقائيًا، وبعد التحليل وإعادة التسلسل لا تعود البايتات مطابقة للتوقيع.

الاختبار محليًا

تحتاج الـ webhooks إلى رابط HTTPS عام، لذلك لا يستطيع حاسوبك المحمول استقبالها مباشرة. هناك خياران عمليان: انشر المعالج على خادم تجريبي (staging) مبكرًا، أو اكشف المنفذ المحلي مؤقتًا عبر أداة أنفاق (tunnelling). أنشئ فواتير صغيرة تشير إلى رابط الـ callback التجريبي، ثم افحص سجلات التسليم في لوحة التاجر لترى بالضبط ما الذي أُرسل وبماذا ردّ خادمك.

حاول تفعيل كل نوع من الأحداث مرة واحدة على الأقل أثناء الاختبار: paid وconfirmed وunderpaid وexpired. عندما يعمل كل فرع من فروع المعالج مع webhook حقيقي، لا يتبقى إلا القليل مما قد يفاجئك في بيئة الإنتاج، وستعرف بالضبط كيف تبدو سجلات التسليم عندما يحدث خطأ ما.

الخطوة 4: معالجة كل حالة من حالات الدفع

يتضمن محتوى الـ webhook رقم الطلب والحالة والمبلغ المتوقع (pay_amount) والمبلغ المستلم (paid_amount) والعملة والشبكة. اربط كل حدث بإجراء:

الحدثالمعنىالإجراء المعتاد
invoice.paidرُصد التحويل والتأكيدات قيد الانتظاراعرض «تم استلام الدفعة، جارٍ التأكيد»
invoice.confirmedاكتمل عدد التأكيدات المطلوبعلّم الطلب مدفوعًا ونفّذه
invoice.underpaidالمبلغ أقل من هامش التسامحانتظر إكمال الدفع أو تواصل مع العميل
invoice.overpaidالمبلغ أكثر من المتوقعنفّذ الطلب وقرّر بشأن الفرق
invoice.expiredلم تصل دفعة صالحة في الوقت المحددحرّر المخزون واترك الطلب غير مدفوع

يتولى mistKET هامش التسامح للدفع الناقص، والدفعات الجزئية التي تُجمع حتى الإجمالي، والدفعات المتأخرة ضمن مهلة السماح؛ أما الكود لديك فيتفاعل فقط مع النتيجة النهائية.

الموثوقية: إعادة المحاولة وعدم التكرار

إذا كانت نقطة الاستقبال لديك متوقفة أو أعادت خطأ، تُعاد محاولة إرسال الـ webhooks مع فواصل متزايدة لساعات. هذا يعني أنك قد تستقبل الحدث نفسه مرتين أحيانًا. اجعل المعالج عديم التكرار (idempotent) بالاعتماد على رقم الطلب:

  • ردّ برمز 2xx بسرعة، ثم عالج المهام الثقيلة في طابور (queue).
  • قبل التنفيذ، تحقّق مما إذا كان الطلب معلَّمًا بأنه مدفوع مسبقًا.
  • سجّل معرّف التسليم والحدث لتتمكن من تتبع المشكلات؛ كما تعرض اللوحة سجلات تسليم الـ webhooks.

قائمة التحقق الأمنية لـ API الدفع

ربط API الدفع بالعملات الرقمية يتعامل مع المال، فتعامل معه كما تتعامل مع أي كود دفع آخر:

  • أبقِ سرّ الـ API وسرّ الـ webhook على الخادم فقط، ولا تضعهما أبدًا في كود الواجهة الأمامية أو تطبيقات الهاتف.
  • قيّد الوصول إلى الـ API عبر قائمة عناوين IP المسموح بها في اللوحة.
  • ارفض الطلبات التي تقع خارج نافذة زمنية قصيرة للطابع الزمني.
  • اضبط مدة صلاحية الفاتورة بما يتوافق مع منطق حجز المخزون لديك.
  • تعامل مع المبالغ كسلاسل نصية أو أعداد عشرية دقيقة (decimal)، لا كأعداد عائمة (float).
نصيحة: قبل الإطلاق، ادفع فاتورة صغيرة بنفسك، وأرسل مبلغًا ناقصًا عمدًا لترى مسار الدفع الناقص، واترك فاتورة واحدة تنتهي صلاحيتها. بذلك تكون قد اختبرت كل الفروع في أقل من ساعة.

إلى أين بعد ذلك

هذا هو ربط API الدفع بالعملات الرقمية كاملًا: طلب واحد موقّع، وwebhook واحد موثّق، وخريطة للحالات. وللاطلاع على المسار نفسه من منظور غير المطورين، اقرأ كيفية قبول الدفع بالعملات الرقمية على موقعك. هل تبني بوتًا بدلًا من موقع؟ راجع قبول الدفع بالعملات الرقمية في بوت تيليجرام. اطلب مفاتيح الـ API بتقديم طلبك عبر Telegram @mistnetwork، واطّلع على المثال في قسم المطورين، وأدِر مفاتيحك عبر تسجيل دخول التاجر.

الأسئلة الشائعة

هل أحتاج إلى SDK لربط API الدفع بالعملات الرقمية؟
ليس مع mistKET. فهو يستخدم HTTPS وJSON ببساطة؛ وأي لغة برمجة قادرة على إرسال طلب HTTP وحساب HMAC-SHA256 يمكنها إتمام الربط.
كيف تتم مصادقة طلبات API في mistKET؟
يرسل كل طلب X-Api-Key وX-Api-Timestamp وX-Api-Signature، حيث التوقيع هو HMAC-SHA256 بصيغة hex للسلسلة '{timestamp}.{raw body}' باستخدام سرّ الـ API لديك.
كيف أتحقق من webhook الدفع بالعملات الرقمية؟
أعد حساب HMAC-SHA256 للسلسلة '{timestamp}.{raw body}' باستخدام سرّ الـ webhook، وقارنه مع X-Mistket-Signature بمقارنة ثابتة الزمن، وارفض الطوابع الزمنية القديمة.
ماذا لو فاتَ خادمي استقبال webhook؟
تُعاد محاولة إرسال الـ webhooks مع فواصل متزايدة لساعات، ويمكنك أيضًا جلب حالة الفاتورة عبر الـ API. اجعل المعالج عديم التكرار بالاعتماد على رقم الطلب.
هل يمكنني فرض شبكة محددة عبر الـ API؟
نعم. يمكنك تثبيت الشبكة في استدعاء الـ API؛ وإلا فيختارها العميل في صفحة الدفع المستضافة.
ما الأحداث التي يجب أن تؤدي إلى تنفيذ الطلب؟
نفّذ الطلب عند invoice.confirmed. استخدم invoice.paid لعرض التقدم فقط، وتعامل مع أحداث underpaid وoverpaid وexpired وفق سياستك.

مقالات ذات صلة