تحتاج مزامنة كتالوج سلة وزد الموثوقة إلى سجل هوية وSnapshot للحالة المطلوبة ومسار مصالحة، لا Loop ينسخ الصفوف حسب SKU ويحذف كل ما يغيب. اعتبر Product ID الخاص بكل منصة هوية Remote، وSKU مفتاحًا تجاريًا يستطيع التاجر تعديله، واحتفظ بتاريخ Aliases المرصودة. حوّل المنتجات المفقودة إلى Tombstones، واعزلها للمراجعة، ثم نفّذ حذفًا موثقًا فقط عندما تسمح الملكية والسياسة. يساعد هذا التصميم تكاملات ERP وPIM والأسواق على تجنب المنتجات المكررة والقوائم القديمة وفقد الكتالوج بالخطأ.
توفر الواجهات الرسمية Primitives مفيدة، لكنها لا تحدد الحقيقة المشتركة بين الأنظمة. توثق سلة القراءة والتحديث والحذف حسب SKU، وتوثق زد قائمة منتجات مقسمة إلى صفحات للمزامنة الكاملة وتحديثات جماعية حسب IDs أو SKUs. هذه عقود نقل، أما قواعد الملكية وتغير الهوية وحل التعارض والحذف فهي مسؤولية التطبيق.
تم التحقق من توثيق سلة وزد الرسمي في 12 أكتوبر 2026. المسارات والصلاحيات وأشكال الاستجابة المذكورة حقائق موثقة، بينما Ledger وTombstones والحجر وخطة الإطلاق توصيات هندسية لا ادعاء بأن المنصتين تنفذانها تلقائيًا.
افصل الهوية عن SKU
للمنتج معرفات متعددة بمعانٍ مختلفة. يجب أن يملك ERP أو PIM معرفًا ثابتًا مثل `catalog_item_id`. وتمنح سلة وزد كل منتج Remote ID خاصًا. أما SKU وBarcode وSlug فهي خصائص تجارية قابلة للتعديل أو إعادة الاستخدام. لذلك اربط كل اتصال بـTenant والمنصة وRemote ID، وخزّن SKU الحالي وتاريخه كصفات.
catalog_item_id platform remote_product_id current_sku state
item_01HZX... salla 1672908878 SHIRT-BLU-M active
item_01HZX... zid a497974d-... SHIRT-BLU-M active
SKU aliases
item_01HZX... SHIRT-BLUE-M valid_to=2026-09-30
item_01HZX... SHIRT-BLU-M valid_to=nullيعيد مسار Product Details By SKU في سلة منتجًا عبر `/products/sku/{sku}`، ويقبل مسار التحديث SKU في الرابط والـPayload. هذا مريح لكنه لا يجعل SKU ثابتًا. إذا عدّل التاجر SKU بين القراءة والكتابة فقد ينشئ Job Mapping ثانية أو يعدّل سجلًا خاطئًا. استخدم Remote Product ID كهوية مخزنة عندما يدعمه المسار المطلوب، واجعل البحث بالـSKU وسيلة اكتشاف أو إصلاح تتطلب تطابقًا واحدًا واضحًا.
ارفض SKUs النشطة المكررة داخل التاجر والقناة نفسها إلا إذا كان العمل يسمح بها صراحة. طبّع Case والمسافات والترقيم للمقارنة فقط واحتفظ بالقيمة الأصلية المرسلة. تعارض التطبيع يدخل المراجعة ولا يدمج منتجين بصمت.
حدّد مالك كل حقل
تفشل المزامنة عندما يستطيع كل نظام الكتابة فوق كل حقل. حدّد مالكًا واحدًا للسعر والكمية والعنوان والوصف والوسائط والضريبة والشحن وحالة النشر. قد يملك ERP المخزون والتكلفة بينما يملك فريق التاجر المحتوى المحلي داخل سلة أو زد. يجب أن يحدّث التكامل الحقول التي يملكها فقط.
خزّن Desired-state Document وHash لكل مجموعة حقول مملوكة. في كل تشغيل قارن الحالة المطلوبة بآخر Remote State مؤكدة، وأرسل Patch فقط عند تغير قيمة مملوكة. لا ترسل Product Object كاملًا لمجرد أن المسار يقبله؛ فالحقول القديمة في Payload واسعة قد تمحو تعديلًا حديثًا للتاجر.
يسمح Update Product في زد بتعديل البيانات الأساسية والمخزون والVariants. تجعل هذه المرونة Ownership Matrix ضرورية. إذا كان التكامل يملك السعر والكمية فقط فيجب أن يحتوي Payload على هاتين القيمتين، وأن يسجل Audit سبب الكتابة.
استخدم Snapshots للمسح الكامل
تقلل Webhooks وUpdated-since Queries زمن التأخير، لكن الكتالوج يحتاج Full Reconciliation دورية. قد تتأخر الأحداث أو تضيع أثناء تغيير Credentials أو Webhooks. وتذكر زد صراحة المزامنة الكاملة كاستخدام لمسار List Products المقسم إلى صفحات والذي يعيد Next Link.
أنشئ `sync_run` بوقت بدء ثابت ونسخة اتصال وRun ID. اتبع عقد Pagination حتى النهاية ولا تخترع أرقام صفحات بعد أن تعيد الواجهة Next Link. نفّذ Upsert لكل Remote Identity داخل Staging Snapshot وسجّل `last_seen_run_id`. لا تعتبر التشغيل مكتملًا ولا تقارنه بالـSnapshot السابقة إلا بعد نجاح كل الصفحات. المسح الجزئي لا يسمح بأي حذف.
STARTED -> SCANNING -> COMPLETE -> DIFFED -> APPLIED
|
+-------> FAILED (no absence decisions)إذا تغير الكتالوج أثناء قراءة الصفحات فقد ترى Snapshot مختلطة زمنيًا. استخدم Ordering أو Cursors الموثقة إن توفرت، وإلا اعتبر المسح دليلًا لا Database Snapshot: أعد قراءة العنصر المستهدف قبل أي إجراء تدميري، ودع التشغيل التالي يحقق التقارب.
حوّل الغياب إلى Tombstone لا Delete
قد يعني غياب منتج من مسح مكتمل أنه حُذف أو أُلغي نشره أو أخفاه Scope جديد أو تعطل Pagination أو نُقل إلى متجر آخر. سجّل Tombstone Candidate مع السبب وأول Run غاب فيها وآخر حالة وOwnership. لا تدخله Destructive Queue قبل اجتياز السياسة.
يمكن للسياسة أن تطلب مسحين كاملين ناجحين بينهما وقت، وفحص Credential حديثًا، وعدم وجود Webhook حديث متعارض، وتأكيد أن Upstream Item متقاعد فعلًا. المنتجات مرتفعة القيمة أو المرتبطة بطلبات حديثة تحتاج اعتمادًا يدويًا. وقد تحتاج العناصر المستخدمة داخل Variants أو Bundles أو طلبات نشطة إلى Unpublish بدل الحذف.
يوفر Quarantine قابلية الرجوع: أوقف Outbound Updates، وحوّل المنتج إلى Draft أو Unavailable عندما يسمح عقد المنصة والملكية، واحتفظ بالMapping. Hard Delete يزيل مسار التعافي وقد يكسر Historical Joins، لذلك لا تستخدمه إلا إذا فرضته سياسات الاحتفاظ والقانون والتاجر.
اجعل الكتابات Idempotent وقابلة للمراقبة
يحتاج كل Outbound Operation إلى Operation ID مشتق من Tenant والعنصر وDesired Version والفعل. خزّن Request Hash والهدف والمحاولة والاستجابة ونتيجة التحقق. إعادة المحاولة بالهوية نفسها لا تنشئ فعلًا منطقيًا جديدًا. نفّذ Serialize للكتابات على كل Product Mapping حتى لا تستبدل استجابة قديمة بطيئة تحديثًا أحدث.
في سلة يستخدم Update Product By SKU طلب `PUT /products/sku/{sku}` مع صلاحية `products.read_write`. قبل إعادة محاولة Timeout غامض اقرأ المنتج وقارن الحقول المملوكة بالنسخة المطلوبة. إذا تطابقت فاعتبر العملية مؤكدة. وإذا لم يعد SKU موجودًا فابحث في Mapping History قبل التفكير في Create.
في تحديثات زد الجماعية، يوصي توثيق Bulk Update Products بألا يتجاوز الطلب 50 IDs أو SKUs لأن الأحجام الأكبر قد تسبب مشكلات معالجة. اعتبر 50 حدًا موثقًا لا Batch Size مستهدفة. اختر حجمًا أصغر وConcurrency عبر الاختبار، واعزل الفشل، وتحقق من كل Product عائد بدل اعتبار Source Batch كلها ناجحة.
صالح قبل الحذف وبعده
توثق سلة `DELETE /products/sku/{sku}` وتعرض استجابة نجاح `202`. قبول الطلب ليس دليلًا كافيًا أن كل Surface أصبحت خالية فورًا. سجّل الاستجابة ثم تحقّق بقراءة لاحقة بعد مهلة مناسبة. إذا بقي المنتج انقل العملية للتحقيق بدل تكرار Deletes بلا حدود.
يجب أن يعيد Deletion Worker حل Canonical Item الثابت وRemote ID وSKU الحالي والملكية قبل التنفيذ مباشرة. أوقف العملية إذا صار SKU يشير إلى عنصر آخر، أو تغير Mapping بعد الاعتماد، أو عاد Upstream Item إلى Active، أو كانت Snapshot التي أنشأت Tombstone غير مكتملة. اكتب Audit Receipt غير قابل للتغيير يوضح من اعتمد الفعل وأي Policy Version استُخدمت.
عندما يكون سلوك Hard Delete غير واضح لمنصة أو Product Class، استخدم انتقال حالة أكثر أمانًا يدعمه العقد الحالي مثل Draft أو Unavailable، واعرض الحالة للتاجر. لا تستنتج Endpoint تدميرية أو Payload من سلوك منصة أخرى.
عامل التعارض كقرار عمل
يوجد Conflict عندما تتغير Remote State بعد آخر قراءة مؤكدة ويخطط التكامل للكتابة فوق الحقل المتغير. اكتشف ذلك عبر Field Hashes أو Version Timestamps عند توفرها. لا تحل كل تعارض بقاعدة “ERP wins”. قد يكون المخزون للـERP بينما محتوى العرض لفريق المتجر.
صنّف التعارضات: Safe Merge للحقول المستقلة، وOwner-wins تلقائية لعقد صريح، ومراجعة لتغييرات الهوية والVariants والضريبة والنشر. خزّن النسختين والقرار المختار. بذلك يحصل التاجر على تفسير وتتوقف Oscillation بين الأنظمة.
يحتاج تغيير SKU إلى Workflow مستقل: أضف Alias الجديدة، وتحقق من Remote Identity، وحدّث المراجع التابعة، ثم اعتزل Alias القديمة بعد Grace Period. لا تنشئ Canonical Item جديدًا فقط لأن SKU معروفًا اختفى.
اختبر Invariants لا Responses فقط
أنشئ Fixtures لـSKU معاد تسميتها وNormalized SKUs متعارضة ومنتجات محذوفة ثم معاد إنشائها وPagination تغير ترتيبها وأخطاء 500 مؤقتة وCredentials منتهية ومسوح جزئية وتعديلات أثناء المصالحة. أثبت أن المسح غير المكتمل لا ينتج Delete، وأن Remote ID واحدة لا ترتبط بأكثر من Canonical Item نشط، وأن العملية المعتمدة تنتج أثرًا منطقيًا واحدًا.
قس مدة Snapshot وعدد العناصر المرصودة وعمليات Create وUpdate وQuarantine وDelete والهويات غير المحلولة ونسبة التعارض وعمر Retry وتأخر Verification. أنشئ Alerts عند هبوط مفاجئ في حجم الكتالوج أو تغير عدد الصفحات أو فشل Authentication أو ارتفاع Tombstones. يجب أن يوقف Circuit Breaker الإجراءات التدميرية عندما يختلف Run جذريًا عن Baseline الحديثة.
شغّل التصميم الجديد أولًا في Shadow Mode يقارن الكتابات المقترحة بالحالة دون تطبيق. ثم فعّل الحقول غير التدميرية لفوج صغير من التجار، وبعدها Quarantine. اجعل Hard Delete آخر Capability، محمية بصلاحية منفصلة وKill Switch.
متى لا تبني مزامنة ثنائية الاتجاه
لا تبنِ محركًا ثنائي الاتجاه عندما يكفي CSV Import ليلي مع مراجعة بشرية. لا تستخدم Upsert حسب SKU عندما يعيد التجار تسمية SKUs كثيرًا ولا يوجد Mapping ثابت. لا تجعل المنصتين تملكان السعر أو الكمية نفسيهما دون Conflict Contract حتمية. ولا تزامن كل Attribute لمجرد أنها متاحة.
يكون PIM واحد موثوق مع نشر أحادي الاتجاه أبسط. وقد تكون الإدارة الأصلية للمنصة أفضل لكتالوج صغير. تفيد الأحداث للسرعة، لكن Full Scans الدورية تبقى مطلوبة للإصلاح. يجب أن تطابق المعمارية تكلفة المنتج القديم أو المحذوف، لا أقصى تعقيد تسمح به API.
خطة تنفيذية
أنشئ Canonical Item ID ثابتًا وMapping لكل Remote Product ID. تتبع SKU Aliases بدل اعتبار SKU هوية. عرّف ملكية الحقول. خزّن Desired State وConfirmed Remote State منفصلتين. شغّل Snapshots مكتملة قابلة للاستئناف. حوّل الغياب إلى Tombstone ثم Quarantine قبل الحذف. اجعل الكتابات Idempotent ومتسلسلة لكل منتج وتحقق من النتيجة. أضف Circuit Breakers وAudit Receipts وKill Switch.
القاعدة المركزية بسيطة: الغياب دليل يحتاج تحقيقًا، وليس إذنًا بالحذف. بهذه الحدود تستطيع تكاملات سلة وزد التقارب بثبات مع الحفاظ على تحكم التاجر وتاريخ قابل للاستعادة.
المراجع الرسمية
تدعم هذه المراجع سلوك الأدوات المذكورة. الأمثلة وقرارات التصميم توضيحية، ويجب تكييفها مع متطلبات المشروع وإصداراته.
- Salla Merchant API — Product Details By SKU, modified 6 October 2026 and verified 12 October 2026
- Salla Merchant API — Update Product By SKU, verified 12 October 2026
- Salla Merchant API — Delete Product By SKU, verified 12 October 2026
- Zid API — List Products for full product synchronization, verified 12 October 2026
- Zid API — Bulk Update Products, verified 12 October 2026
إعداد: Noor Yasser
تعمل على تحدٍ تقني مشابه؟
أساعد الفرق على تحويل القرار المعماري إلى نطاق واضح وتنفيذ يمكن تشغيله ومراجعته بثقة.




