أريد الحديث عن تقاطع فوترة الاتصالات وJava EE وGWT وSalesforce.com - تركيبة من منتصف 2013 يجب أن تُرفق بلوحة مزاجية من الـflat design الناشئ والجميع يتجادل حول ما إذا كانت CSS المتجاوبة موضة عابرة. لكن إليك الحقيقة: شحنت برمجيات حقيقية في هذا الـstack لمشغّلي اتصالات حقيقيين يعالجون أموالاً حقيقية. وكمية غير قليلة مما تعلمته في ذلك البيئة لا تزال قابلة للتطبيق اليوم، لأن المشاكل الأساسية هيكلية لا تقنية.

BluLogix بنت Cloud Innovation Suite - منصة فوترة سحابية لمشغّلي الاتصالات. دوري كان تطوير الـbackend والإشراف على الـfrontend وتصميم سير العمل بـBPMN، والأكثر تعليمية: تكامل CIS مع Salesforce.com عبر Talend ETL. هذا الأخير هو ما أريد قضاء معظم هذه التدوينة فيه، لأنه حيث أصبحت الهندسة ممتعة فعلاً.

كيف تبدو فوترة الاتصالات فعلاً

قبل أن تفهم لماذا تكامل Salesforce صعب لنظام فوترة اتصالات، تحتاج نموذجاً تقريبياً لما هي فوترة الاتصالات فعلاً.

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

هذا هو السبب في وجود أنظمة فوترة الاتصالات كفئة برمجيات متخصصة. لا يمكنك فعل هذا في جدول بيانات. لا يمكنك فعله في QuickBooks. نموذج البيانات مختلف جذرياً عن برمجيات المالية العامة.

GWT - Google Web Toolkit - كان الطريقة التي تبني بها واجهات ويب غنية بـJava في 2013 إذا أردت أن يكون كود الـUI آمن النوع وقابلاً للاختبار ومكتوباً من مهندسي Java غير المطلوب منهم معرفة JavaScript بعمق. كتبت Java، صرّف GWT ذلك إلى JavaScript، ومدقق النوع في IDE الخاص بك كان يعمل عبر الـstack بأكمله. في 2013، قبل وجود TypeScript وقبل نضج أُطر الـfrontend الحديثة، كان هذا تبادلاً معقولاً فعلاً. مخرجات JavaScript كانت مطوّلة ودورة التصحيح كانت بطيئة، لكن تجربة المطوّر لفرق مُمركزة على Java كانت أفضل من البديل: JavaScript خام كان مهندسو Java يتعاملون معه بنفس مستوى الحماس الذي يحملونه تجاه PHP. GWT ميت الآن. لا بأس. في 2013، في متجر Java EE يبني برمجيات مؤسسية، كانت الأداة الصحيحة.

لماذا تكره Salesforce نظام الفوترة الخاص بك

نموذج بيانات Salesforce مبني حول تجريد CRM: حسابات وجهات اتصال وفرص ومنتجات. هذا النموذج يعمل بشكل رائع لعمليات المبيعات. إنه ملاءمة بائسة لفوترة الاتصالات.

مثال محدد. في Salesforce، الحساب شركة. الفرصة بيع محتمل. المنتج شيء تبيعه. حين تُغلَق الفرصة، تصبح طلباً، والمنتجات تصبح جزءاً من ذلك الطلب.

في نظام فوترة اتصالات، “العميل” قد يكون لديه حسابات متعددة (واحد لكل شركة تابعة)، كل منها مع اشتراكات متعددة، كل اشتراك يحتمل أن يتألف من حزم خدمات متعددة، كل حزمة خدمات تحتوي على مكونات مُصنَّفة متعددة بدورات فوترة وطبقات تسعير مختلفة. العلاقة بين “ما باعه فريق المبيعات” و”ما يُصنِّفه نظام الفوترة ويفوتره” هي many-to-many بطرق لا يمثلها ببساطة الـObjects القياسية في Salesforce.

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

تحديداً في BluLogix، كنا نستخدم Talend Open Studio لطبقة ETL. Talend هي أداة ETL مرئية: تبني تدفقات البيانات كرسوم بيانية موجّهة من مكونات تحويل، وتولّد Talend الـJava code الأساسي. النموذج المرئي مفيد لأصحاب المصلحة الذين يحتاجون فهم منطق التكامل والموافقة عليه. الكود المُولَّد هو ما يعمل فعلاً. الفجوة بين “ما وافق عليه صاحب المصلحة في النموذج المرئي” و”ما الحالات الحدية التي يصطدم بها الكود المُولَّد الساعة 3 صباحاً في أول يوم من دورة الفوترة” - هناك تكسب راتبك.

BPMN لسير عمل الفوترة

منصة CIS استخدمت BPMN لتعريفات العمليات التجارية - وليس بالصدفة، نفس نموذج سير العمل الذي استخدمته لاحقاً في Talentera مع Camunda. فوترة الاتصالات لها حالة شرطية معقدة: اشتراك يمكن أن يكون نشطاً، موقوفاً (عدم الدفع)، موقوفاً (طلب العميل)، منتهياً، محمولاً، منقولاً. الانتقالات بين الحالات لها قواعد أعمال: لا يمكنك إعادة تفعيل اشتراك منتهٍ، الإيقاف بسبب عدم الدفع يُشغّل تدفق إعادة تفعيل مختلف عن الإيقاف الطوعي. هذه القواعد تختلف بحسب الولاية القضائية ونوع المنتج.

BPMN هي لغة النمذجة الصحيحة لهذا. البديل هو منطق حالة آلة مُرمَّز بشكل صلب مضمّن في محرك الفوترة، مما يعني أن كل تغيير في القاعدة هو نشر كود. مع BPMN، تغيير سير عمل الإيقاف-إلى-التفعيل لسوق تنظيمي محدد هو نشر تعريف عملية، لا نشر كود. يمكن لفريق الامتثال مراجعة مخطط BPMN مباشرة بدلاً من قراءة Java. هذه ليست ميزة نظرية - جداول مراجعة الامتثال تُقاس بالأسابيع، و”نحتاج إعادة نشر محرك الفوترة لتحديث هذا سير العمل” يضيف أسابيع لكل تغيير في الامتثال.

طبقة Spring Security تعاملت مع التحكم في الوصول عبر الخدمات الداخلية لمنصة الفوترة. Spring WS غطّى واجهات خدمة SOAP - في 2013، SOAP لا تزال اللغة المشتركة للتكامل المؤسسي، ومشغّلو الاتصالات الأكبر الذين استهدفتهم المنصة لديهم middleware يتحدث SOAP ويتوقع WSDL. واجهة GWT تحدثت إلى نقاط نهاية Spring MVC. كانت هذه معمارية Java EE قياسية لتلك الحقبة. مملّة بالتصميم.

عمل ETL الذي أهمّ فعلاً

تكامل Salesforce القائم على Talend كان له متطلب جوهري واحد: حين تُغلق صفقة مبيعات في Salesforce (الفرصة تنتقل إلى Closed Won)، يجب إنشاء الاشتراك المقابل وإعداد الفوترة في CIS دون إدخال بيانات يدوي. إدخال البيانات اليدوي في فوترة الاتصالات هو حيث يحدث تسريب الإيرادات. إعداد خصم مفقود، تاريخ دورة فوترة خاطئ، حزمة منتجات مُكوَّنة بشكل غير صحيح - هذه ليست أخطاء تتسبب في تعطل البرنامج. تسبّب في فواتير غير صحيحة. الفواتير الغير صحيحة تولّد نزاعات. النزاعات تكلّف وقتاً وتنتهك ثقة العميل. في الاتصالات حيث تبلغ العقود المؤسسية ملايين الدولارات سنوياً، الفوترة غير الصحيحة وجودية.

مهمة Talend التي تعاملت مع هذا عملت على جدول، تستطلع Salesforce عبر SOAP API (لاحقاً REST API حين وسّعت Salesforce سطح API الخاص بها)، تسحب الفرص في حالة Closed Won التي لم تُوفَّر بعد في CIS، تحوّل الفرصة وبيانات المنتج المرتبطة إلى كائنات اشتراك CIS، تُنشئ إعداد الفوترة، وتُعلّم السجل كموفَّر. معالجة الأخطاء كانت أكثر تعقيداً من المسار السعيد: الفشل الجزئي يحتاج أن يكون قابلاً لإعادة المحاولة دون إنشاء اشتراكات مكررة. نموذج التزامن في Salesforce للعمليات المجمّعة كان يحتاج الاحترام. نموذج معاملة CIS كان يحتاج ضمان الذرية عبر إنشاء الاشتراك وإعداد الفوترة.

الجزء الذي لم يُخبرني به أحد قبل البدء: نموذج بيانات Salesforce أكثر تقلباً مما تُشير إليه وثائق API. منظمات Salesforce المختلفة، التي هيأها مدراء مختلفون على فترات مختلفة، لها تخطيطات حقول مختلفة وحقول مخصصة مختلفة وقواعد تحقق مختلفة. تكامل يعمل بشكل مثالي مع منظمة واحدة يحتاج إعادة التحقق مع كل منظمة يُنشَر لها. بنينا خطوة تحقق في مهمة Talend تتحقق من شكل البيانات المصدر قبل محاولة التحويل، حتى تظهر الفشل كأخطاء جودة بيانات لا كسجلات CIS تالفة. تلك الخطوة أنقذتنا من حادثة بيانات تقريباً لكل نشر.

عن الشحن لعملاء اتصالات يدفعون فعلاً

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

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

عالجت أحداث فوترة اتصالات حقيقية. شحنت تكاملاً نقل بيانات عملاء حقيقية بين نظام فوترة وCRM. فعلت ذلك بـGWT وJava EE وTalend وBPMN، مع Spring Security وSpring WS وعالم ثقيل بـXML يبدو الآن قديماً.

العالم ليس مختلفاً كثيراً. Salesforce لا تزال تمتلك نفس الاختلافات في نموذج البيانات مع كل نظام متخصص تحاول التكامل معه. أنظمة الفوترة لا تزال آلات حالة مدفوعة بالأحداث في جوهرها. BPMN لا تزال الأداة الصحيحة لسير العمل المدفوع بالامتثال. تغيّر stack التقنية. المشاكل هي نفسها.

أعرف كيف أعمل في الـstack القديم. أعرف لماذا اتخذ الاختيارات التي اتخذها. هذا أندر مما يبدو.