عند بناء تكامل مع منصة فاتورة، النجاح في البيئة المثالية ليس المقياس. المقياس الحقيقي هو كيف يتصرّف نظامك حين تتعطّل الشبكة لثوانٍ، أو حين ترجع المنصة رمز خطأ خادم مؤقتاً، أو حين يتجاوز معدّل طلباتك الحد المسموح. في هذه اللحظات تتحدد سلامة فواتيرك: هل تُعاد المحاولة فتصل الفاتورة، أم يسقط الطلب صامتاً فيكتشف العميل الفجوة بعد أيام؟ منطق إعادة المحاولة (Retry Logic) هو الطبقة التي تحوّل تكاملاً هشاً إلى تكامل يصمد في الإنتاج.
هذا الدليل يشرح متى تُعيد المحاولة ومتى تمتنع، وكيف تبني تراجعاً أسّياً (exponential backoff) مع توزيع عشوائي (jitter)، وكيف تحافظ على عدم تكرار المقاصة عبر إعادة استخدام نفس المعرّف الفريد (UUID)، وكيف تتعامل مع الطلبات التي تفشل نهائياً عبر طابور الرسائل الميتة (dead-letter queue). الهدف أن يخرج المطوّر بنموذج قابل للتطبيق مباشرة على واجهة المقاصة (Clearance) وواجهة الإبلاغ (Reporting).
هذا المقال جزء من مركز المطوّرين ضمن الفاتورة الإلكترونية من قيود. ويفترض أنك قرأت نقاط نهاية API لمنصة فاتورة وتعرف الفرق بين واجهة المقاصة وواجهة الإبلاغ، كما يفترض إلمامك بـمعالجة أخطاء API لمنصة فاتورة وبنية استجابة الأخطاء وقواعد إرسال الفاتورة للمقاصة والإبلاغ. منطق إعادة المحاولة يبني فوق هاتين الطبقتين مباشرة.
لماذا تحتاج إلى منطق إعادة محاولة مدروس
الشبكة ليست مثالية، والخوادم تتعطّل أحياناً، وحدود المعدّل موجودة لسبب. في تكامل الفوترة الإلكترونية، نسبة صغيرة من الطلبات ستفشل لأسباب عابرة لا علاقة لها بصحة الفاتورة. الفاتورة سليمة، والبيانات صحيحة، لكن الطلب لم يصل أو لم تصل الاستجابة. هنا تكمن المشكلة: الفشل العابر مؤقت بطبيعته، وإعادة الإرسال البسيطة كفيلة بنجاحه.
المطوّر الذي يعامل كل فشل كنهاية المطاف يخسر فواتير صحيحة بسبب انقطاع دام ثانيتين. والمطوّر الذي يُعيد المحاولة على كل خطأ دون تمييز يُغرق المنصة بطلبات مكررة، ويصطدم بحدود المعدّل، وقد يُنشئ فواتير مقاصة مكررة لدى الهيئة. الحل وسط هذين الطرفين: منطق يُعيد المحاولة فقط على ما يستحق، بوتيرة تتباعد تدريجياً، مع ضمان أن إعادة الإرسال لا تُنتج تكراراً.
تبدأ الاستراتيجية بسؤال واحد عند كل فشل: هل هذا الخطأ عابر أم نهائي؟ الخطأ العابر (transient) قابل للحل بإعادة المحاولة لأن سببه مؤقت. الخطأ النهائي (permanent) لن يتغير مهما أعدت الإرسال لأن سببه في البيانات نفسها. خلط الفئتين هو أكثر خطأ شائع في تكاملات الفوترة، ونتيجته إما خسارة فواتير صحيحة أو إغراق المنصة بطلبات محكوم عليها بالفشل.
أين موقع طبقة إعادة المحاولة في تدفق الإصدار
منطق إعادة المحاولة طبقة وسيطة تجلس بين منطق إنشاء الفاتورة وبين عميل HTTP الذي يتصل بمنصة فاتورة. عند فشل الطلب، لا يعود الخطأ مباشرة إلى منطق العمل. بل يمر أولاً عبر طبقة القرار التي تصنّف الخطأ، ثم تقرر: إعادة فورية، أم انتظار ثم إعادة، أم تسليم نهائي لطابور الرسائل الميتة.
| الاستجابة | القرار |
|---|---|
| 2xx نجاح | لا حاجة لإعادة |
| 4xx خطأ منطقي | لا تُعِد، صحّح أولاً |
| 429 / 5xx / مهلة | أعد المحاولة مع تراجع أسّي |
تصنيف الاستجابات: ما الذي يستحق إعادة المحاولة
القرار الأول والأهم هو التصنيف. لا تُعيد المحاولة على كل فشل، بل على الفشل العابر فقط. الجدول التالي يلخّص كيف تتعامل مع كل فئة من الاستجابات القادمة من واجهتي المقاصة والإبلاغ:
| الحالة | الفئة | أعد المحاولة؟ | السبب |
|---|---|---|---|
| 500 / 502 / 503 / 504 | خطأ خادم المنصة | نعم | المشكلة في المنصة لا في فاتورتك. الخطأ مؤقت ويُحل غالباً خلال ثوانٍ. |
| 429 Too Many Requests | تجاوز حد المعدّل | نعم، مع احترام الترويسة | الطلب صحيح لكن الوتيرة مرتفعة. انتظر المدة التي تحددها ترويسة Retry-After. |
| مهلة الاتصال / انقطاع الشبكة | خطأ شبكة | نعم، بحذر | قد يكون الطلب وصل دون أن تصلك الاستجابة. أعد بنفس UUID لتجنّب التكرار. |
| 400 Bad Request | طلب مشوّه | لا | بنية الطلب خاطئة. إعادة الإرسال بنفس البيانات ستفشل حتماً. |
| 401 Unauthorized | مصادقة فاشلة | لا (جدّد أولاً) | شهادة CSID منتهية أو الرمز المميز غير صالح. جدّد الاعتماد ثم أرسل كطلب جديد، لا كإعادة محاولة عمياء. |
| 422 Unprocessable Entity | فشل قواعد التحقق | لا | الفاتورة فشلت في validationResults. أصلح البيانات أولاً، فإعادة الإرسال دون تغيير تكرّر الفشل. |
القاعدة الجوهرية: أخطاء فئة 5xx ومهلات الشبكة و429 مرشحة لإعادة المحاولة لأن الفاتورة صحيحة والمشكلة عابرة. أخطاء فئة 4xx المنطقية (400 و401 و422) ليست مرشحة لإعادة المحاولة الآلية لأن سببها في الطلب نفسه، ولن يتغيّر مهما كررت الإرسال. التمييز هنا ليس تفصيلاً تقنياً بل خط الدفاع الأول ضد إهدار الموارد وضد إغراق المنصة.
خطأ 429 حالة خاصة تستحق وقفة. هو من فئة 4xx لكنه قابل لإعادة المحاولة، شرط أن تحترم ترويسة Retry-After إن وُجدت. لا تتعامل معه كخطأ منطقي ولا تتجاهل المدة التي تحددها المنصة، فإعادة الإرسال الفورية بعد 429 تطيل فترة الحظر بدل أن تحلّها. تفاصيل النوافذ الزمنية والحدود تستحق مراجعة مستقلة ضمن مركز المطوّرين.
مهلة الشبكة (timeout) أصعب الحالات تصنيفاً، لأنها غامضة بطبيعتها. حين تنقطع الاستجابة، لا تعرف إن كان الطلب قد وصل المنصة وعولج فعلاً، أم سقط في الطريق. هنا تحديداً تصبح إعادة استخدام نفس المعرّف الفريد ضرورة لا خياراً، كما سنفصّل في قسم منع التكرار.
ميّز التصنيف عن المعالجة
التصنيف يقرر هل نُعيد المحاولة. المعالجة تقرر كيف. الخلط بينهما يُنتج كوداً متشعّباً يصعب صيانته. الأنظف أن تبني دالة تصنيف واحدة تُرجع قراراً صريحاً، ثم تبني منطق المعالجة فوق هذا القرار:
لاحظ الافتراض الأخير. أي رمز غير معروف يُصنَّف افتراضياً على أنه غير قابل لإعادة المحاولة. هذا الموقف المحافظ يحميك من حلقات إعادة لا نهائية على حالات لم تتوقعها. الأسلم أن تسجّل الرمز المجهول وتسلّمه للمراجعة اليدوية بدل افتراض أنه عابر.
التراجع الأسّي مع التوزيع العشوائي
حين تقرر إعادة المحاولة، السؤال التالي: متى؟ إعادة الإرسال الفورية خطأ شائع، لأن السبب العابر غالباً لم يُحلّ بعد. الإرسال المتكرر بلا انتظار يُسمّى «العاصفة الراعدة» (retry storm): مئات العملاء يُعيدون المحاولة في اللحظة نفسها فيُطيلون عطل المنصة بدل أن ينتظروا تعافيها.
الحل المعياري هو التراجع الأسّي. بدل فترة ثابتة بين المحاولات، تتضاعف الفترة في كل محاولة: ثانية واحدة، ثم اثنتان، ثم أربع، ثم ثماني، وهكذا. هذا يمنح المنصة مهلة متزايدة للتعافي، ويقلّل الضغط تدريجياً بدل أن يصبّه دفعة واحدة.
المحاولة 1: بعد ثانية واحدة
المحاولة 2: بعد ثانيتين
المحاولة 3: بعد 4 ثوانٍ
المحاولة 4: بعد 8 ثوانٍ
أضف توزيعاً عشوائياً (Jitter) لكل فترة
لكن التراجع الأسّي وحده لا يكفي. إذا تعطّلت المنصة وأعاد ألف عميل المحاولة بعد ثانية واحدة بالضبط، ثم بعد ثانيتين بالضبط، فإنهم يضربون المنصة في موجات متزامنة. الحل إضافة توزيع عشوائي (jitter): بدل انتظار ثانيتين تماماً، انتظر مدة عشوائية ضمن نافذة حول الثانيتين. هذا يبعثر الطلبات على محور الزمن فيمنع تزامنها.
هذا النمط يُعرف بـ «full jitter»: المدة قيمة عشوائية بين الصفر والحد الأسّي الحالي. هو الأكثر فاعلية في تبديد العواصف الراعدة لأنه يوزّع الطلبات على كامل النافذة الزمنية. لاحظ أيضاً السقف (cap): مهما زاد رقم المحاولة، لا تتجاوز الفترة 32 ثانية، حتى لا تصبح المدد طويلة بلا معنى عملي.
الحد الأقصى للمحاولات
إعادة المحاولة ليست بلا نهاية. لكل طلب حد أقصى للمحاولات، بعده يُسلَّم الطلب لطابور الرسائل الميتة بدل أن يدور في حلقة أبدية. الرقم المناسب يعتمد على طبيعة الواجهة، لكن القاعدة العملية أن أربعاً إلى ستّ محاولات تغطّي معظم الأعطال العابرة. مع تراجع أسّي يبدأ من ثانية ويُضاعف، خمس محاولات تمتد عبر نحو ثلاثين ثانية إجمالاً، وهي نافذة كافية لتعافي معظم أعطال الخوادم المؤقتة.
انتبه إلى تسلسل القرار في الحلقة. أولاً نفحص النجاح فنخرج فوراً. ثم نفحص هل الخطأ غير قابل لإعادة المحاولة فنرمي خطأً نهائياً دون انتظار. وأخيراً، إن كان الخطأ عابراً، ننتظر وفق التراجع ثم نكرّر. حين تُستنفد المحاولات، يذهب الطلب للطابور الميت ولا يضيع.
منع التكرار: إعادة استخدام نفس المعرّف الفريد
هنا أخطر جزء في منطق إعادة المحاولة، وأكثره إهمالاً. حين تنقطع الشبكة بعد إرسال طلب المقاصة، قد يكون الطلب قد وصل المنصة وعُولج، لكن الاستجابة لم تعد إليك. إذا أعدت المحاولة بمعرّف فريد جديد، فأنت تطلب من الهيئة مقاصة فاتورة ثانية لنفس العملية. النتيجة: فاتورتان مُصدّقتان لمعاملة واحدة، وهذا خطأ محاسبي وضريبي يصعب تصحيحه لاحقاً.
القاعدة الذهبية: كل محاولة لإرسال نفس الفاتورة تستخدم نفس المعرّف الفريد (UUID) ونفس قيمة التجزئة (hash) المتسلسلة. المعرّف الفريد يُولَّد مرة واحدة عند إنشاء الفاتورة، لا عند كل محاولة إرسال. هكذا تتعامل المنصة مع المحاولات المكررة كطلب واحد، فإن كانت قد عالجت الطلب الأول تُرجع النتيجة نفسها بدل إنشاء مقاصة جديدة.
إرسال بمعرّف UUID ثابت
انقطاع الشبكة
إعادة بنفس UUID = لا تكرار
هذا المبدأ يُسمّى «العملية عديمة الأثر الجانبي عند التكرار» (idempotency). الطلب عديم الأثر الجانبي عند التكرار هو طلب يُنتج النتيجة نفسها سواء أُرسل مرة أو خمساً. منطق إعادة المحاولة يعتمد عليه اعتماداً كاملاً: بدونه، كل إعادة محاولة مخاطرة بإنشاء تكرار، فيصبح العلاج أخطر من الداء.
عملياً، احفظ المعرّف الفريد مع الفاتورة في قاعدة بياناتك قبل أول إرسال. عند كل محاولة، اقرأ المعرّف المحفوظ ولا تولّد جديداً. وإن وصلتك استجابة 200 لطلب كنت تظنه فاشلاً (لأن المهلة انقطعت في المحاولة السابقة)، فهذا تأكيد أن إعادة الاستخدام عملت كما يجب: المنصة طابقت المعرّف وأعادت الفاتورة المُصدّقة دون تكرار.
التفريق بين المقاصة والإبلاغ في إعادة المحاولة
سلوك إعادة المحاولة يختلف قليلاً بين الواجهتين. واجهة المقاصة (للفواتير الضريبية B2B) متزامنة: تنتظر تصديق الهيئة قبل تسليم الفاتورة للمشتري، فإعادة المحاولة هنا تحجب العملية حتى تنجح أو تُستنفد. واجهة الإبلاغ (للفواتير المبسّطة B2C) غير متزامنة: الفاتورة تُسلَّم للمشتري فوراً ثم تُبلَّغ الهيئة خلال 24 ساعة، فإعادة المحاولة تحدث في الخلفية دون أن تعطّل العميل عند نقطة البيع.
هذا الفرق يؤثر على تصميم الطابور. فواتير المقاصة تستحق محاولات أسرع وأكثر إلحاحاً لأن المشتري ينتظر. فواتير الإبلاغ تتحمّل تراجعاً أبطأ ونافذة أوسع، طالما أُكمل الإبلاغ ضمن مهلة الأربع والعشرين ساعة التي تفرضها الهيئة.
طابور الرسائل الميتة: شبكة الأمان الأخيرة
ماذا يحدث للفاتورة بعد استنفاد كل المحاولات؟ لا يجوز أن تختفي صامتة، ولا أن تظل تدور في الحلقة إلى الأبد. الإجابة هي طابور الرسائل الميتة (dead-letter queue): مخزن منفصل تُسلَّم إليه الطلبات التي فشلت نهائياً، لتراجَع وتُعالَج يدوياً أو آلياً لاحقاً.
الطابور الميت يخدم ثلاثة أغراض. أولاً، يمنع ضياع الفواتير: كل فاتورة فشلت محفوظة في مكان معروف لا تختفي منه. ثانياً، يفصل الفشل عن خط الإنتاج الرئيسي: تعطّل فاتورة واحدة لا يوقف بقية الإصدار. ثالثاً، يوفّر مرجعاً للتحليل: تراكم نوع معين من الفشل في الطابور يكشف مشكلة بنيوية تستحق المعالجة.
| الحقل | ما يُخزَّن | الفائدة |
|---|---|---|
| معرّف الفاتورة (UUID) | المعرّف الفريد الأصلي | يضمن أن إعادة المعالجة تستخدم المعرّف نفسه فلا تُنتج تكراراً. |
| حمولة الطلب | جسم الفاتورة كاملاً كما أُرسل | يتيح إعادة الإرسال دون إعادة بنائها من الصفر. |
| آخر استجابة | رمز الحالة وجسم الخطأ الأخير | يحدد سبب الفشل النهائي ويوجّه المعالجة اليدوية. |
| عدّاد المحاولات | كم محاولة جرت ومتى | يكشف هل المشكلة عابرة طويلة أم نمط متكرر. |
| الطابع الزمني | وقت أول وآخر محاولة | يربط الفشل بنوافذ عطل المنصة المعروفة. |
القاعدة العملية: لا تُعد المعالجة من الطابور الميت آلياً ودون حدود. الطلب وصل الطابور لأنه فشل خمس مرات، فإعادته فوراً غالباً تفشل مرة سادسة. الأنسب جدولة إعادة معالجة دورية (مثلاً كل ساعة) مع حد أقصى لعدد دورات الإعادة، وتنبيه بشري حين يتجاوز طلب ما هذا الحد، إذ يصبح حينها حالة تستحق فحصاً يدوياً لا إعادة آلية.
لا تخلط الطابور الميت بالأخطاء المنطقية
خطأ شائع آخر: دفع فواتير فشلت بخطأ 422 (فشل تحقق) إلى الطابور الميت بانتظار إعادة المحاولة. هذا خطأ، لأن الفاتورة لن تمر مهما أُعيدت ما دامت بياناتها خاطئة. الطابور الميت مخصص للفشل العابر المُستنفَد، لا للفشل المنطقي. الفواتير ذات الأخطاء المنطقية تذهب إلى مسار مختلف: تُعرض على المستخدم ليصحّح البيانات، ثم تُرسل كفاتورة معدّلة بمعرّف جديد، لا كإعادة محاولة بمعرّف قديم.
سيناريو كامل: من الانقطاع إلى التعافي
لنربط القطع في مثال واقعي يمر به أي تكامل في الإنتاج. تاجر يُصدر فاتورة ضريبية B2B بقيمة 12,500 ر.س، ويرسلها لواجهة المقاصة. في تلك اللحظة، تشهد المنصة موجة ضغط مؤقتة فترجع رمز 503، ثم تنقطع الشبكة في المحاولة التالية قبل وصول الاستجابة. كيف يتعامل منطق إعادة محاولة سليم مع هذا التسلسل؟
عند إنشاء الفاتورة، يولّد النظام معرّفاً فريداً (UUID) واحداً ويحفظه في قاعدة البيانات مع حالة «قيد الإرسال». المحاولة الأولى ترجع 503، فيصنّفها المنطق على أنها خطأ خادم عابر قابل لإعادة المحاولة. ينتظر النظام مدة عشوائية ضمن نافذة الثانية الواحدة وفق التراجع الأسّي، ثم يعيد الإرسال بنفس المعرّف.
المحاولة الثانية تصطدم بانقطاع الشبكة: يصل الطلب المنصة وتُعالجه فعلاً، لكن الاستجابة تضيع في الطريق فيسجّل النظام مهلة (timeout). هنا يظهر دور إعادة استخدام المعرّف. لو ولّد النظام معرّفاً جديداً الآن، لطلب من الهيئة مقاصة فاتورة ثانية لنفس المعاملة. لكنه يحتفظ بالمعرّف الأصلي، فينتظر ضمن نافذة الثانيتين ثم يعيد الإرسال.
المحاولة الثالثة تنجح وترجع 200، لكن المفاجأة أن المنصة تُرجع الفاتورة المُصدّقة نفسها التي عالجتها في المحاولة الثانية المنقطعة. لأن المعرّف لم يتغيّر، طابقت المنصة الطلب مع ما عالجته سابقاً ولم تُنشئ مقاصة جديدة. يخزّن النظام الفاتورة المُصدّقة ورمز الاستجابة السريعة (QR)، ويحدّث الحالة إلى «مُصدّقة»، وتكتمل العملية بفاتورة واحدة لا فاتورتين.
هذا التسلسل يلخّص المبادئ الثلاثة معاً: التصنيف ميّز الخطأ العابر من النهائي، والتراجع الأسّي منح المنصة مهلة للتعافي، وإعادة استخدام المعرّف منعت التكرار رغم انقطاع وسط العملية. لو سقط أي مبدأ من الثلاثة، لانتهى السيناريو بفاتورة ضائعة أو بفاتورة مكررة.
المراقبة والتسجيل: ما لا تراه لا تستطيع إصلاحه
منطق إعادة المحاولة يعمل في الخلفية بطبيعته، وهذا خطر صامت. الطلبات تُعاد وتنجح دون أن يلاحظ أحد، حتى يتحول عطل عابر متكرر إلى مشكلة بنيوية لا أحد يراها. لذلك التسجيل (logging) جزء أصيل من المنطق، لا إضافة اختيارية.
سجّل لكل محاولة: معرّف الفاتورة، رقم المحاولة، رمز الاستجابة، سبب التصنيف، ومدة الانتظار التي طُبّقت. هذا السجل يجيب عن أسئلة حاسمة عند التحقيق: هل ترتفع نسبة 503 في ساعة معينة؟ هل فاتورة بعينها تُعاد أكثر من غيرها؟ هل يقترب طابور الرسائل الميتة من الامتلاء؟ بدون هذه البيانات، تكتشف المشكلة من شكوى العميل لا من لوحة المراقبة.
راقب ثلاثة مؤشرات أساسية. الأول: معدّل إعادة المحاولة، أي نسبة الطلبات التي احتاجت محاولة واحدة على الأقل بعد الأولى. ارتفاعه المفاجئ يشير إلى عطل في المنصة أو في شبكتك. الثاني: معدّل الوصول للطابور الميت، أي نسبة الطلبات التي استنفدت كل محاولاتها. أي ارتفاع هنا إنذار يستحق فحصاً فورياً. الثالث: زمن التعافي، أي المدة من أول فشل حتى نجاح أو تسليم نهائي.
التنبيه الآلي يبني فوق هذه المؤشرات. اضبط حداً لمعدّل الوصول للطابور الميت، وحين يتجاوزه النظام، أرسل تنبيهاً للفريق المعني. الهدف أن تعرف بالمشكلة قبل العميل، فتصلحها وهي عطل عابر صغير لا أزمة فواتير متراكمة.
أخطاء شائعة في منطق إعادة المحاولة
قبل أن نختم، إليك الأخطاء التي تتكرر في تكاملات الفوترة وكيف تتجنّبها:
| الخطأ | النتيجة | الصواب |
|---|---|---|
| إعادة المحاولة على خطأ 422 | تكرار الفشل بلا فائدة واستهلاك للموارد | أصلح بيانات الفاتورة، ثم أرسلها كفاتورة معدّلة لا كإعادة محاولة. |
| توليد معرّف فريد جديد عند كل محاولة | مقاصة فاتورة مكررة لدى الهيئة | ولّد المعرّف مرة واحدة عند الإنشاء وأعد استخدامه في كل إرسال. |
| إعادة فورية دون انتظار | عاصفة طلبات تُطيل عطل المنصة | طبّق التراجع الأسّي مع توزيع عشوائي بين المحاولات. |
| محاولات بلا حد أقصى | حلقة لا نهائية تستهلك الموارد | ضع حداً أقصى ثم سلّم الطلب للطابور الميت. |
| تجاهل ترويسة Retry-After عند 429 | إطالة فترة الحظر بدل حلّها | احترم المدة التي تحددها المنصة بدقة. |
| إعادة محاولة صامتة دون تسجيل | أعطال متكررة لا يراها أحد | سجّل كل محاولة وراقب معدّلاتها. |
كيف يساعدك قيود في منطق إعادة المحاولة
الفائدة العملية الأكبر من فهم منطق إعادة المحاولة هي أن قيود يطبّقه نيابة عنك في تكامله المباشر مع منصة فاتورة، فلا تحتاج إلى بناء هذه الطبقة من الصفر:
- مقاصة وإبلاغ تلقائيان مع منطق إعادة مدمج: يتولّى قيود إرسال كل فاتورة B2B للمقاصة الفورية وكل فاتورة B2C للإبلاغ خلال 24 ساعة، ويُعيد المحاولة آلياً على الأعطال العابرة دون تدخّل منك.
- منع التكرار مدمج: يحفظ قيود المعرّف الفريد (UUID) وسلسلة التجزئة (hash) لكل فاتورة ويعيد استخدامهما عند أي إعادة إرسال، فلا تتكرر المقاصة لدى الهيئة.
- إدارة شهادة CSID: يُدير قيود شهادة الختم المشفّر (CSID) تلقائياً ويتعامل مع تجديدها، فلا تتوقف فواتيرك بسبب شهادة منتهية.
- حفظ سلسلة التجزئة للتحقق: يخزّن قيود سلسلة تجزئة الفواتير لضمان تكامل التسلسل، وهي الركيزة التي يعتمد عليها منع التكرار عند إعادة المحاولة.
لاحظ ما لا يفعله قيود وما يبقى مسؤوليتك: تقديم الإقرار الضريبي ودفع الضريبة يتمّان عبر بوابة الهيئة من جانب العميل، وتسجيل شهادة CSID لدى الهيئة يبقى خطوة يقوم بها العميل بإرشاد من قيود. قيود يتولّى طبقة الإصدار والمقاصة والإبلاغ، لا التقديم النهائي للإقرار.
قائمة تحقق لمنطق إعادة محاولة سليم
قبل أن تعتبر طبقة إعادة المحاولة جاهزة للإنتاج، راجع هذه النقاط:
- صنّف قبل أن تعيد: أعد المحاولة على 5xx و429 ومهلات الشبكة فقط. لا تُعد على 400 و401 و422.
- تراجع أسّي مع توزيع عشوائي: ضاعف الفترة في كل محاولة، وأضف jitter لتبعثر الطلبات، وضع سقفاً أعلى للمدة.
- حد أقصى للمحاولات: أربع إلى ست محاولات كافية. بعدها سلّم للطابور الميت.
- نفس المعرّف الفريد في كل محاولة: ولّد UUID مرة واحدة عند الإنشاء، وأعد استخدامه في كل إرسال لمنع التكرار.
- احترم ترويسة Retry-After: عند 429، انتظر المدة التي تحددها المنصة لا مدة من عندك.
- طابور رسائل ميتة: خزّن الطلبات المُستنفَدة بكامل سياقها بدل أن تتركها تختفي.
- افصل الفشل المنطقي عن العابر: الأخطاء المنطقية تذهب للتصحيح، لا للطابور الميت.
- راقب وسجّل: سجّل كل محاولة وسببها لتكشف الأنماط المتكررة قبل أن تتفاقم.
منطق إعادة المحاولة ليس ترفاً هندسياً بل شرط أساسي لتكامل فوترة يصمد في الإنتاج. الفرق بين تكامل يخسر فواتير عند أول انقطاع وتكامل يتعافى تلقائياً هو هذه الطبقة بالضبط: تصنيف دقيق، تراجع مدروس، منع تكرار محكم، وشبكة أمان نهائية. إن بنيت تكاملك المباشر مع منصة فاتورة، فاجعل هذه الطبقة أولوية لا فكرة لاحقة. وإن أردت تجاوز بنائها كلياً، فقيود يطبّقها نيابة عنك ضمن تكامله المعتمد.
فوترة إلكترونية تتعافى تلقائياً من أعطال الشبكة
يتولّى قيود المقاصة والإبلاغ مع منصة فاتورة، ويعيد المحاولة آلياً على الأعطال العابرة بنفس المعرّف الفريد، فلا تتكرر فواتيرك ولا تضيع.