التجارة السعودية · معمارية المرتجعات

مرتجعات زد: افصل اعتماد الإرجاع عن تنفيذ الاسترداد

معمارية عملية لمرتجعات زد تفصل الاعتماد والفحص الفعلي وقرار المخزون وتنفيذ الاسترداد، وتمنع تكرار العمليات المالية.

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

المرتجع ليس استردادًا ماليًا أُلصقت به بوليصة شحن. هو عملية منسقة بين طلب العميل وأهلية المنتجات والاستلام الفعلي وقرار المخزون وحركة المال. إذا ضغط التكامل هذه الحقائق في حقل واحد اسمه `returned`، فقد تعيد محاولةٌ المبلغ مرتين، أو تعيد منتجًا تالفًا إلى المخزون القابل للبيع، أو يغلق الدعم الحالة بينما ما زال العميل ينتظر أمواله.

تعرض وثائق Reverse Orders الحالية في زد عمليات منفصلة لعرض المنتجات القابلة للإرجاع، وحساب الإجماليات، وإنشاء طلب المرتجع، وتحديث كميات المنتجات المستلمة وحالتها، وإنشاء الاسترداد. هذا الفصل مفيد، لكن التكامل يحتاج مع ذلك إلى Control Plane دائم خاص به. تصف API الأوامر المتاحة؛ ولا تستبدل سياسة اعتماد التاجر، أو دليل المستودع، أو المطابقة المالية.

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

ابدأ مما بقي قابلًا للإرجاع

قبل عرض نموذج المرتجع، اقرأ الطلب الحالي عبر واجهة View for Return في زد. تقول الوثائق إن الواجهة تعيد فقط المنتجات التي بقيت لها كميات قابلة للإرجاع، وتعيد حساب الإجماليات من هذه العناصر. وتعرّف الكمية المتبقية بأنها الكمية الأصلية مطروحًا منها مجموع المرتجعات السابقة. لذلك لا تستطيع نسخة طلب مخزنة قديمًا الإجابة بأمان بعد مرتجع جزئي.

احفظ الاستجابة كلقطة أهلية مع وقت القراءة ومعرف الطلب وهوية السطر وأقصى كمية متبقية والعملة وأقصى مبلغ قابل للاسترداد. دع العميل يختار بناءً على هذه اللقطة، ثم أعد القراءة أو الحساب مباشرة قبل الاعتماد. تفسر اللقطة ما رآه العميل؛ وتحمي القراءة الجديدة من مرتجع آخر اكتمل في الوقت نفسه.

لا تعرّف السطر باستخدام SKU وحده. قد يحمل سطران SKU نفسه لكنهما يختلفان في السعر أو الخصم أو الضريبة أو التخصيص. احتفظ بهوية Order Product من زد وهوية منتج Reverse Order في كامل المسار.

احسب أولًا، لكن لا تعتبر الحساب اعتمادًا

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

احفظ مدخلات الحساب واستجابته كمقترح ذي إصدار. اعرض العملة والتفصيل للمشغل أو العميل. وإذا تغيرت المنتجات أو الكميات أو العروض أو المرتجعات السابقة قبل الاعتماد، فأنه المقترح واحسب من جديد. لا تستخدم مبلغًا أعدت بناءه محليًا كمرجع نهائي عندما تستطيع المنصة حساب الإجمالي الحالي القابل للاسترداد.

يجب أن يحمل المقترح قرار أعمال أيضًا: من طلب الإرجاع، وما قاعدة السياسة التي قبلته، وهل يخصم الشحن، وهل الفحص مطلوب. هذه قرارات التاجر، ولا تستنتج من استجابة HTTP 200.

أنشئ Reverse Order واحدًا لكل نية معتمدة

تنشئ واجهة Create Reverse Orders طلب المرتجع وتعيد معرفه، وموقع المخزون المختار، والمنتجات، وإجمالي المرتجع والاسترداد، ووسائل الاسترداد المتاحة. تعامل مع هذا المعرف كمرجع المنصة الدائم لكل عملية لاحقة.

ضع قيدًا فريدًا على التاجر والطلب الأصلي ومعرف نية الإرجاع المعتمدة داخل نظامك. قبل استدعاء زد، اكتب سجل أمر يحمل Idempotency Key ثابتًا والكميات المقصودة لكل سطر. بعد النجاح، احفظ معرف Reverse Order والاستجابة. إذا انتهت مهلة الشبكة، انقل الأمر إلى `outcome_unknown`؛ ولا تنشئ نية ثانية تلقائيًا. طابق مع حالة المنصة أو حوّل الحالة إلى مراجعة مضبوطة.

حد منع التكرار المحلي توصية للتكامل. لا تفترض ضمان Idempotency لدى المزود ما لم توثقه المنصة. السؤال الآمن بعد استجابة غامضة هو «هل أنشأت هذه النية Reverse Order بالفعل؟» وليس «هل أستطيع إعادة إرسال POST نفسها؟».

يفصل مسار المرتجع الآمن بين طلب العميل والاستلام الفعلي وقرار المخزون وتنفيذ الاسترداد، ويغلق كل مرحلة بدليل مستقل.
يفصل مسار المرتجع الآمن بين طلب العميل والاستلام الفعلي وقرار المخزون وتنفيذ الاسترداد، ويغلق كل مرحلة بدليل مستقل. اضغط لعرض أكبر

احتفظ بأربعة سجلات مترابطة بدل حالة واحدة

استخدم أربعة سجلات بعلاقات صريحة: نية الإرجاع، وReverse Order في زد، وفحص الاستلام الفعلي، وأمر الاسترداد. تحفظ النية المنتجات المطلوبة ودليل الاعتماد. ويعكس سجل Reverse Order هوية المنصة والكميات المؤهلة. ويحفظ الفحص ما وصل فعليًا وحالته. ويسجل أمر الاسترداد المبلغ والوسيلة وهوية المحاولة والنتيجة المرصودة.

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

استخدم سجل انتقالات Append-Only يحتوي الفاعل والمصدر والتوقيت والحالة السابقة والجديدة والسبب. تضيف التصحيحات حدث تعويض بدل إعادة كتابة التاريخ. بهذا يستطيع الدعم تفسير أن العميل طلب وحدتين، ووصلت واحدة، وكانت أخرى تالفة، ولم تعد إلى المخزون إلا وحدة واحدة.

سجل الحالة قبل تغيير المخزون القابل للبيع

تسجل واجهة Update Return Products كميات المستلم بحالة جيدة، وغير المستلم، والمستلم تالفًا. القيد الموثق هو ألا يتجاوز مجموعها الكمية المعادة؛ وأن تكون القيم أعدادًا صحيحة غير سالبة؛ وأن يفشل الطلب كاملًا إذا فشل سطر واحد. وتقول الوثائق إن هذه القيم مؤثرة في مطابقة الاسترداد وتعديلات المخزون وتدقيق المرتجعات.

طبّق القيد نفسه محليًا قبل استدعاء API. احتفظ بإصدار الفحص وهوية موظف المستودع أو النظام الذي أنشأه. ولا تجعل «مستلم» مرادفًا تلقائيًا لـ«قابل للبيع»: أضف Disposition مثل إعادة للمخزون، حجر، تجديد، إتلاف أو إعادة للمورد. لا تنتج حركة مخزون قابلة للبيع إلا حالة جيدة مع قرار Restock مؤكد.

تحتاج حركة المخزون إلى أمر مستقل قابل لمنع التكرار ومفتاحه Reverse Order والسطر وإصدار القرار. إذا صحح المستودع كمية، فانشر الفرق كحركة جديدة أو عوض الحركة القديمة. لا تعِد حساب المخزون بإعادة تشغيل Snapshots قابلة للتعديل دون Ledger.

نفذ الاسترداد كأمر مالي مضبوط

تستدعى واجهة Create Refund لطلب مرتجع موجود بعد مراجعة `refund_total` و`available_refund_payment_methods`. تسرد الوثائق وسائل متعددة، وتوضح أن استرداد `zid_bank_transfer` يحتاج رفع إيصال عبر واجهة منفصلة. لذلك لا يثبت اعتماد Reverse Order انتقال المال، كما لا يثبت إرسال طلب الاسترداد اكتمال التسوية.

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

عند Timeout أو 5xx، انقل الحالة إلى `refund_outcome_unknown`. امنع استردادًا جديدًا للرصيد نفسه حتى تثبت المطابقة نجاح الأمر الأول أو فشله. وفي التحويل البنكي، افصل دليل رفع الإيصال عن دليل الإكمال المالي. الإيصال يوثق فعلًا؛ ولا يثبت وحده تسوية البنك إلا إذا عرّفت إجراءات التاجر هذا المعنى وتحققت منه.

طابق الحقيقة الفعلية وحقيقة المنصة والمال

شغّل مهمة مطابقة تقارن أربعة مجاميع لكل سطر وعملة: الكمية المطلوبة، والكمية المعادة في المنصة، والكمية المصنفة فعليًا، وحركة المخزون المسجلة محليًا؛ ثم قارن المبلغ المحسوب القابل للاسترداد وأوامر الاسترداد وسجل الاسترداد في المنصة. يجب أن يولد كل اختلاف استثناءً محدودًا، لا Retry Loop آلية.

تشمل الاستثناءات المفيدة: غياب Reverse Order بعد نتيجة إنشاء مجهولة، وكمية فعلية أعلى من المعادة، وإعادة مخزون قابل للبيع أعلى من الكمية السليمة، واسترداد أعلى من الرصيد المتاح، وتحويل بنكي بلا دليل الإيصال المطلوب، واسترداد مكتمل مع قرار مخزون غير محسوم. عيّن مالكًا وإجراءً آمنًا تاليًا لكل فئة.

خزّن المال كوحدات صغرى صحيحة أو Decimal مع العملة الأصلية. لا تقارن Display Strings. أعد الحساب من زد قبل استرداد تصحيحي، وسجل لماذا يختلف الحساب الجديد عن المقترح الأصلي.

تسلسل تنفيذي عملي

يستطيع التكامل الموثوق اتباع هذا التسلسل: اقرأ View for Return؛ التقط العناصر المطلوبة من العميل؛ احسب الإجماليات الحالية؛ طبّق سياسة التاجر؛ أنشئ نية محلية دائمة؛ أنشئ Reverse Order في زد مرة واحدة؛ أنشئ بوليصة الإرجاع عند الحاجة؛ سجل فحص المستودع؛ قرر مصير المخزون؛ اعتمد مبلغ الاسترداد ووسيلته؛ نفذ أمر استرداد واحدًا؛ أرفق دليل التحويل البنكي عند انطباقه؛ ثم طابق حتى تتفق السجلات الفعلية وسجلات المنصة والمال.

قد يختلف الترتيب التشغيلي الدقيق حسب سياسة التاجر ووسيلة الدفع. بعض التجار يسترد قبل الاستلام، وآخرون يشترطون الفحص. مثّل هذا الفرق كسياسة وقاعدة اعتماد، لا كشروط متناثرة في الكود. الثابت هو ألا تنتحل مرحلة دور أخرى: البوليصة ليست استلامًا، والاستلام ليس Restock، والاعتماد ليس تسوية، واستجابة HTTP ليست مطابقة.

قس جودة الضبط لا سرعة الإرجاع فقط

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

السرعة ليست الهدف الوحيد. يجب أن تشمل Guardrails: استردادًا أعلى من القيمة المؤهلة، واستردادًا مكررًا، وإعادة منتج تالف إلى المخزون القابل للبيع، ونتائج مجهولة لم تحسم، وحالات أغلقت قبل اكتمال التزام العميل والمحاسبة. مسار أسرع يزيد هذه الأحداث ليس تحسينًا.

قاعدة التصميم الأساسية بسيطة: تعامل مع Reverse Order والفحص وحركة المخزون والاسترداد كسجلات مستقلة مترابطة. جمّد الدليل المستخدم لكل قرار، واجعل الأوامر الخارجية Idempotent من جانبك، ولا تغلق المرتجع حتى تثبت المطابقة أن الطرد والمال وصلا إلى حالتيهما النهائيتين المقصودتين.

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

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

إعداد: Noor Yasser

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

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

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

احجز لقاءً لمدة ٣٠ دقيقةالخدمة المرتبطةتطبيقات سلة وزد وأدوات التجّارمشروع من الأعمالMember Plus