هذا الدليل موجّه للمطوّرين وفِرَق التكامل التقني الذين يربطون أنظمتهم ببرمجة الفاتورة الإلكترونية من قيود ومنصة فاتورة باستخدام لغة Python. موضوعه واحد: كيف تبني مسار إرسال فاتورة كاملًا بلغة Python، من بناء ترويسة المصادقة حتى تحليل استجابة الهيئة ومعالجة الأخطاء. كل ما يلي قابل للنسخ والتشغيل بعد ضبط القيم الحساسة الخاصة بمنشأتك.
نفترض أنك قرأت بالفعل المفاهيم الأساسية. هذا الدليل لا يشرح ما هي شهادة الختم التشفيري (CSID) ولا الفرق بين المصادقة والإبلاغ، بل يترجم تلك المفاهيم إلى شيفرة Python فعلية. للأساس النظري راجع دليل المصادقة (Authentication) في واجهة الفوترة، ولوصفة الإرسال الكاملة راجع دليل إرسال الفاتورة (Invoice Submission) عبر API، ولقائمة العناوين راجع دليل نقاط نهاية API (Endpoints) لمنصة فاتورة.
هذا الدليل واحد من سلسلة أمثلة عملية تغطي اللغات الأكثر استخدامًا لدى فِرَق التكامل في السعودية. اخترنا Python هنا لأنها لغة سريعة في النماذج الأولية وغنية بمكتبات التشفير والشبكة. المنطق نفسه ينطبق على أي لغة، والاختلاف في الصياغة فقط. إن كنت تعمل بلغة مختلفة، فالخطوات الست التي نمرّ عليها هنا ثابتة لا تتغيّر، وما يتغيّر هو اسم المكتبة وطريقة استدعاء الدالة.
قبل أن نغوص في الشيفرة، يهمّنا أن نضع حدودًا واضحة لما يغطّيه هذا الدليل. نحن نفترض أن مستند UBL جاهز وموقّع لديك. بناء المستند نفسه وتوقيعه رقميًا موضوع واسع له أدواته ومكتباته، وقد فصّلناه في أدلة أخرى من السلسلة. ما نركّز عليه هنا هو ما يأتي بعد التوقيع: كيف تحوّل مستندًا موقّعًا إلى طلب HTTP صحيح، وكيف ترسله، وكيف تقرأ ما يعود منه. هذا هو الجزء الذي يتعثّر فيه أغلب المطوّرين، لأن خطأً صغيرًا في ترميز أو ترويسة يُترجَم إلى رفض غامض من البوابة.
لماذا Python خيار عملي للتكامل مع منصة فاتورة؟
تجمع Python بين بساطة القراءة وقوة المكتبات الجاهزة. مكتبة requests تختصر طلبات HTTP إلى أسطر قليلة، ووحدتا hashlib وbase64 جزء من المكتبة القياسية، فلا تحتاج تثبيت أي شيء لحساب التجزئة أو الترميز. هذا يجعل Python مناسبة لبناء نموذج أولي للتكامل خلال ساعات، ثم تطويره إلى خدمة إنتاجية لاحقًا.
تذكّر أن منصة فاتورة لا تعرف بأي لغة كُتب نظامك. ما يصل البوابة هو طلب HTTP يحمل ترويسات وجسمًا بصيغة JSON. مهمتك أن تبني هذا الطلب بشكل صحيح. كل ما يلي يركّز على هذه النقطة: تحويل بيانات الفاتورة إلى طلب تقبله الهيئة، وقراءة ما يعود منها.
قبل أن تبدأ، ثبّت المكتبة الوحيدة الخارجية التي نحتاجها. باقي الأدوات موجودة في Python القياسية.
نوصي باستخدام بيئة Python افتراضية معزولة لكل مشروع تكامل، حتى لا تتعارض إصدارات المكتبات بين مشاريعك. هذا يحميك من مفاجآت يصعب تشخيصها لاحقًا في بيئة الإنتاج. اضبط أيضًا إصدارًا محددًا لمكتبة requests في ملف الاعتماديات، حتى لا يتغيّر سلوك خدمتك فجأة عند تحديث تلقائي للمكتبة.
ننصحك كذلك بفصل شيفرة التكامل عن منطق عملك من البداية. اجعل الدوال التي تبني الترويسة وتحسب التجزئة وترسل الطلب في وحدة مستقلة. هذا الفصل يسهّل اختبار كل دالة على حدة، ويتيح لك تبديل بيئة الاختبار بالإنتاج بتغيير الإعدادات فقط، بلا لمس منطق الإرسال. التكامل الذي يُكتب بهذا الانضباط أسهل في الصيانة عندما تتطوّر متطلبات الهيئة لاحقًا.
الصورة الكبيرة: ست خطوات بين المستند الموقّع والنتيجة
قبل أن نكتب أي دالة، لنرسم المسار كاملًا في الذهن. إرسال فاتورة واحدة ليس طلبًا منفردًا، بل سلسلة تحويلات مترابطة. تبدأ بمستند UBL موقّع، وتمرّ بحساب التجزئة، ثم الترميز، ثم بناء الترويسة، ثم الإرسال، وتنتهي بتحليل الاستجابة وحفظ النتيجة. كل خطوة تعتمد على ما قبلها، وأي خلل في الترتيب يُنتج رفضًا من الهيئة.
الترتيب ليس اختياريًا. حساب التجزئة يجب أن يأتي على المحتوى النهائي الموقّع، لأن أي تعديل لاحق يُبطل القيمة. وبناء جسم الطلب يحتاج المستند مرمّزًا بـ Base64. ولهذا نتعامل مع الخطوات كخطّ إنتاج صارم: مخرَج كل خطوة هو مدخَل التالية. سنمرّ على كل واحدة بدالة Python مستقلة، ثم نجمعها في النهاية في دالة واحدة قابلة للاستدعاء من خدمتك.
الخطوة الأولى: بناء ترويسة المصادقة الأساسية
كل طلب ترسله لمنصة فاتورة يجب أن يحمل ترويسة Authorization من نوع Basic. تتكوّن هذه الترويسة من معرّف الشهادة (CSID) وسرّه المرافق، يفصل بينهما نقطتان رأسيتان، ثم تُرمَّز النتيجة بـ Base64. انتبه إلى أنها CSID وليست أي اختصار آخر. خطأ حرف واحد هنا يعني رفض الطلب على البوابة برمز الحالة 401 قبل أن ينظر النظام في محتوى الفاتورة.
المعرّف الذي تستخدمه في بيئة الاختبار هو معرّف الامتثال (Compliance CSID). بعد إنهاء مرحلة الإصدار تنتقل إلى معرّف الإنتاج (Production CSID). الشيفرة نفسها لا تتغيّر، يتغيّر العنوان الأساسي والمعرّف فقط. لا تكتب القيم الحساسة داخل الشيفرة مباشرة، بل اقرأها من متغيّرات البيئة كما في المثال التالي.
دمج csid:secret
ترميز Base64
إضافة البادئة Basic
الكود التالي يبني ترويسة المصادقة من متغيّرات البيئة:
لاحظ أننا نقرأ FATOORA_CSID وFATOORA_SECRET من متغيّرات البيئة. هذا يفصل القيم الحساسة عن الشيفرة المصدرية، فلا تتسرّب بياناتك إلى مستودع الكود. ضع هذه القيم في خدمة إدارة أسرار أو في متغيّرات بيئة الخادم، لا في ملف نصي داخل المشروع.
دالة build_auth_header تجمع المعرّف والسرّ بنقطتين رأسيتين بينهما، ثم تحوّلهما إلى بايتات بترميز UTF-8، ثم تطبّق Base64. هذه هي القاعدة التي تتكرّر في كل لغة، والاختلاف في أسماء الدوال فقط.
نقطة دقيقة كثيرًا ما تُهمَل: الترميز هنا UTF-8 وليس أي ترميز آخر. إذا كان معرّفك أو سرّك يحوي محارف خاصة، فترميز خاطئ ينتج ترويسة لا تطابق ما تتوقّعه البوابة. التزم دائمًا UTF-8 عند تحويل النص إلى بايتات قبل تطبيق Base64. هذه عادة جيدة تجنّبك أخطاء يصعب تشخيصها لاحقًا.
تذكّر كذلك الفرق الجوهري بين دور CSID في المصادقة ودورها في التوقيع. في المصادقة نرسل معرّف الشهادة وسرّه في الترويسة لإثبات أن المُرسِل جهاز مسجّل لدى الهيئة. أما في التوقيع فنستخدم المفتاح الخاص المرتبط بالشهادة لإنشاء الختم داخل الـ XML. المفتاح الخاص لا يُرسل أبدًا في أي ترويسة، بل يبقى محليًا في نظامك. الخلط بين الدورين مصدر شائع للأخطاء الأمنية، فاحرص على فصلهما في تصميمك.
الخطوة الثانية: حساب تجزئة الفاتورة (invoiceHash)
بعد بناء مستند UBL وتوقيعه، تحسب قيمة التجزئة (invoiceHash) باستخدام خوارزمية SHA-256. تُحسب التجزئة على المحتوى النهائي للمستند، لأن أي تعديل لاحق على الـ XML يُبطل القيمة. هذه التجزئة جزء من سلسلة مترابطة، إذ تدخل تجزئة الفاتورة السابقة في حساب الفاتورة التالية. لهذا يجب حفظ كل تجزئة فور إصدارها.
الناتج الذي ترسله للهيئة هو تمثيل Base64 لقيمة التجزئة الثنائية، لا التمثيل الست عشري (hex) النصي. هذا فرق دقيق يقع فيه كثير من المطوّرين فيحصلون على رفض غير مفهوم. الدالة التالية تحسب التجزئة بالطريقة الصحيحة.
انتبه إلى استدعاء .digest() لا .hexdigest(). الأول يعيد البايتات الثنائية التي نرمّزها بعدها بـ Base64، وهو ما تتوقّعه الهيئة. الثاني يعيد سلسلة hex نصية ترفضها البوابة. هذا أكثر خطأ شائع في حساب التجزئة.
سبب وجود التجزئة أصلًا هو إثبات سلامة الفاتورة. التجزئة بصمة فريدة للمحتوى. لو تغيّر بايت واحد في المستند بعد توقيعه، لتغيّرت البصمة كليًا، فتكتشف الهيئة العبث فورًا. لهذا نحسب التجزئة على المحتوى النهائي بالضبط، بعد التوقيع لا قبله. أي مسافة بيضاء زائدة أو تعديل على تنسيق الـ XML بعد التوقيع يغيّر التجزئة، فتُرفض الفاتورة.
هناك بُعد آخر للتجزئة لا يقلّ أهمية: ترابط السلسلة. كل فاتورة تحمل تجزئة سابقتها ضمن بياناتها، فتتكوّن سلسلة مترابطة تمنع حذف فاتورة من المنتصف أو إعادة ترتيبها دون أن يظهر الكسر. عمليًا هذا يعني أنك ملزَم بحفظ تجزئة كل فاتورة فور حسابها، لأنها مدخل إلزامي للفاتورة التالية. سنعود إلى هذه النقطة عند تجميع المسار في دالة واحدة، لأنها من أكثر الأخطاء التي تكلّف فِرَق التكامل وقتًا في التشخيص.
الخطوة الثالثة: ترميز مستند UBL بـ Base64
جسم الطلب الذي ترسله للبوابة يحمل المستند الموقّع مرمّزًا بـ Base64 داخل حقل JSON. لا ترسل الـ XML الخام، بل نسخته المرمّزة. الترميز هنا ليس تشفيرًا، بل تحويل البايتات الثنائية إلى نص آمن للنقل داخل JSON.
الآن لديك ثلاث قيم جاهزة: ترويسة المصادقة، وتجزئة الفاتورة، والمستند المرمّز. هذه هي مدخلات الطلب الذي سترسله في الخطوة التالية.
يخلط بعض المطوّرين بين الترميز والتشفير، فيظنّون أن Base64 يحمي بيانات الفاتورة. هذا غير صحيح. Base64 ترميز نصي قابل للعكس يقرأه أي طرف، وغرضه نقل البايتات الثنائية بأمان داخل JSON، لا إخفاؤها. حماية بيانات الفاتورة أثناء النقل تأتي من قناة HTTPS المشفّرة، وسلامتها تأتي من التوقيع الرقمي والتجزئة. لا تعتمد على Base64 لأي غرض أمني.
الخطوة الرابعة: اختيار المسار وإرسال الطلب
منصة فاتورة تفرّق بين مسارين بحسب نوع الفاتورة. الفواتير الضريبية الكاملة بين المنشآت (B2B) تمرّ بمسار المصادقة (Clearance)، إذ تُصادق الهيئة الفاتورة قبل تسليمها للمشتري. الفواتير الضريبية المبسّطة للمستهلك (B2C) تمرّ بمسار الإبلاغ (Reporting)، إذ تُبلَّغ الهيئة بها خلال مهلة محدّدة بعد إصدارها. المسار النسبي نفسه يُستدعى تحت العنوان الأساسي للبيئة التي تعمل فيها، فالفرق بين الاختبار والإنتاج هو العنوان الأساسي والمعرّف، لا المسار.
| المعيار | Clearance (B2B) | Reporting (B2C) |
|---|---|---|
| النقطة | clearance/single | reporting/single |
| Clearance-Status | 1 | 0 |
| التوقيت | قبل التسليم | خلال 24 ساعة |
الكود التالي يجمع الترويسات وجسم الطلب ويرسله بمكتبة requests. غيّر العنوان الأساسي والمسار النسبي بحسب بيئتك ونوع الفاتورة:
لاحظ ضبط timeout=30 في الاستدعاء. الطلب بلا مهلة قد يعلّق خدمتك إلى الأبد إذا تأخّرت البوابة. حدّد دائمًا مهلة معقولة، وعالج تجاوزها بإعادة المحاولة كما في القسم اللاحق. لاحظ كذلك ترويسة Accept-Version التي تحدّد إصدار الواجهة، وهي ترويسة تطلبها البوابة في كل استدعاء.
الفرق بين المسارين أعمق من اختلاف نقطة النهاية. في مسار المصادقة تنتظر ردّ الهيئة قبل تسليم الفاتورة للمشتري، لأن الفاتورة لا تُعدّ نافذة حتى تُصادَق. هذا يفرض على نظامك أن يتعامل مع المصادقة جزءًا من تدفّق إصدار الفاتورة نفسه، لا خطوة لاحقة. أما في مسار الإبلاغ فالفاتورة تصدر فورًا للمستهلك، ثم تُبلَّغ الهيئة بها خلال المهلة المقرّرة. هذا يمنحك مرونة في تجميع فواتير B2C وإرسالها دفعة لاحقة، لكنه يحمّلك مسؤولية ألا تتجاوز المهلة.
عمليًا، صمّم نظامك ليعرف نوع كل فاتورة قبل الإرسال، ويوجّهها إلى المسار الصحيح تلقائيًا. لا تترك اختيار المسار قرارًا يدويًا، لأن خطأً واحدًا هنا يعني محاولة مصادقة فاتورة مبسّطة أو إبلاغ فاتورة كاملة، وكلاهما يُرفَض. اربط نوع الفاتورة بالمسار في طبقة واحدة واضحة من شيفرتك.
الخطوة الخامسة: تحليل الاستجابة ومعالجة الأخطاء
عودة الطلب لا تعني نجاح الفاتورة بالضرورة. عليك أن تقرأ رمز الحالة أولًا، ثم تحلّل جسم JSON. الهيئة تعيد كائنًا يحوي حالة المصادقة أو الإبلاغ، إضافة إلى قائمتي تحذيرات وأخطاء. فاتورة قد تُقبل مع تحذيرات، وأخرى قد تُرفض مع أخطاء تشرح السبب. عالج الحالتين بوضوح.
القاعدة العملية: رمز 2xx مع حالة CLEARED أو ما يقابلها في الإبلاغ يعني نجاحًا. رمز 401 يعني خطأ في المصادقة، فراجع المعرّف والسرّ. رمز 400 يعني خطأً في بنية الفاتورة، اقرأ errorMessages لتعرف السبب الدقيق. القيم في المثال التالي توضيحية لشكل الاستجابة.
المثال يقرأ validationResults ويفصل التحذيرات عن الأخطاء. التحذير لا يمنع قبول الفاتورة، أما الخطأ فيمنعها، ويحمل رمزًا ورسالة تشرحان المشكلة. اطبع هذه الرسائل أو سجّلها، لأنها مفتاحك لتشخيص أي رفض بسرعة بدل التخمين.
تعامَل مع التحذيرات بجدية رغم أنها لا تمنع القبول. التحذير اليوم قد يصبح خطأً مانعًا في إصدار لاحق من قواعد الهيئة. إن تجاهلت التحذيرات وراكمتها، فقد تستيقظ يومًا على رفض جماعي لفواتيرك بعد تحديث في البوابة. اجعل مراجعة التحذيرات جزءًا من روتين متابعتك، وأصلح أسبابها مبكرًا.
من المفيد أن تبني خريطة لرموز الأخطاء الشائعة التي تقابلها، تربط كل رمز بسببه وإصلاحه. الرفض رقم 401 يقودك إلى المصادقة. الرفض رقم 400 يقودك إلى بنية المستند أو قيمة التجزئة. مع الوقت تتراكم لديك معرفة تحوّل كل رفض من لغز يستهلك ساعات إلى مشكلة معروفة الحلّ. هذه الخريطة من أثمن ما تبنيه فِرَق التكامل الناضجة.
الأخطاء الشائعة التي تسبّب الرفض
قبل أن ننتقل إلى إعادة المحاولة، يستحق الأمر أن نجمع أكثر أسباب الرفض شيوعًا في مكان واحد، لأن معرفتها مسبقًا توفّر عليك ساعات تشخيص. أولها استخدام hexdigest بدل digest عند حساب التجزئة، فينتج تمثيل نصي ترفضه البوابة. ثانيها تعديل الـ XML بعد التوقيع، ولو بمسافة بيضاء، فتتغيّر التجزئة ويُبطَل التوقيع.
ثالثها الخلط بين معرّف الامتثال ومعرّف الإنتاج، فترسل إلى بيئة الإنتاج بمعرّف اختبار أو العكس. رابعها كسر سلسلة التجزئة بإهمال حفظ تجزئة الفاتورة السابقة. خامسها توجيه الفاتورة إلى المسار الخطأ، كمحاولة مصادقة فاتورة مبسّطة. سادسها نسيان ترويسة Accept-Version أو وضع قيمة خاطئة فيها. راجع هذه القائمة كلما واجهت رفضًا غامضًا، فغالبًا السبب واحد منها.
الخطوة السادسة: إعادة المحاولة بتراجع أُسّي
الشبكة ليست مثالية. قد ترجع البوابة رمز 502 أو تتأخّر فتنتهي المهلة. في هذه الحالات أعد المحاولة بدل أن تفشل فورًا، لكن لا تُعد فورًا وبلا توقّف، فذلك يزيد الضغط على البوابة. الأسلوب الصحيح هو التراجع الأُسّي (Exponential Backoff): تزيد الفترة بين كل محاولة وأختها.
انتبه إلى نقطة مهمة: أعد المحاولة فقط على الأخطاء المؤقتة مثل 502 و503 وانتهاء المهلة. لا تُعد المحاولة على 400 أو 401، لأنها أخطاء في طلبك لا تُحل بالتكرار. تكرار طلب خاطئ يبقى خاطئًا.
الفترة تبدأ بثانية ثم تتضاعف: 1 ثم 2 ثم 4 ثم 8 ثوانٍ. هذا يمنح البوابة وقتًا للتعافي ويقلّل الضغط عليها. في الإنتاج يُفضّل إضافة عشوائية بسيطة (Jitter) إلى الفترة حتى لا تتزامن إعادة المحاولات من عدة عمليات في اللحظة نفسها.
انتبه إلى مسألة دقيقة في إعادة المحاولة مع الفواتير: قد ينجح الطلب فعلًا على البوابة، لكن تنقطع الاستجابة في طريق العودة، فتظنّه فاشلًا وتعيده. هذا يخلق خطر إرسال الفاتورة مرتين. لتجنّب ذلك، أرسل معرّفًا فريدًا ثابتًا لكل فاتورة، حتى تتعرّف البوابة على الطلب المكرّر فلا تعالجه مرتين. هذا ما يسمّى مبدأ العملية المتكافئة (Idempotency)، وهو ضروري لأي مسار إرسال جادّ.
لا تجعل عدد المحاولات كبيرًا بلا حدّ. أربع محاولات بتراجع أُسّي كافية في معظم الحالات. إن فشل الطلب بعدها، فالأرجح أن المشكلة ليست عابرة، بل عطل أطول في البوابة أو في شبكتك. عند هذه النقطة سجّل الفشل في طابور للمعالجة اليدوية أو التلقائية لاحقًا، بدل أن تستمرّ في المحاولة بلا جدوى وتستهلك موارد خدمتك.
تجميع المسار في دالة واحدة
بعد أن فهمت كل خطوة على حدة، إليك كيف تتسلسل معًا في مسار واحد قابل للاستدعاء. الدالة التالية تأخذ المستند الموقّع ومعرّفه الفريد، وتمرّ بكل الخطوات حتى تعيد نتيجة الهيئة. هذا هو الهيكل الذي تبني عليه خدمتك الإنتاجية.
لاحظ السطر الأخير: حفظ التجزئة. هذه ليست خطوة اختيارية. كل فاتورة جديدة تعتمد على تجزئة سابقتها في سلسلة مترابطة. من يهمل حفظ التجزئة يكسر السلسلة، فترفض الهيئة الفاتورة التالية. ابنِ طبقة تخزين موثوقة قبل أن ترسل أول فاتورة إنتاجية.
بناء ملف UBL والتوقيع
حساب التجزئة SHA-256
ترميز Base64 وبناء ترويسة Basic
POST للمقاصة أو الإبلاغ
قراءة الاستجابة وحفظ النتيجة
أفضل الممارسات قبل الانتقال إلى الإنتاج
الشيفرة أعلاه أساس صالح، لكن خدمة الإنتاج تحتاج طبقات إضافية. اعزل القيم الحساسة في خدمة إدارة أسرار، لا في متغيّرات بيئة مكشوفة. سجّل كل طلب واستجابة في نظام سجلّات منظّم، حتى تتمكّن من تشخيص أي رفض بعد وقوعه. اختبر مسارك كاملًا في بيئة الاختبار بمعرّف الامتثال حتى تنجح كل العيّنات قبل أن تنتقل إلى معرّف الإنتاج.
راقب أيضًا حدود المعدّل (Rate Limits). إن أرسلت دفعة كبيرة من الفواتير دفعة واحدة قد تصطدم بحدّ البوابة. وزّع الإرسال على فترات، واستفد من منطق إعادة المحاولة لاستيعاب أي بطء مؤقت. التكامل الناجح ليس الذي يرسل فاتورة واحدة بنجاح، بل الذي يصمد أمام آلاف الفواتير وحالات الفشل المتنوّعة.
ابنِ مسارك على بيئة الاختبار أولًا، وأرسل فيها فواتير تجريبية تغطّي كل الحالات: فاتورة كاملة، فاتورة مبسّطة، فاتورة بأصناف متعدّدة، فاتورة بخصم، وفاتورة دائنة. لا تكتفِ بحالة واحدة ناجحة. الحالات الحدّية هي التي تكشف ثغرات مسارك قبل أن تكتشفها في الإنتاج أمام عملائك. عامِل بيئة الاختبار كأنها إنتاج مصغّر.
أخيرًا، راقب خدمتك بعد إطلاقها. اجمع مقاييس بسيطة: نسبة الفواتير المقبولة، ومتوسّط زمن الاستجابة، وعدد حالات إعادة المحاولة. هذه المقاييس تنبّهك مبكرًا إلى تدهور قبل أن يتحوّل إلى أزمة. التكامل ليس مشروعًا ينتهي عند أول فاتورة ناجحة، بل خدمة حيّة تحتاج متابعة مستمرة مع تطوّر متطلبات الهيئة.
تذكّر أخيرًا أن منصة قيود تتولّى عنك كل هذه الطبقة التقنية إن لم ترغب في بنائها بنفسك. هذا الدليل موجّه لمن يبني تكاملًا مخصّصًا. أما إن كنت صاحب منشأة تبحث عن إصدار فواتير متوافقة مع هيئة الزكاة والضريبة والجمارك بلا كتابة سطر برمجي واحد، فنظام قيود يصدرها ويربطها بالهيئة مباشرة.
فوترة إلكترونية متوافقة بلا كتابة أي شيفرة
يصدر قيود فواتيرك الإلكترونية ويربطها بمنصة فاتورة مباشرة، بلا بناء تكامل تقني. جرّب المنصة وأصدر أول فاتورة متوافقة في دقائق.
الخلاصة العملية
بنينا في هذا الدليل مسار إرسال فاتورة كاملًا بلغة Python: ترويسة مصادقة Basic من CSID وسرّه، تجزئة SHA-256 مرمّزة بـ Base64، مستند UBL مرمّز، طلب POST بمكتبة requests، تحليل للاستجابة، وإعادة محاولة بتراجع أُسّي. كل دالة قابلة للنسخ والتكييف على نظامك.
إن كنت تبني التكامل بلغة أخرى، فالمنطق ثابت والصياغة فقط تختلف. راجع الأمثلة المكافئة في بقية لغات السلسلة، ثم عُد إلى أدلة المصادقة وإرسال الفاتورة ونقاط النهاية كلما احتجت تفصيلًا أعمق لأي خطوة.