واجهات دفع مرنة: المهلات وإعادة المحاولة وقواطع الدائرة

يجب أن تعكس سياسات المرونة قابلية تكرار العملية وما إذا كانت نتيجتها معروفة.

استمع إلى المقال

جارٍ تجهيز الصوت…

هندسة التقنية المالية

في واجهة دفع، يعني انتهاء المهلة أن «العميل لا يعرف النتيجة»، لا أن الدفع فشل. قاعدتي التصميمية هي فصل تعافي النقل عن الحقيقة المالية ومنح كل عملية هوية دائمة يمكن الاستعلام عنها قبل الإعادة. وحالات الدفع التالية اصطناعية.

مسار قرار لواجهة دفع يوضح إعادة المحاولة الآمنة والاستعلام وقاطع الدائرة والإشعارات والمطابقة
الشكل 11. لا تُعد المحاولة إلا عندما تسمح دلالة العملية وحالتها بذلك؛ وجّه النتيجة المجهولة إلى الاستعلام والتعافي بدلاً من تحصيل ثانٍ أعمى.

صنف العملية قبل سياسة الإعادة

أسماء طرق HTTP نقطة بداية فقط. يعرّف RFC 9110 في القسم 9.2.2 الطريقة غير مكررة الأثر بحسب أثرها المقصود، ويحذر من إعادة طلب غير آمن تلقائياً ما لم يعرف العميل أن دلالته تسمح بذلك أو يثبت أن الطلب الأصلي لم يطبق.

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

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

مهلة شاملة ومحاولات محدودة

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

يشرح مقال Amazon Builders’ Library عن المهل والإعادات والتراجع مع العشوائية كيف تضخم الإعادات الحمل، ولماذا نحتاج تراجعاً أسياً وعشوائية وميزانية للمحاولات. طبقها في طبقة واحدة. فإذا أعاد العميل والبوابة والخدمة والمكتبة ثلاث مرات، تضاعف الطلب الواحد إلى عشرات استدعاءات المزود.

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

اجعل «مجهول» حالة حقيقية

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

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

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

قاطع الدائرة عند حد المزود

يحمي قاطع الدائرة المتصلين والاعتمادية المتعثرة، لكنه لا يقرر هل تحرك المال. يصف نمط AWS لقاطع الدائرة حالات مغلق ومفتوح ونصف مفتوح مع مجسات تعاف مضبوطة.

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

استجابة تساعد على التعافي

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

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

اختبر كل حد فشل

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

تحقق من عدد الآثار الخارجية لا من استجابات HTTP فقط. راقب المحاولات لكل عملية، وتضخيم الإعادة، وانتهاء المهلة، وحالة القاطع، ومنع الأثر المكرر، وعمر المجهول، ونجاح الاستعلام، وفروقات المطابقة.

القرار المعماري

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

حوّل التعافي إلى عقد قابل للتشغيل

قبل إطلاق نقطة نهاية، أكتب جدولاً يربط كل فئة خطأ بالقرار المسموح للعميل: هل يعيد بالمفتاح نفسه، أم يستعلم عن معرف العملية، أم ينتظر إشعاراً، أم يتوقف لأن النتيجة حاسمة؟ أضع الرمز المقروء آلياً إلى جانب رسالة بشرية واضحة، وأحافظ على المعنى نفسه عبر البوابة ومكتبة العميل وخدمة المجال. لا أسمح لكل طبقة أن تفسر 500 بطريقتها.

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

في التشغيل أربط المقاييس بمعرف العملية: عدد المحاولات، وميزانية الوقت المستهلكة، وحالة القاطع، ومرجع المزود، والإشعارات المستلمة، وقرار المطابقة. أطلق تنبيهاً على نمو عمر المجهول أو تضخم الإعادة أو ارتفاع اختلافات المطابقة، لا على نسبة أخطاء HTTP وحدها. فقد تبدو الواجهة مستقرة بينما تتراكم عمليات مالية بلا حسم.

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

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

قراءات مرتبطة

المراجع

نقاش هندسي

ما القرار الذي كنت ستتخذه؟

شارك سؤالاً أو تجربة أو رأياً مخالفاً. التعليقات متاحة للأعضاء المسجلين للحفاظ على نقاش مهني ومفيد.