Salla & Zid · Order integration architecture

حالات الطلب في سلة وزد: ابنِ State Machine موحدة وآمنة

نموذج حالات يحفظ حقائق المنصة ويمنح ERP والمستودع والدعم قرارات مشتركة آمنة وقابلة للتفسير.

المسار المرتبطهندسة التجارة الإلكترونية
رسم تقني أصلي يوضح دخول حالات سلة وزد إلى State Machine موحدة مع مسارات مستقلة للدفع والتنفيذ والإرجاع؛ وليس لوحة إنتاج.
تصوّر بصري للفكرة — يتبعه شرح ومخطط تنفيذي داخل المقال.

يجب التعامل مع حالات الطلب في سلة وزد كحقائق مصدرية، لا كأنها Workflow موحد داخل ERP. التكامل الموثوق يحفظ حالة المنصة الأصلية وCustom Sub-status، ثم يربطهما بـCanonical State Machine صغيرة، ويفصل الدفع والتنفيذ والإرجاع إلى محاور مستقلة، ويطابق Webhooks مع قراءات API. بهذه الطريقة لا ينقل Event متأخر أو تغيير اسم حالة مخصصة أو Transition عكسي غير مدعوم الطلب إلى مرحلة تشغيلية خاطئة. يفيد هذا التصميم عند ربط OMS أو ERP أو المستودع أو الشحن أو خدمة العملاء بمتاجر على المنصتين دون محو المعنى الخاص بكل منصة.

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

ابدأ بعقود المنصتين الموثقة

تعيد واجهة List Order Statuses في سلة الحالات الأصلية والحالات أو الحالات الفرعية المخصصة للمتجر. يتضمن الرد الموثق حقولًا مثل id وname وtype وslug وoriginal وchildren. وتقبل واجهة Update Order Status إما slug لحالة معرفة مسبقًا أو status_id لحالة مخصصة؛ لذلك عقد الكتابة ليس اسمًا مترجمًا فقط. كما توفر سلة تاريخ حالات الطلب الذي يعيد الحالات السابقة والحالية لطلب محدد.

توثق زد مجموعة Main Status Codes في Change Order Status، ومنها new وpreparing وready وindelivery وdelivered وcancelled وحالات Reverse. تقبل الواجهة نفسها Custom Status Code، وتوثق قيدًا مهمًا في الشحن: الطلب الذي تعالجه شركة شحن متكاملة لا يعود ببساطة من Ready إلى New. وقد يحتاج الانتقال إلى Ready إلى inventory_address_id حتى تعرف شركة الشحن نقطة الاستلام.

وتوفر زد List Custom Order Statuses. أما Bulk Create/Update فموصوفة كعملية Full Replacement للحالات الفرعية المخصصة. التعامل معها كأنها Patch جزئية قد يحذف حالات تعتمد عليها إجراءات أخرى.

الخلاصة العملية: الاسم للعرض. أما الدليل الذي يعتمد عليه التكامل فهو Provider Code وProvider ID والحالة الأم ومعرف المتجر ونسخة العقد التي تمت ملاحظتها.

افصل أربعة محاور بدل Enum ضخمة

لا تستطيع Enum خطية واحدة تمثيل كل الحقائق دون اختراع Transitions غير منطقية. احتفظ بأربعة محاور مترابطة ومستقلة:

| المحور | قيم نموذجية | المصدر المسؤول | | --- | --- | --- | | دورة الطلب | open، processing، fulfilled، cancelled، closed | حالة الطلب في سلة أو زد | | الدفع | pending، authorized، paid، refunded، voided، unknown | أحداث الدفع والمعاملات | | التنفيذ | unallocated، picking، packed، handed_over، delivered، exception | المستودع والشحنة | | المسار العكسي | none، requested، approved، received، refunded، rejected | Return أو Reverse Order |

قد يكون الطلب مدفوعًا وما يزال Preparing. وقد يصبح Delivered ثم يدخل Reverse Flow. وإلغاء الطلب لا يعني أن المبلغ رُد تلقائيًا. تفصل وثائق Webhooks في زد بين order.status.update وorder.payment_status.update، وتوضح أن unpaid قد تجمع pending وrefunded وvoided. وتنشر سلة أحداثًا منفصلة لـorder.status.updated وorder.payment.updated وorder.cancelled وorder.refunded. هذا الفصل دليل واضح على عدم دمج الدفع والتنفيذ في Field واحدة.

استخدم Canonical Lifecycle فقط للقرارات المشتركة بين الأنظمة، وأبقِ التفاصيل الخاصة بالمنصة بجانبها بدل توسيع Enum عالمية بلا حدود.

ابنِ Mapping بإصدارات لكل متجر

يجب أن يكون Mapping خاصًا بربط المتجر لأن التاجر يستطيع إنشاء الحالات المخصصة وإعادة تسميتها وتعطيلها وتغيير ترتيبها. يمكن أن يبدو السجل الآمن هكذا:

~~~json { "provider": "salla", "store_id": "store_42", "provider_status_id": "1638621685", "provider_slug": "completed", "parent_code": "completed", "canonical_state": "fulfilled", "mapping_version": 7, "observed_at": "2026-10-18T16:40:00Z", "source": "status_catalog" } ~~~

اجعل إصدارات Mapping ثابتة غير قابلة للتعديل. يجب أن يسجل كل Transition رقم الإصدار الذي أنتجها. عندما يغير التاجر Catalog، اقرأها من جديد واحسب Diff واطلب مراجعة عند تغير Parent أو Canonical State. يمكن قبول تغيير الاسم فقط تلقائيًا، لكن نقل Custom Status من Preparing إلى Cancelled يحتاج مراجعة.

لا تربط القيمة المجهولة بأقرب حالة مألوفة. خزّنها كـunmapped، واحتفظ بالـRaw Payload، وأوقف الأتمتة ذات الأثر المدمر، وأنشئ مهمة تشغيلية. unknown أكثر أمانًا من delivered أو refunded أو cancelled كاذبة.

احفظ حقائق المنصة واربطها بسياسة بإصدارات وحدّث محاور الطلب المستقلة قبل إجراءات ERP.
احفظ حقائق المنصة واربطها بسياسة بإصدارات وحدّث محاور الطلب المستقلة قبل إجراءات ERP. اضغط لعرض أكبر

اعتبر Webhook إشعارًا لا Log مرتبة

توثق سلة إعادة المحاولة عندما لا تحصل Webhook على استجابة ناجحة؛ لذلك التكرار متوقع. وتوفر زد Webhooks لحالة الطلب والدفع مع اشتراكات شرطية حسب Status أو Delivery Option أو Payment Method. لا يجوز افتراض أن ترتيب الوصول يساوي ترتيب العمل.

أدخل كل Webhook موثقة في Durable Inbox قبل المعالجة. استخدم Provider Event ID كمفتاح منع تكرار إن توفر، وإلا أنشئ Hash ثابتة من Provider وStore وEvent Type وResource ID وProvider Timestamp وNormalized Payload. أعد الاستجابة بسرعة ثم عالج بصورة غير متزامنة.

لكل Event:

1. تحقق من Signature أو آلية المصادقة الموثقة. 2. خزّن Raw Event ووقت الاستلام. 3. اقرأ Order Projection الحالية وإصدار Mapping. 4. ارفض Transition عكسية مستحيلة إلا إذا سمح بها Workflow الموثق. 5. طبق Event على المحور الصحيح. 6. سجل Transition ومصدرها وCorrelation ID. 7. أضف Read-after-write أو Reconciliation عندما يكون الأثر مهمًا.

مقارنة Timestamp وحدها لا تكفي. قد تختلف ساعات المصدر وتأخير Retry وتعديل Custom Status. استخدم API State كحقيقة المنصة الحالية، واستخدم Event History كدليل يشرح تغير Projection.

للتوسع في نمط الاستقبال المتين، اقرأ Webhooks سلة وزد التي تتحمل الأحداث المفقودة.

ضع Transition Guard أمام كل Write

يجب ألا يستدعي طلب ERP لتعيين Order كـShipped واجهة المنصة مباشرة. حل أولًا المتجر والحالة المصدرية الحالية وCanonical Transition المطلوبة والهدف الخاص بالمنصة والسياق الإلزامي، ثم تحقق أن Transition مسموحة.

~~~text ERP command -> قراءة Store Policy والطلب الحالي من المنصة -> حل Canonical Transition -> اختيار Provider Status أو Custom Status ID -> فحص الدفع وعنوان المخزون ومتطلبات الشحنة -> إرسال Command واحدة Idempotent -> تسجيل Outcome Unknown عند Timeout -> إعادة قراءة المنصة قبل Retry ~~~

يمكن أن يتكون Idempotency Key من Store وOrder والحالة المصدرية المطلوبة وBusiness Command ID. عند Timeout لا تعد الإرسال عميانيًا؛ قد تكون المنصة نفذت Transition وضاعت الاستجابة.

افصل فشل الصلاحيات عن Transition غير الصالحة. 401 مشكلة Credential، و403 مشكلة Scope أو Permission، وValidation Response مشكلة بيانات Command، وTimeout يحتاج Outcome Reconciliation. وضعها كلها في Retry Queue واحدة يكرر الآثار ويخفي أخطاء الإعداد.

طابق Snapshots والتاريخ

تقلل Webhooks زمن التأخير لكنها لا تثبت الاكتمال. شغّل Reconciliation محدودة للطلبات الحديثة والحالات غير النهائية المهمة. اقرأ الطلبات بفلاتر المنصة الموثقة، ثم قارن Provider Facts مع Projection الداخلية.

في سلة يساعد Order History على تفسير حالة حالية مفاجئة. وفي زد يثبت الطلب الحالي وStatus Catalog العقد المشاهد. يجب أن تصلح Reconciliation الـProjection، لا أن تعيد كل Business Side Effect. إذا كشفت Event مفقودة أن الطلب Delivered، حدّث Projection ثم قيّم الإجراءات اللاحقة عبر Records قابلة للتكرار؛ لا ترسل Notification للعميل لمجرد أن Reconciler رأى فرقًا.

استخدم High-water Mark مع Overlap Window، لا شرط last_updated > cursor فقط. تلتقط النافذة Timestamps المتساوية وتأخر الظهور. امنع التكرار بمعرف الطلب المصدر وObserved Version. راقب Reconciliation Lag وMismatch وUnknown Status وRepair Outcome لكل متجر.

الدفع يحتاج Ledger بدل Status Overwrite؛ يشرحه مقال Salla Payment Reconciliation. ويجب فصل الشحنة بالطريقة نفسها؛ راجع Salla Shipment State Machine.

عامل Custom Status كمخطط بيانات

Catalog الحالات المخصصة Schema إعدادات. صدّر الحالة الحالية، واحسب Desired Diff، وحدد كل Automation وReport وNotification وRole تشير إلى كل Status. لا تستخدم الاسم المترجم كـForeign Key.

في سلة احفظ Numeric Status IDs وSlugs وعلاقة Original Parent. وفي زد عامل Bulk Create/Update كـFull Replacement: أرسل كل الحالات التي يجب أن تبقى، وتحقق من ملكية IDs، ثم قارن Catalog المرجعة بعد الكتابة.

نفذ التغيير أولًا على Test Store أو Workflow منخفضة المخاطر. جمّد Status Catalog Writes أثناء Migration أو استخدم Optimistic Version Check حتى لا تستبدل Control Plane تغييرات أخرى. احتفظ بالنسخة الكاملة السابقة وإصدار Mapping للـRollback.

متى لا تقُد Canonical Model القرار

تفيد Canonical Model في Analytics متعددة المنصات، وWarehouse Queues، وERP Orchestration، وشاشات الدعم. لكنها لا تتجاوز قواعد المنصة الأصلية. تبقى سلة وزد مصدر الحقيقة للـTransitions التي يفرضها Checkout أو Shipping أو Return System.

لا تستخدم الحالة الموحدة لاختلاق Provider Transition غير مدعومة. ولا تعِد تسمية Custom Status فقط كي تبدو المتاجر متطابقة. ولا تسجل Refunded لأن Order ألغيت، أو Delivered لأن Carrier طبع Label. احفظ كل حقيقة عند حدود مصدرها.

لمتجر واحد بلا OMS خارجي قد لا تحتاج طبقة Normalization معقدة. يمكن أن تكفي Durable Inbox مع Provider Codes وترجمة صغيرة للتقارير. أضف Canonical Model عندما تحتاج أنظمة متعددة قرارًا مشتركًا، لا لأن الرسم المعماري يصبح أنظف.

راقب التكامل كـControl Plane

قس Webhook Age وDuplicate Rate وStatus Catalog Drift وعدد Unmapped Status ومحاولات Transition غير الصالحة وWrite Outcome Unknown وReconciliation Mismatch وRepair Latency. أنشئ Audit Record تحتوي Actor وCommand ID والحقائق القديمة والجديدة وCanonical Transition وإصدار Mapping والمصدر.

أنشئ Alert عندما تعود Terminal Provider State إلى ERP Queue نشطة، أو تتعارض محاور الدفع والطلب، أو تختفي Custom Status، أو يجمع متجر قيمًا مجهولة. يجب أن تعرض Dashboard حالة المنصة والحالة الموحدة ووقت آخر تحقق، حتى لا يعامل الدعم Projection قديمة كحقيقة مباشرة.

قائمة الإنتاج

اكتشف Status Catalog لكل متجر. خزّن Provider IDs وCodes وParents وLabels. استخدم Versioned Mappings واعزل القيم المجهولة. افصل Order وPayment وFulfilment وReverse Flows. خزّن Webhooks في Durable Inbox واجعل Consumers قابلة للتكرار. احرس Writes بالحالة الحالية ومتطلبات المنصة. أعد القراءة بعد Outcome مجهولة. طابق الطلبات الحديثة غير النهائية بنافذة Overlap. عامل Custom Status Replacement كـSchema Migration. سجل كل Transition واختبر Rollback.

الهدف ليس إجبار سلة وزد على Vocabulary واحدة؛ بل تمكين ERP أو OMS من اتخاذ قرارات مشتركة آمنة مع الحفاظ على حقائق المنصة الدقيقة اللازمة لتفسير كل طلب والتعافي منه ومتابعته.

المراجع الرسمية

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

إعداد: Noor Yasser

من القرار إلى التنفيذ

تعمل على تحدٍ تقني مشابه؟

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

احجز لقاءً لمدة ٣٠ دقيقةالخدمة المرتبطةهندسة الأنظمة الخلفية وتكاملات APIمشروع من الأعمالمنصة اللوجستيات