الويب هوك
تتيح الويب هوك لمنصة Logistall أن تدفع تغييرات حالة الشحنات إلى نقطة النهاية الخاصة بك بدل أن تستطلع /v1/shipments دوريًا. وهي منفصلة عن واجهة القراءة /v1/* — فالاشتراكات تُدار داخل تطبيق Logistall على الويب، لا عبر استدعاء API عام.
الاشتراك
Section titled “الاشتراك”تُنشأ اشتراكات الويب هوك من قسم الويب هوك في صفحة مفاتيح API (الصفحة نفسها التي تنشئ فيها مفاتيح API — انظر المصادقة والأسئلة الشائعة في دليل المستخدم). إضافة اشتراك تطلب منك:
- رابط النقطة — حيث سيرسل Logistall حمولة الحدث عبر
POST. - الحدث — يوجد حاليًا نوع حدث واحد فقط:
shipment.status_changed. - Secret (اختياري) — يُستخدم لتوقيع التسليمات كي تتحقق من أنها صادرة عن Logistall. يُنصح به بشدة؛ فمن دونه تُرسل التسليمات غير موقَّعة.
يمكن حذف الاشتراكات من الصفحة نفسها، ما يوقف التسليمات المستقبلية إلى ذلك الرابط.
يُطلق shipment.status_changed كلما تغيّر حقل status لشحنة عبر التطبيق (مثلًا، عندما ينقل موزع شحنات أو سائق شحنةً من pickup_scheduled إلى in_transit).
الحمولة
Section titled “الحمولة”{ "event": "shipment.status_changed", "tenantId": "7f2a1c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d", "shipmentId": "3f1c9c2a-6b3e-4b3a-9b2d-1a2b3c4d5e6f", "shipmentNumber": "SHP-00482", "oldStatus": "pickup_scheduled", "newStatus": "in_transit", "at": "2026-07-13T09:15:00.000Z"}قيمة Content-Type هي application/json.
التحقق من التوقيع
Section titled “التحقق من التوقيع”إذا كان لاشتراكك سر مضبوط، فإن كل تسليم يتضمن:
X-Logistall-Signature: sha256=<hex-encoded HMAC-SHA256>التوقيع هو HMAC-SHA256 على متن الطلب الخام بالضبط (نص JSON كما أُرسل، لا نسخة معاد تسلسلها منه)، بمفتاح هو سر الويب هوك الخاص بك. احسب HMAC نفسه من جهتك وقارن.
// Node.js (Express) example. Requires the RAW request body as a string/Buffer —// re-stringifying a parsed JSON object can reorder keys and break the comparison.const crypto = require('crypto');
function verifyLogistallSignature(rawBody, signatureHeader, secret) { if (!signatureHeader || !signatureHeader.startsWith('sha256=')) return false;
const expected = crypto .createHmac('sha256', secret) .update(rawBody) .digest('hex');
const provided = signatureHeader.slice('sha256='.length);
const a = Buffer.from(expected, 'hex'); const b = Buffer.from(provided, 'hex'); if (a.length !== b.length) return false;
return crypto.timingSafeEqual(a, b);}
// Express route — use express.raw() (not express.json()) so req.body is a Buffer.app.post( '/webhooks/logistall', express.raw({ type: 'application/json' }), (req, res) => { const ok = verifyLogistallSignature( req.body, req.header('X-Logistall-Signature'), process.env.LOGISTALL_WEBHOOK_SECRET ); if (!ok) return res.status(401).send('Invalid signature');
const event = JSON.parse(req.body.toString('utf8')); // ... handle event ... res.status(200).end(); });إذا لم يكن لاشتراكك سر مضبوط، فإن التسليمات تُرسل من دون الترويسة X-Logistall-Signature — ولا شيء للتحقق منه.
إعادة المحاولة
Section titled “إعادة المحاولة”لكل محاولة تسليم مهلة 5 ثوانٍ. إذا فشلت (خطأ شبكة أو انتهاء مهلة أو استجابة من غير فئة 2xx)، يعيد Logistall المحاولة حتى 3 محاولات إجمالًا لذلك التسليم، مع تأخير قصير قبل المحاولتين الثانية والثالثة (نحو 200 ملّي ثانية ثم 800 ملّي ثانية). فإذا فشلت المحاولات الثلاث كلها، يُوسم التسليم بأنه غير ناجح ولا تُعاد محاولته بعد ذلك — لا توجد إعادة تسليم مجدولة بعد تلك النافذة.
ينبغي لنقطة نهايتك أن تستجيب سريعًا بحالة من فئة 2xx فور قبولها الحدث قبولًا دائمًا؛ ونفّذ المعالجة الأثقل بشكل غير متزامن خارج معالج الطلب، كي لا تصطدم بمهلة الثواني الخمس.
سجلات التسليم
Section titled “سجلات التسليم”كل محاولة تسليم (الرابط ورمز الحالة المستلَم وعدد المحاولات والنجاح/الفشل وآخر خطأ إن وُجد) تُسجَّل داخليًا على الاشتراك. وحتى كتابة هذه السطور لا توجد صفحة في التطبيق ولا نقطة نهاية API لعرض ذلك السجل بنفسك — فإذا بدا أن تسليمًا ما يفشل، فراجع سجلات نقطة نهايتك أنت، أو تواصل معنا مزوّدًا برابط الاشتراك والوقت التقريبي ليُفحص الأمر من جهة الخادم.