Fiatside

Developers

الخطافات

يخبرك webhook أن طلبًا تغيرت حالته. لا يحل محل قراءة الطلب: إنه إشعار، وليس مصدر حقيقة.

عقد منشور، غير مفتوح بعد

لا يتم إصدار webhooks اليوم. شكله وتوقيعه وسياسة إعادة المحاولة محددة ومنشورة هنا حتى يمكن كتابة جهاز الاستقبال الخاص بك واختباره مسبقًا.

01

الأحداث

يحمل كل حدث نفس الغلاف: معرف، ونوع، وطابع زمني، وكائن بيانات. اشترك في الأنواع التي تتعامل معها وتجاهل الباقي بصمت — ستتم إضافة أنواع جديدة، والمستقبل الذي يفشل على نوع غير معروف يكسر نفسه.

الأحداث
النوعماذا يعني
order.createdتم إنشاء الطلب وتثبيت السعر. تم تعيين عنوان الإيداع.
order.deposit_detectedتظهر معاملة واردة على الشبكة، قبل التأكيد. استخدم هذا الحدث لطمأنة المستخدم، ولا تسلم أي شيء أبدًا.
order.confirmingعداد التأكيد يتقدم. يُصدر عند كل خطوة، وليس عند كل كتلة.
order.deposit_confirmedتم الوصول إلى عدد التأكيدات المطلوب من قبل الشبكة.
order.underpaidالمبلغ المستلم أقل من المبلغ المتوقع بما يتجاوز التسامح. الطلب ليس مفقودًا: إنه ينتظر الاختيار بين إضافة المبلغ، أو المتابعة بالمبلغ المستلم، أو استرداد الأموال.
order.overpaidالمبلغ المستلم يتجاوز المبلغ المتوقع. يبقى المبلغ الأولي بالسعر المثبت؛ يتم التعامل مع الزيادة بشكل منفصل.
order.payout_sentغادر التحويل عبر قناة الدفع. انتبه: الإرسال ليس استلامًا — يعتمد التأخير المتبقي على بنك المستفيد.
order.completedتم تأكيد التسوية من قبل قناة الدفع. حالة نهائية.
order.payout_failedرفضت قناة الدفع التحويل أو أعادته، مع ذكر السبب. لا تتم إعادة المحاولة تلقائيًا عند إرجاع بنكي: السبب دائمًا تقريبًا في التفاصيل.
order.refundedتم إرجاع الأموال، فقط إلى العنوان الأصلي، صافية من رسوم الشبكة.
02

الحمولة

غلاف ثابت، مهما كان النوع.

مثالjson
{
  "id": "evt_01J9ZQF3K8N2M4X7",
  "type": "order.payout_sent",
  "created": 1788356981,
  "data": {
    "reference": "K7Q4-M2XB",
    "state": "PAYOUT_SENT",
    "railId": "sepa_instant",
    "netMinor": 91228,
    "currency": "EUR",
    "sentAt": "2026-09-02T12:21:44Z"
  }
}
03

التوقيع

يحمل كل تسليم رأس توقيع: طابع زمني وHMAC-SHA256 محسوب على ذلك الطابع الزمني، ونقطة، ونص الطلب الخام.

Fiatside-Signaturehttp
Fiatside-Signature: t=<timestamp unix>,v1=<hex hmac-sha256>
التحقق، Node.jstypescript
import { createHmac, timingSafeEqual } from 'node:crypto'

// IMPORTANT : le corps doit etre le corps BRUT, avant tout parsing JSON.
// Re-serialiser l'objet change l'ordre des cles et invalide la signature.
export function verify(rawBody: string, header: string, secret: string): boolean {
  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=') as [string, string]))
  const timestamp = Number(parts['t'])
  const signature = parts['v1']
  if (!timestamp || !signature) return false

  // Rejeu : une signature valide capturee hier ne doit pas etre rejouable aujourd'hui.
  if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false

  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex')
  const a = Buffer.from(expected, 'hex')
  const b = Buffer.from(signature, 'hex')
  // Comparaison a temps constant : un === laisse fuiter la signature octet par octet.
  return a.length === b.length && timingSafeEqual(a, b)
}
  • وقع النص الخام، قبل أي تحليل. إعادة تسلسل كائن JSON تغير ترتيب المفاتيح والمسافات: لن يتطابق التوقيع بعد ذلك، وستبحث لفترة طويلة.
  • قارن في وقت ثابت. مقارنة === تتوقف عند أول بايت مختلف، مما يسمح للمهاجم بقياس التوقيع المتوقع بايتًا بايت.
  • ارفض ما بعد نافذة التسامح البالغة 300 ثانية. بدون هذا الفحص، يظل طلب صالح تم التقاطه بالأمس قابلاً لإعادة التشغيل اليوم.
  • أجب بـ 200 قبل المعالجة. ضع الحدث في قائمتك وتعامل معه بعد ذلك: المعالجة الطويلة تؤدي إلى مهلة وبالتالي إعادة محاولة، حتى لو كنت قد استلمت الحدث.
04

إعادة المحاولة والترتيب

أي حالة غير 2xx، أو عدم وجود استجابة على الإطلاق، تؤدي إلى إعادة محاولة وفق الجدول أدناه.

إعادة المحاولة والترتيب
المحاولةالتأخير
1فوري
230 s
32 min
410 min
51 h
66 h
  • ترتيب الوصول غير مضمون. قد يصل حدث دفع قبل حدث التأكيد الذي يسبقه منطقيًا: ثق بحالة الطلب، وليس بترتيب الاستلام.
  • يمكن أن يصل نفس الحدث مرتين. قم بتخزين معرف الحدث وتجاهل المعرف الذي تمت معالجته بالفعل: التكرارية (idempotency) على جهاز الاستقبال الخاص بك هي مسؤوليتك، ومن السهل تحقيقها.
  • لا تثق أبدًا بمبالغ الحمولة (payload) لاعتماد أي شيء على جانبك. أعد قراءة الطلب عبر API: الحمولة تقول أن شيئًا ما حدث، وAPI يحدد بالضبط ما حدث.
  • بعد المحاولة الأخيرة، يتم إسقاط الحدث ويبقى مرئيًا في سجل الأحداث الخاص بك. يمكنك إعادة تشغيله يدويًا.