المدفوعات RBKmoney تحت غطاء محرك السيارة - منطق منصة الدفع


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


نظرة عامة المنطق والنهج العامة


بشكل عام ، يبدو مخطط العناصر الأساسية لهذا الجزء من المعالجة المسؤول عن المدفوعات كما يلي.



داخل منطقتنا ، نقسم مجالات المسؤولية إلى 3 مجالات:


  • المنطقة الخارجية ، والكيانات الموجودة على الإنترنت ، مثل تطبيقات JS لنموذج الدفع الخاص بنا (تقوم بإدخال تفاصيل بطاقتك هناك) ، والخلفيات للعملاء التاجر لدينا ، وكذلك معالجة بوابات البنوك الشريكة لنا ومقدمي طرق الدفع الأخرى ؛
  • هناك منطقة داخلية يسهل الوصول إليها إلى حد كبير ، حيث توجد خدمات microservices مباشرة ، والتي توفر عمل بوابة الدفع مباشرةً وتدير الخصم من المال ، مع أخذها في الاعتبار في نظامنا والخدمات الأخرى عبر الإنترنت ، والتي تتميز بالمتطلبات "يجب أن تكون متوفرة دائمًا ، على الرغم من أي إخفاقات داخل البلدان النامية" ؛
    • هناك مجال منفصل من الخدمات التي تعمل مباشرة مع البيانات الكاملة لحاملي البطاقات ؛ هذه الخدمات لها متطلبات منفصلة طرحتها وزارة السكك الحديدية وتخضع لشهادة إلزامية بموجب معايير PCI-DSS. سنشرح بمزيد من التفصيل لماذا هذا الفصل أدناه ؛
  • المنطقة الداخلية ، حيث توجد متطلبات أقل لتوافر الخدمات المقدمة أو وقت استجابتها ، بالمعنى الكلاسيكي - هذا مكتب خلفي. على الرغم من ذلك ، بالطبع ، نحاول هنا أيضًا ضمان مبدأ "متاح دائمًا" ، لكننا نبذل جهدًا أقل في هذا الصدد ؛

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


لضمان قابلية التوسع ، نحاول تخزين الحالات في أقل عدد ممكن من الأماكن. الخدمات عديمي الجنسية في الرسم التخطيطي ليس لها اتصالات مع المخازن الثابتة ، الدولة ، على التوالي ، متصلة بها. بشكل عام ، نستخدم العديد من الخدمات المحدودة للتخزين الثابت للدولة - بالنسبة للجزء الرئيسي من المعالجة ، فهذه هي مجموعات Riak KV ، والخدمات ذات الصلة - PostgreSQL ، لمعالجة قائمة الانتظار غير المتزامنة - نستخدم Kafka.


لضمان توفر عالية ، نقوم بنشر الخدمات في العديد من الحالات ، عادةً من 3 إلى 5.


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


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


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


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


يشير فصل ألوان الخدمات الميكروية في الرسم البياني إلى اللغات التي تتم كتابتها بها - باللون الأخضر الفاتح - وهذه هي تطبيقات Java والأزرق الفاتح - Erlang.


تعمل جميع الخدمات في حاويات Docker ، وهي عبارة عن تصميمات CI للبناء وتقع في سجل Docker المحلي. تقوم بنشر الخدمات على إنتاج SaltStack ، والتي يتم تكوينها في مستودع Github الخاص.


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



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


التفاعل مع العالم الخارجي



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


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


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


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


تسجيل النظام الأساسي واجهات برمجة التطبيقات العامة



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


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


بعد المصادقة الناجحة في الخدمة ، يتلقى العميل JWT. سنستخدمها لاحقًا للترخيص - على الجانب Keycloak ، يمكنك تحديد الحقول التعسفية التي تصف الأدوار التي سيتم تضمينها كهيكل بسيط json في JWT وتوقيعها باستخدام المفتاح الخاص للخدمة.


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


عندما توصلنا إلى خطة الإلغاء الرئيسية ، فإن القصة منفصلة وتستحق مشاركتها الخاصة.


لذلك ، لقد تلقينا JWT ، يمكننا استخدامه للمصادقة. هنا مجموعة من microservices Common API تدخل في الاعتبار ، على الرسم البياني الموضح باسم CAPI و CAPI-DSS ، والتي تنفذ الوظائف التالية:


  • إذن من الرسائل المستلمة. يسبق كل مكالمة واجهة برمجة تطبيقات عامة مؤلف Authoriza: Bearer {JWT} رأس HTTP. تستخدم خدمات مجموعة واجهة برمجة التطبيقات (API) الشائعة للتحقق من البيانات الموقعة باستخدام المفتاح العمومي الحالي لخدمة الترخيص ؛
  • التحقق من صحة البيانات المستلمة. نظرًا لأن المخطط يوصف بأنه أحد مواصفات OpenAPI ، والمعروف أيضًا باسم Swagger ، يمكن أن يكون التحقق من صحة البيانات سهلاً للغاية ولديه فرصة ضئيلة في تلقي أوامر التحكم في دفق البيانات. هذا له تأثير إيجابي على أمن الخدمة ككل ؛
  • ترجمة تنسيقات البيانات من REST JSON العامة إلى التوفير الثنائي الداخلي ؛
  • وضع إطار لربط النقل ببيانات مثل trace_id الفريد وتمرير الحدث داخل المنصة إلى خدمة تدير منطق العمل وتعرف ، على سبيل المثال ، الدفع.

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


PCI-DSS وبيانات البطاقة المفتوحة



كما ترون في المخطط ، لدينا مجموعتان من هذه الخدمات - المجموعة الرئيسية ، واجهة برمجة تطبيقات Common ، هي المسؤولة عن معالجة جميع تدفقات البيانات التي لا تحتوي على بيانات حامل البطاقة المفتوحة ، والثانية ، واجهة برمجة تطبيقات PCI-DSS Common ، والتي تعمل مباشرة مع هذه البطاقات. في الداخل ، هي نفسها تمامًا ، لكننا فصلناها فعليًا ورتبناها على قطع مختلفة من الحديد.


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


الفواتير والترقيم



لذلك ، نريد أن نبدأ الدفع وشطب الأموال من بطاقة الدافع.


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


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


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


هذا له تأثير إيجابي على التحويل وتجربة المستخدم.


آلة حالة الفاتورة



داخل المنصة ، تتحول هذه السلسلة إلى تفاعلات على الطريق التالي:


  • قبل تسليم المحتوى إلى متصفحك ، تم دمج عميلنا التجاري مع نظامنا الأساسي وتسجيله معنا وتلقي JWT للحصول على ترخيص ؛
  • من الخلف ، دعا التاجر طريقة createInvoice () ، أي أنه أنشأ فاتورة للدفع في نظامنا الأساسي. في الواقع ، أرسلت الواجهة الخلفية للتاجر طلب HTTP POST للمحتوى التالي إلى نقطة النهاية لدينا:

curl -X POST \ https://api.rbk.money/v2/processing/invoices \ -H 'Authorization: Bearer {JWT}' \ -H 'Content-Type: application/json; charset=utf-8' \ -H 'X-Request-ID: 1554417367' \ -H 'cache-control: no-cache' \ -d '{ "shopID": "TEST", "dueDate": "2019-03-28T17:41:32.569Z", "amount": 6000, "currency": "RUB", "product": "Order num 12345", "description": "Delicious meals", "cart": [ { "price": 5000, "product": "Sandwich", "quantity": 1, "taxMode": { "rate": "10%", "type": "InvoiceLineTaxVAT" } }, { "price": 1000, "product": "Cola", "quantity": 1, "taxMode": { "rate": "18%", "type": "InvoiceLineTaxVAT" } } ], "metadata": { "order_id": "Internal order num 13123298761" } }' 

تمت موازنة الطلب على أحد تطبيقات erlang الخاصة بمجموعة واجهة برمجة التطبيقات (API) ، والتي تحقق من صلاحيته ، وذهب إلى خدمة Bender ، حيث استلم مفتاح العاطل ، ونقله إلى tift وأرسل طلبًا إلى مجموعة خدمات Hellgate. يقوم مثيل Hellgate بإجراء عمليات التحقق من الأعمال ، على سبيل المثال ، تأكد من عدم حظر مالك هذا JWT من حيث المبدأ ، ويمكنه إنشاء فواتير والتفاعل بشكل عام مع النظام الأساسي وبدء إنشاء فاتورة.


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


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


هنا تأتي الخدمة الثالثة ، وهي الرشاشة. يرسل Hellgate Machinegun دعوة إلى "إنشاء آلية" مع حمولة في شكل معلمات الاستعلام. يقوم Machinegun بتنظيم الطلبات المتزامنة ، وباستخدام Hellgate ، يقوم بإنشاء الحدث الأول من المعلمات - InvoiceCreated. التي ثم نفسها ويكتب في رياك وقوائم الانتظار. بعد ذلك ، يتم إرجاع استجابة ناجحة بالترتيب العكسي للطلب الأولي في السلسلة.


باختصار ، يعد Machinegun مثل DBMS مع مؤقتات على أي DBMS آخر ، في الإصدار الحالي من النظام الأساسي - عبر Riak. يوفر لك واجهة تسمح لك بالتحكم في الأجهزة المستقلة ، كما توفر ضمانات للغبطة وترتيب التسجيل. إنها MG التي لن تسمح بتدوين الحدث تلقائيًا من قائمة الانتظار تلقائيًا إذا جاءت عدة HG فجأة مع هذا الطلب.


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


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


بالمناسبة ، تكون أكواد مصدر Machinegun مفتوحة تحت رخصة Apache 2.0 في مستودعنا العام . نأمل أن تكون هذه الخدمة مفيدة للمجتمع.


يتم وصف وصف مفصل لعمل Machinegun ، وبشكل عام ، كيف نقوم بإعداد نظام التوزيع ، إلى وظيفة كبيرة منفصلة ، لذلك لن أتوقف هنا بمزيد من التفاصيل.


الفروق الدقيقة في تفويض العملاء الخارجيين



بعد عملية الحفظ الناجحة ، تقوم Hellgate بإرجاع البيانات إلى CAPI ، والتي تحول الهيكل الثنائي ثلاثي إلى JSON مصممة بشكل جميل ، جاهزة لإرسالها إلى الواجهة الخلفية للتاجر:


 { "invoice": { "amount": 6000, "cart": [ { "cost": 5000, "price": 5000, "product": "Sandwich", "quantity": 1, "taxMode": { "rate": "10%", "type": "InvoiceLineTaxVAT" } }, { "cost": 1000, "price": 1000, "product": "Cola", "quantity": 1, "taxMode": { "rate": "18%", "type": "InvoiceLineTaxVAT" } } ], "createdAt": "2019-04-04T23:00:31.565518Z", "currency": "RUB", "description": "Delicious meals", "dueDate": "2019-04-05T00:00:30.889000Z", "id": "18xtygvzFaa", "metadata": { "order_id": "Internal order num 13123298761" }, "product": "Order num 12345", "shopID": "TEST", "status": "unpaid" }, "invoiceAccessToken": { "payload": "{JWT}" } } 

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


مثال على الأدوار الموضحة داخل JWT مماثلة:


  "resource_access": { "common-api": { "roles": [ "invoices.18xtygvzFaa.payments:read", "invoices.18xtygvzFaa.payments:write", "invoices.18xtygvzFaa:read", "payment_resources:write" ] } } 

يحتوي JWT على عدد محدود من المحاولات لاستخدامه وعمره الذي نهيئه ، والذي يسمح لك بنشره في متصفح دافع. حتى إذا تم اعتراضها ، فإن الحد الأقصى الذي يمكن للمهاجم القيام به هو دفع فاتورة شخص آخر أو قراءة بياناته. علاوة على ذلك ، نظرًا لأن جهاز الدفع لا يعمل ببيانات البطاقة المفتوحة ، فإن الحد الأقصى الذي يمكن للمهاجم رؤيته هو رقم البطاقة المقنّعة من النوع 4242 42** **** 4242 ، ومبلغ الدفع ، وسلة البضائع اختيارياً.


تتيح لك الفاتورة ومفتاح الوصول الذي تم إنشاؤه بدء عملية الدفع. نعطي معرف الفاتورة و JWT الخاص به لمتصفح Payer والتحكم في التحويل إلى تطبيقات JS الخاصة بنا.


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


التوكين وبيانات البطاقة



لكن Checkout لا يعمل مع بيانات البطاقة. كما ذكرنا أعلاه ، نريد تخزين البيانات الحساسة في شكل بيانات حامل البطاقة في أقل عدد ممكن من الأماكن. للقيام بذلك ، ننفذ رمزية.


هذا هو المكان الذي تلعب فيه مكتبة Tokenizer JS. عندما تقوم بإدخال بطاقتك في حقول الإدخال والنقر فوق "الدفع" ، فإنها تعترض هذه البيانات وترسلها إلينا بشكل غير متزامن للمعالجة عن طريق استدعاء طريقة createPaymentResource () .


هذا الطلب متوازن لتطبيقات CAPI-DSS الفردية ، والتي تخوّل الطلب أيضًا ، فقط عن طريق التحقق من الفاتورة JWT ، التحقق من صحة البيانات وإرسالها بواسطة tront إلى خدمة تخزين بيانات البطاقة. في الرسم البياني ، يشار إليه على أنه CDS - تخزين بيانات البطاقة.


الأهداف الرئيسية لهذه الخدمة:


  • تلقي البيانات الحساسة على المدخلات ، في حالتنا - بيانات بطاقتك ؛
  • تشفير هذه البيانات باستخدام مفتاح تشفير البيانات ؛
  • توليد بعض القيمة العشوائية المستخدمة كمفتاح ؛
  • حفظ البيانات المشفرة على هذا المفتاح في نظام Riak الخاص بك ؛
  • إرجاع المفتاح في شكل رمز بيانات الدفع إلى خدمة CAPI-DSS.

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


لم يكن من دون حماية من إمكانية إطلاق النار على نفسك في القدم. هناك احتمال غير صفري بأن يتم نشر JWT خاص ، مصمم لتخويل طلبات من الواجهة الخلفية ، على الويب إلى متصفح العميل. لمنع حدوث ذلك ، أنشأنا الحماية - يمكنك استدعاء أسلوب createPaymentResource () فقط باستخدام مفتاح ترخيص الفاتورة. عند محاولة استخدام منصة JWT خاصة سيعود خطأ HTTP / 401.


بعد إكمال طلب الرمز المميز ، يُرجع Tokenizer الرمز المميز المستلم إلى Checkout وينهي عمله في هذا.


عملية دفع آلة الأعمال



يبدأ Checkout عملية الدفع ، أي أنه يستدعي طريقة createPayment () ، ويمرر الرمز المميز لبيانات البطاقة المستلمة مسبقًا ويبدأ عملية استقصاء الأحداث ، في الواقع ، استدعاء أسلوب getInvoiceEvents () API مرة واحدة في الثانية.


تقع هذه الطلبات من خلال CAPI في Hellgate ، والتي تبدأ في تنفيذ عملية أعمال الدفع ، دون استخدام بيانات البطاقة:


  • بادئ ذي بدء ، يذهب Hellgate إلى خدمة إدارة التكوين - المهيمنة ويتلقى المراجعة الحالية لتكوين المجال. يحتوي على جميع القواعد التي سيتم بها إجراء هذه الدفعة ، والبنك الذي سيذهب إليه للحصول على إذن ، وما هي رسوم المعاملات التي سيتم تسجيلها ، إلخ.
    • من خدمة إدارة الأعضاء ، وهي الآن جزء من HG ، تتعرف على البيانات حول الأرقام الداخلية لحسابات التاجر لصالح الدفع ، وتطبق مقدار الرسوم ، وتضع خطة النشر وتضعها في خدمة Shumway. هذه الخدمة مسؤولة عن إدارة المعلومات حول حركة الأموال على حسابات المشاركين في أي معاملة عند إجراء الدفع. تحتوي خطة النشر على تعليمات "لتجميد الحركة المحتملة للأموال على حسابات المشاركين في المعاملة المحددة في الخطة" ؛
    • يُثري بيانات الدفع بالرجوع إلى خدمات إضافية ، على سبيل المثال ، في Binbase من أجل معرفة بلد البنك المصدر الذي أصدر البطاقة ونوعها ، على سبيل المثال ، "الذهب ، والائتمان" ؛
    • يستدعي خدمة المفتش ، كقاعدة عامة ، هذا هو برنامج مكافحة الاحتيال من أجل الحصول على سجل الدفع واتخاذ قرار بشأن اختيار محطة تغطي مستوى المخاطر الصادر عن التهديف. على سبيل المثال ، يمكن استخدام محطة بدون تأمين ثلاثي الأبعاد للدفعات منخفضة المخاطر ، والدفع الذي تلقى مستوى خطر فادح سينهي حياته على هذا ؛
    • استدعاء خدمة الكشف عن الأخطاء ، و Faultdetector ، وعلى أساس البيانات الواردة منه تحديد مسار الدفع - محول بروتوكول البنك ، والذي يحتوي حاليا على أقل عدد من الأخطاء وأعلى احتمال للدفع الناجح ؛
    • يرسل طلبًا إلى محول بروتوكول البنك المحدد ، فليكن "محول YellowBank" ، "قم بتخويل المبلغ المحدد من هذا الرمز المميز" في هذه الحالة.

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


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


يخطر المحول HG بالتفويض الناجح ، تتم إزالة رمز CVV الخاص بك من خدمة CDS ، وهذه هي نهاية مرحلة التفاعل. إدارة يعود إلى HG.



بناءً على عملية الدفع المحددة بواسطة استدعاء createPayment () من قبل تاجر عملية الدفع التجارية ، تتوقع HG إجراء مكالمات من واجهة برمجة التطبيقات الخارجية إلى طريقة التقاط التفويض ، أي تأكيد سحب الأموال من بطاقتك ، أو القيام بذلك فورًا ، إذا اختار التاجر المخطط الدفع على مرحلة واحدة.


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


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


في وقت التفويض ، المبلغ الذي تم حظره على حسابك بناءً على سعر الصرف في يوم التفويض. نظرًا لأن الدفع قد يكون في حالة "مصرح به" (على الرغم من أن وزارة السكك الحديدية لديها توصيات لفترة أقصاها الآن وهي 3 أيام) لعدة أيام ، فسيتم الحصول على التفويض بمعدل اليوم الذي تم إصداره فيه.


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


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


تجدر الإشارة أيضًا إلى أن أي تغييرات في حالة آلة الفاتورة ، والتي تشمل عملية الدفع ، يتم تسجيلها بواسطة Hellgate في Machinegun ، مما يضمن استمرار البيانات وإثراء الفاتورة بأحداث جديدة.


حالة التزامن لجهاز الدفع وواجهة المستخدم



بينما تجري عملية الدفع الأساسية داخل المنصة ، فإن Checkout يصب في المعالجة عن طريق طلب الأحداث. عند استلام أحداث معينة ، يرسم الحالة الحالية للدفع في نموذج يمكن فهمه لأي شخص - يرسم أداة تحميل مسبقة ، أو يعرض الشاشة "تمت معالجة دفعتك بنجاح" أو "تعذر الدفع ،" أو يعيد توجيه المتصفح إلى صفحة البنك المصدر لإدخال كلمة المرور ثلاثية الأبعاد الآمنة ؛


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


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


تكرار الأحداث في المنطقة دون اتصال



إلى جانب واجهات التحكم في الماكينة ، تنفذ Machinegun خدمة مسؤولة عن تجاوز تدفق الأحداث إلى الخدمات المسؤولة عن مهام النظام الأساسي الأخرى الأقل عبر الإنترنت.


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


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


بشكل عام ، ينتهي تكرار أحداث Machinegun مع التأكيد على أن البيانات قد تم حفظها في Kafka ، وأن المستهلكين متصلون بالفعل بموضوعات Kafka ويقومون بتنزيل قوائم الأحداث التي تهمهم.


نموذج طلب منطقة دون اتصال نموذجي


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


تعمل جميع الخدمات الأخرى المماثلة وفقًا لنفس المنطق ، على سبيل المثال ، خدمة Magista ، المسؤولة عن البحث عن الفواتير والمدفوعات في حساب التاجر الشخصي أو خدمة Hooker ، والتي ترسل عمليات رد اتصال غير متزامنة إلى الواجهة الخلفية للتجار الذين لا يستطيعون لسبب أو لآخر تنظيم أحداث الاقتراع عن طريق الاتصال مباشرة إلى API المعالجة.


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


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


حسنًا ، حول Salt Stack في المرة القادمة ¯\_(ツ)_/¯

Source: https://habr.com/ru/post/ar447440/


All Articles