الرئيسية الربط والمطورون استقبل طلبات زيدا عبر خطاف الويب

استقبل طلبات زيدا عبر خطاف الويب

آخر تحديث في Oct 20, 2026

لمن: المالكون، العمليات
أين تجدها: الإعداد > التكاملات > خطافات الويب، مفاتيح API
متاحة في: لوحة التحكم على الويب · كل الدول

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

أضف خطاف ويب

  1. افتح الإعداد > التكاملات > خطافات الويب في لوحة تحكم زيدا.
  2. اضغط إضافة خطاف وأدخل رابطك.
  3. اختر الأحداث التي تريدها.
  4. اختر أجزاء الطلب التي ترسلها زيدا (انظر «أجزاء الطلب»).
  5. اضغط حفظ، ثم انسخ سر الخطاف. ولا تعرضه زيدا إلا مرة واحدة، فاحفظه على خادمك وحده.

يجب أن يكون أول الرابط https://، وأن يصل إلى عنوان عام، وألا يحمل اسم مستخدم ولا كلمة مرور. وترفض زيدا العنوان الخاص أو الداخلي حين تحفظه. ولا تتبع زيدا عمليات التحويل (redirect).

ومن الصفحة نفسها يستطيع المتجر أن يرسل حدثًا تجريبيًا، ويقرأ سجل الإرسال لآخر 30 يومًا، ويعيد إرسال عملية سابقة، وينشئ سرًا جديدًا (فيتوقف القديم في الحال)، ويوقف الخطاف ويشغله.

إضافة خطاف ويب: العنوان والأحداث المرسلة

أحداث خطافات الويب

الحدث متى ترسله زيدا
order.created عند إرسال الطلب، وهي أول مرة يصل فيها إلى المتجر.
order.status_changed مع كل تغير في الحالة بعد ذلك: accepted وready وdispatched وdelivered وfulfilled وcanceled وreturned وdeleted. وكذلك حين يرجع فريق المتجر الطلب إلى حالة سابقة تصحيحًا.
order.paid حين يصل المال: عند إرسال طلب دفع مقدمًا، أو بعده عند تسجيل دفع أونلاين، أو حين يحدد فريق المتجر أنه استلم المبلغ نقدًا أو بالبطاقة عند التسليم، أو أنه استلم ثمن طلب على الحساب.
order.canceled عند إلغاء الطلب. وترسله زيدا مع حدث order.status_changed الخاص به.

ترسل كل طلبات المتجر أحداثًا، من أي مصدر جاءت، ومنها الطلبات الحية التي أرسلتها بواجهة الطلبات. ولا يرسل شيئًا ما يلي:

  • طلب لم يكتمل إرساله قط، كطلب أونلاين لم يدفعه العميل فانتهت مهلته؛
  • بيع مسجل أرسلته بواجهة الطلبات؛
  • جولة طلب على طاولة في الطلب من الطاولة، لأن العميل يدفع ثمنها على الطاولة.

ولا تضمن زيدا ترتيب وصول عمليات الإرسال، فقد تصل إعادة محاولة بعد حدث أحدث منها. فاستعمل occurred_at وorder.status لتعرف أي الحالات أحدث.

طلب خطاف الويب

ترسل زيدا طلب HTTP من نوع POST بمحتوى JSON.

الترويسة القيمة
Content-Type application/json
User-Agent Zyda-Webhooks/1
X-Zyda-Event اسم الحدث، مثل order.created.
X-Zyda-Delivery معرف عملية الإرسال، وهو أيضًا delivery_id في المحتوى. ولا يتغير في كل إعادة محاولة للعملية نفسها.
X-Zyda-Signature t=<unix seconds>,v1=<signature>. انظر «تحقق من التوقيع».

محتوى خطاف الويب

للأحداث كلها شكل واحد، وهذه نسخته الأولى.

  • order.status هي الحالة التي يتحدث عنها هذا الحدث.
  • order.previous_status هي الحالة التي قبلها. وهي pending في order.created.
  • الأوقات بصيغة ISO 8601، بتوقيت UTC.
  • المبالغ أرقام، بعملة المتجر.
  • لا تكون قيمة test هي true إلا في الحدث التجريبي.

مثال على order.status_changed:

{
  "version": 1,
  "event": "order.status_changed",
  "delivery_id": "6f1c2a9e-0b7d-4c55-9a51-2f0e8d3b7c14",
  "occurred_at": "2026-10-14T10:32:00Z",
  "test": false,
  "store": { "id": 4321, "name": "Sample Store" },
  "order": {
    "id": 880123,
    "number": "1042",
    "status": "accepted",
    "previous_status": "submitted",
    "created_at": "2026-10-14T10:20:05Z",
    "submitted_at": "2026-10-14T10:20:06Z",
    "due_at": "2026-10-14T10:50:06Z",
    "is_scheduled": false,
    "time_slot": null,
    "delivery_type": "pickup",
    "origin": "manual_order",
    "is_manual_order": true,
    "branch": { "id": 101, "name": "Main Branch" },
    "channel": "whatsapp",
    "captured_by": "api",
    "taken_by": "staff",
    "customer": { "name": "Sample Customer", "phone": "+96550000000" },
    "address": {
      "area": null, "city": null, "block": null, "street": null, "avenue": null, "building": null,
      "floor": null, "unit_no": null, "unit_type": null, "notes": null, "lat": null, "lng": null
    },
    "items": [
      {
        "id": 5550001,
        "menu_item_id": "a1b2c3d4-0000-4000-8000-000000000001",
        "variant_id": "123456",
        "name": "Burger patties, 6 pieces",
        "name_ar": null,
        "variant_name": "Regular",
        "quantity": 2,
        "unit_price": 4.75,
        "total_price": 9.5,
        "notes": "Extra fat",
        "options": []
      }
    ],
    "payment": {
      "method": "CASH",
      "status": "paid",
      "cash_collected_at": null,
      "currency": "KWD",
      "subtotal": 9.5,
      "discount": 0.0,
      "voucher_code": null,
      "delivery_fee": 0.0,
      "service_fee": null,
      "tax": 0.0,
      "total": 9.5
    }
  }
}

لا يتغير بين الأحداث إلا event وorder.status وorder.previous_status:

الحدث order.status order.previous_status
order.created submitted pending
order.status_changed الحالة الجديدة الحالة التي قبلها
order.paid حالة الطلب في ذلك الوقت الحالة التي قبلها، إن كان التغيير نفسه قد نقل الحالة. وإلا فهي null.
order.canceled canceled الحالة التي قبلها

ملاحظات على الحقول:

  • channel مفتاح مصدر الطلب، مثل website أو phone أو talabat. انظر «مصادر الطلبات».
  • captured_by النظام الذي سجل الطلب، وهو api في الطلب الذي ترسله أنت.
  • taken_by من أخذ الطلب: customer أو staff أو ring_agent أو ai_agent.
  • كل عنصر في items[].options فيه name وname_ar وquantity وprice.
  • في الدفع نقدًا أو بالبطاقة عند التسليم، قد تكون قيمة payment.status هي paid قبل التحصيل. وتملأ زيدا cash_collected_at وترسل order.paid حين يحدد فريق المتجر أنه استلم المبلغ.
  • يشمل discount القسيمة.
  • قد تكون channel وcaptured_by وtaken_by وcash_collected_at بقيمة null في الطلبات القديمة.

أجزاء الطلب

يستطيع كل خطاف أن يستثني أيًا من هذه الأجزاء: customer (الاسم والهاتف) وaddress وitems وpayment. ويبقى للجزء المستثنى مفاتيحه، لكن قيمة كل منها null، وقيمة items هي []. فلا يتغير شكل المحتوى أبدًا.

تحقق من التوقيع

تحقق من كل طلب قبل أن تثق به.

  1. اقرأ t وv1 من ترويسة X-Zyda-Signature.
  2. كون هذا النص: قيمة t، ثم نقطة، ثم محتوى الطلب الخام كما وصلك تمامًا. مثل 1760437920.{"version":1,...}.
  3. احسب HMAC-SHA256 لهذا النص، واجعل سر الخطاف المفتاح. واكتب النتيجة بالنظام الست عشري بحروف صغيرة.
  4. قارن نتيجتك بقيمة v1 مقارنة ثابتة الزمن. فإن اختلفتا، فارفض الطلب.
  5. ارفض الطلب إذا ابتعد t عن ساعتك أكثر من بضع دقائق. فبهذا تمنع من يعيد إرسال طلب قديم.

استعمل المحتوى الخام. فإذا حللت JSON ثم كتبته من جديد، تغيرت البايتات ولم يعد التوقيع يطابق.

مثال بلغة Node.js (والخطوات السابقة واحدة في كل لغة):

const crypto = require('crypto');

function verifyZydaSignature(rawBody, signatureHeader, secret, toleranceSeconds = 300) {
  const parts = Object.fromEntries(
    String(signatureHeader || '').split(',').map((part) => {
      const at = part.indexOf('=');
      return [part.slice(0, at).trim(), part.slice(at + 1).trim()];
    })
  );
  const t = parts.t;
  if (!t || !parts.v1) return false;
  if (Math.abs(Date.now() / 1000 - Number(t)) > toleranceSeconds) return false;

  const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
  const a = Buffer.from(expected, 'utf8');
  const b = Buffer.from(parts.v1, 'utf8');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

رد سريعًا، وإعادة المحاولة

  • رد بأي حالة 2xx خلال 10 ثوان. وتنتظر زيدا الاتصال 5 ثوان. وأجل الأعمال البطيئة إلى ما بعد الرد، في طابور مثلًا.
  • يرى المتجر أول 2 KB من ردك في سجل الإرسال.
  • إذا انتهت المهلة، أو وقع خطأ في الشبكة، أو جاء رد 5xx أو 429، أعادت زيدا المحاولة بعد دقيقة، ثم 5 دقائق، ثم 15 دقيقة، ثم ساعة، ثم 3 ساعات، ثم 6 ساعات، ثم 14 ساعة: 8 محاولات في نحو يوم.
  • أي رد آخر، ومنه سائر ردود 4xx والتحويل، يفشل عملية الإرسال في الحال. إلا أن تطبيق ويب في Google Apps Script (script.google.com) إذا رد برمز 302 أو 303، عدته زيدا إرسالًا ناجحًا، لأن البرنامج النصي قد عمل. ومع ذلك لا تتبع زيدا التحويل.
  • قد تصلك عملية الإرسال نفسها أكثر من مرة، فأسقط المكرر منها بقيمة X-Zyda-Delivery.
  • بعد 50 عملية إرسال فاشلة متتالية، توقف زيدا الخطاف. ولا تعد العملية فاشلة إلا بعد أن تستنفد محاولاتها. ويشغل المتجر الخطاف مرة أخرى من إرسال الأحداث.

والحدث التجريبي الذي يرسله المتجر من لوحة التحكم فيه "test": true، وdelivery_id أوله test_، وطلب مختلق قيمة id فيه 0 وقيمة number هي TEST-0001.

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