ترميز Base64 في نظام الفوترة الوطني هو الخطوة التي يتحول فيها ملف الفاتورة بصيغة XML إلى نص واحد يوضع داخل طلب بصيغة JSON، قبل أن يرسله برنامجك إلى نظام الفوترة الوطني لدى دائرة ضريبة الدخل والمبيعات. فالنظام لا يستقبل ملف XML كما هو، بل يستقبله مرمّزًا في جسم الطلب تحت مفتاح واحد اسمه invoice.
يشرح هذا المقال موقع هذه الخطوة في مسار الإرسال كما يرسمه الدليل التقني للربط (الإصدار 1.5)، وما يذهب إلى ترويسة الطلب وما يذهب إلى جسمه، وخطوات تجهيز الجسم بالترتيب، والأخطاء التي تتجنبها عند الترميز، وما يعود إليك في الرد. والمقال يصف الخطوات ولا يقدم شيفرة جاهزة، لأن أي شيفرة لم تُجرَّب على النظام نفسه لا تصلح مرجعًا.
ترميز Base64 في نظام الفوترة الوطني ومكانه في مسار الإرسال
يرسم الدليل التقني الصادر عن الدائرة مسار إرسال الفاتورة في مخطط واحد (ص9). يبدأ المسار من نظام المكلف، أي البرنامج الذي يصدر الفاتورة، وينتهي في نظام الفوترة الوطني (JoFotara)، وبينهما ثلاث محطات.
- الفاتورة الإلكترونية. لها ترويسة (Header) تحمل رقم المستخدم (Client ID) والمفتاح السري (Secret Key)، وجسم (Body) فيه ملف XML بتفاصيل الفاتورة يمر بخطوة «Encoding Base64».
- ملف JSON. هو الغلاف الذي يحمل الفاتورة المرمّزة إلى النظام.
- نتيجة إرسال الفاتورة. إما Submitted (Success) أو Already Submitted، وفي الحالتين تعود الفاتورة الموقّعة ورمز الاستجابة السريع (QR Code)، وإما Error فتعود قائمة الأخطاء (Error List).

يتضح من المخطط أن الترميز يقع على ملف XML وحده، داخل جسم الطلب. أما ملف JSON فهو الحاوية التي يوضع فيها الناتج، ولا يمر هو نفسه بالترميز. وهذا الفرق هو أساس معظم ما يلي في هذا المقال.
والملف الذي يُرمَّز مبني على معيار UBL 2.1، وهو المعيار الذي يطلبه الدليل لكل فاتورة، ونتناول بنيته في مقال مستقل عن معيار UBL 2.1 في نظام الفوترة الوطني. وللصورة الأشمل عن النظام نفسه ومن يلتزم به، راجع مقال نظام الفوترة الوطني الإلكتروني.
مكونات طلب الإرسال وأين يذهب كل منها
يقول الدليل التقني (ص10) إن ملف JSON المجهّز للإرسال يحتوي على ثلاثة مكونات، هي رقم المستخدم والمفتاح السري والفاتورة بصيغة XML. ويضيف في ملاحظة أن القيمتين الأوليين تؤخذان من شاشة «ربط الأجهزة» في نظام الفوترة الوطني.

لكن مثال الإرسال في الدليل نفسه (ص96) يوزع هذه المكونات على موضعين مختلفين. فرقم المستخدم والمفتاح السري يذهبان في ترويسة الطلب، والفاتورة المرمّزة وحدها تذهب في جسمه. والمخطط في ص9 يوافق المثال، إذ يضع القيمتين تحت كلمة Header. لذلك يصح أن تقرأ «المكونات الثلاثة» على أنها ما يحمله الطلب كله، لا ما يحمله نص JSON وحده.
وطريقة الحصول على القيمتين نفسيهما، ومن ينشئهما وكيف ترتبطان بتسلسل مصدر الدخل، مشروحة في مقال رقم المستخدم والمفتاح السري في نظام الفوترة الوطني، فلا نعيدها هنا.
خطوات تجهيز جسم الطلب {“invoice”: “…”}
يلخص الدليل التقني الخطوة الأولى من إرسال الفاتورة في جملة واحدة (ص96). بعد تجهيز الفاتورة بصيغة XML يُرمَّز الملف بنظام Base64 ويُدرج في ملف JSON، مع إضافة رقم المستخدم والمفتاح السري.

تستعمل الجملة في الصورة لفظًا آخر لهذه الخطوة، والمقصود بها ترميز Base64. والترميز يغيّر طريقة كتابة الملف لينتقل نصًا واحدًا داخل JSON، ولا يجعل محتواه سريًا. لذلك نسميه في هذا المقال «ترميزًا» في كل موضع.
وإذا فصّلنا تلك الجملة على ما يذكره الدليل في مواضع أخرى، فالترتيب ست خطوات.
- ابنِ ملف الفاتورة كاملًا بصيغة UBL 2.1 XML. يبدأ الملف بسطر التعريف الذي يحدد الترميز
encoding="UTF-8"، ثم العنصر الجذرInvoiceبفضاءات الأسماء، ثمcbc:ProfileIDبالقيمةreporting:1.0. ويطلب الدليل (ص10) هذه البداية كما هي. - تأكد أن وسم البداية للعنصر
Invoiceمكتوب على سطر واحد. إن توزع على أكثر من سطر يرد الخطأInvalid Invoice Minification(ص102). ولتصغير الملف قواعده التفصيلية التي لا يتسع لها هذا المقال. - ثبّت الملف قبل ترميزه. ما تُرمّزه هو ما يصل إلى النظام، فأي تعديل على الفاتورة بعد الترميز لا يصل ما لم تُعِد الترميز من الملف المعدّل.
- رمّز الملف كاملًا بترميز Base64، من سطر التعريف حتى وسم الإغلاق، لتحصل على نص واحد.
- ضع النص الناتج قيمةً للمفتاح
invoiceفي جسم الطلب بصيغة JSON، فيكون الجسم على شكل{"invoice": "…"}، حيث تحل محل النقاط سلسلة Base64 كاملة. - أرسل الطلب بطريقة POST إلى العنوان الذي يذكره الدليل، وهو
https://backend.jofotara.gov.jo/core/invoices/، ومعه الترويسات الثلاثClient-IdوSecret-KeyوContent-Type: application/json.
هذا الترتيب هو ما يرسمه مثال الدليل نفسه، أي بناء XML ثم ترميزه ثم وضعه في جسم JSON تحت المفتاح invoice ثم الإرسال مع ترويستي القيمتين. ومثال الدليل مكتوب بلغة C#، وهو يبيّن شكل الطلب لكنه ليس شيفرة جاهزة للنسخ، كما سيأتي.
أخطاء تتجنبها عند ترميز الملف وإرسال الطلب
كل نقطة في القائمة الآتية مأخوذة من نص الدليل التقني أو من ملاحظات موثقة على أمثلته، إلا نقطتين نشير إليهما بوضوح على أنهما ملاحظتان عامتان منا.
- ترميز نص JSON كاملًا بدل ملف XML وحده. الترميز في المخطط (ص9) يقع على ملف XML داخل الجسم، ونص JSON يبقى نصًا مقروءًا يحمل المفتاح
invoiceوقيمته. - وضع رقم المستخدم والمفتاح السري داخل جسم الطلب. مكانهما في مثال الدليل (ص96) هو الترويسة، والجسم يحمل الفاتورة وحدها.
- تغيير اسم المفتاح
invoiceأو كتابته بصيغة أخرى. الاسم في مثال الدليل هو هذا بالحرف. - ترميز نسخة غير النسخة النهائية من الملف. هذه ملاحظة عامة منا لا قاعدة من الدائرة. فإن عدّلت سطرًا بعد الترميز، فما يصل إلى النظام هو النسخة القديمة.
- كتابة وسم البداية للعنصر
Invoiceعلى أكثر من سطر. يرد عندها الخطأInvalid Invoice Minification. - تغيير سطر التعريف أو حذفه. يطلب الدليل (ص10) سطر التعريف بترميز UTF-8 كما هو في بداية الملف.
- اختلاف ترميز حفظ الملف عما يعلنه سطر التعريف. هذه ملاحظة عامة منا لا قاعدة من الدائرة. فإن أعلن الملف UTF-8 وحفظه برنامجك بترميز حروف آخر، صار الملف يقول عن نفسه شيئًا ونصه شيئًا آخر. والدليل لا يذكر هذه الحالة ولا رسالة خطأ خاصة بها.
- نسخ أمثلة XML من الدليل كما هي. في بعض أمثلة الدليل عيوب معروفة، منها علامات تنصيص مكررة في أمثلة الضريبة الخاصة، ومعرّفات فريدة (UUID) بصيغة غير سليمة. والترميز لا يصحح شيئًا في الملف، فما كان معيبًا قبله يبقى معيبًا بعده.
- نسخ مثال C# في الدليل حرفيًا. يضيف المثال ترويسة رابعة تحمل قيمة جلسة التُقطت من جلسة الدائرة نفسها. لا ترسل هذه الترويسة ولا تنسخ المثال كما هو، فالطلب الذي يصفه الدليل يقوم على الترويسات الثلاث السابقة.
- البحث عن بيئة تجريبية في الدليل. لا يذكر الدليل التقني (الإصدار 1.5) بيئة تجريبية مفتوحة للمكلفين أو لمزودي البرامج، والعنوان الوحيد للإرسال فيه هو العنوان السابق.
وحماية الطلب لا تأتي من الترميز، بل من حماية رقم المستخدم والمفتاح السري. فمن إرشادات الدائرة العشرة ألا تُكتب القيمتان مكشوفتين في الشيفرة، والدليل يحمّل المكلف كامل المسؤولية عن أي استخدام غير مصرح به لهما.
ما الذي يعود في الرد بعد الإرسال
يعيد النظام ردًا فيه رمز حالة الطلب (Response Status Code) وعدد من الحقول. والرمز 200 يعني أن الطلب استُلم وعولج تقنيًا، لكنه لا يحسم مصير الفاتورة. فالحالة الحاسمة للفاتورة هي قيمة الحقل EINV_STATUS، ولها ثلاث قيم.
SUBMITTEDوتعني أن الفاتورة قُبلت وعاد معها رمز الاستجابة السريع.ALREADY_SUBMITTEDوتعني أن الفاتورة أُرسلت من قبل بالرقم والمعرّف الفريد نفسيهما، ويعود معها رمز الاستجابة الأصلي.NOT_SUBMITTEDوتعني أن الفاتورة رُفضت، فلا يكون رمز الحالة 200، وتعود حقول رمز الاستجابة والمعرّف الفريد والرقم والفاتورة الموقعة فارغة.
ومن حقول الرد حقل EINV_SINGED_INVOICE [كذا في الدليل]، وهو الفاتورة التي وقّعتها الدائرة، ويعود بترميز Base64 أيضًا. فالتوقيع يصدر عن الدائرة، ولا يطلب الدليل توقيعًا ولا شهادة رقمية من المكلف. لكن الدليل لا يشرح بنية هذا الحقل بعد فك ترميزه، ولا بنية رمز الاستجابة في EINV_QR، فلا تبنِ في برنامجك منطقًا يعتمد على فك ترميزهما. واحفظ القيمتين كما وصلتا، وأظهر رمز الاستجابة على فاتورة البائع كما يطلب الدليل.
وإن جاء رمز الحالة غير 200، فالرمز يدلك على مكان البحث بحسب ما يقوله الدليل (ص101).
- الرمز 403 يدل على خطأ في رقم المستخدم أو المفتاح السري، وتفصيله في مقال خطأ 403 في نظام الفوترة الوطني.
- الرمز 400 يدل على أخطاء في قيم ملف XML، وتفصيلها في الحقل
EINV_MESSAGE، وطريقة قراءتها في مقال خطأ 400 في نظام الفوترة الوطني. - الرمز 500 يربطه الدليل بخطأ في الرقم الضريبي أو تسلسل مصدر الدخل، وبدرجة أقل في رقم المستخدم أو المفتاح السري، أو بنسبة ضريبة ليست ضمن النسب المعتمدة لدى الدائرة. وتفصيله في مقال خطأ 500 في نظام الفوترة الوطني.
- الرمز 504 يدل على تعذّر الاتصال بنظام الفوترة الوطني، بسبب جدار الحماية لدى المكلف أو موقع النظام نفسه، وتفصيله في مقال خطأ 504 في نظام الفوترة الوطني.
إعادة الإرسال بعد خطأ أو انقطاع
إن فشل الإرسال أو انقطع الاتصال قبل وصول الرد، فإرشادات الدائرة واضحة في نقطتين.
- أعد الإرسال بالرقم نفسه والمعرّف الفريد نفسه. المفتاح الأساسي للفاتورة في النظام هو الرقم
cbc:IDوالمعرّفcbc:UUIDمعًا، والدليل يحذّر من أن توليد معرّف جديد عند إعادة المحاولة قد يؤدي إلى تكرار الفاتورة. - احكم على النتيجة من قيمة
EINV_STATUSلا من رمز الحالة وحده. فإن عادت القيمةALREADY_SUBMITTED، فالفاتورة وصلت في المحاولة الأولى، ويعود معها رمز الاستجابة الأصلي.
أما إن كان الرد خطأ في قيم الفاتورة، فالتصحيح يقع في ملف XML نفسه. صحّح الملف، ثم رمّزه من جديد، ثم أرسله بالرقم والمعرّف الفريد نفسيهما. ويوصي الدليل كذلك بحفظ الرقم والمعرّف الفريد ورمز الاستجابة وحالة الفاتورة، وبالاحتفاظ بسجل كامل لكل إرسال ورد وإعادة إرسال، فهذا السجل هو ما ترجع إليه حين تسأل لماذا رُفضت فاتورة بعينها.
وإن احتجت إلى الدائرة، فالدليل (ص104) يحيل إلى لجنة الدعم الفني لشؤون الفوترة في دائرة ضريبة الدخل والمبيعات عبر الرابط istd.gov.jo. جهّز قبل التواصل رقم الفاتورة ومعرّفها الفريد ووقت الإرسال ونص الرد كاملًا، ولا ترسل المفتاح السري في أي مراسلة.
ترميز Base64 حين يرسل قيود فواتيرك
إن كنت تستخدم تكامل قيود مع نظام الفوترة الوطني، فلا تحتاج إلى تجهيز جسم الطلب بنفسك. يبني قيود ملف الفاتورة بصيغة UBL 2.1 مع معرّفها الفريد، ويرسله إلى نظام الفوترة الوطني دون تدخل يدوي، ولا يلزمك توقيع أو شهادة رقمية خاصة بك.
ويفحص قيود كل فاتورة على مستوى الحقول لحظة إنشائها، وهي الرقم الضريبي، ونوع المستند وطريقة الدفع، ونسبة ضريبة المبيعات العامة، واكتمال البنود، وينبهك بأي خطأ قبل إرسالها لتقليل حالات الرفض. وإن رُفضت فاتورة، تعيد الدائرة حالة الفاتورة ورسالة الخطأ، ويعرضها قيود في لوحة الحالة، فتعيد إرسالها بالمعرّف الفريد (UUID) نفسه بعد تصحيح السبب.
فوترة إلكترونية ومحاسبة متكاملة في نظام واحد
قيود متكامل مع نظام الفوترة الوطني (JoFotara). تُصدر فاتورتك بالدينار الأردني من قيود فتُقيَّد في دفاترك تلقائيًا وتُرسل إلى النظام، وبعد قبولها يعود عليها رمز QR من دائرة ضريبة الدخل والمبيعات.
الأسئلة الشائعة
ما المقصود بترميز Base64 في نظام الفوترة الوطني؟
يعني تحويل ملف الفاتورة بصيغة XML إلى نص واحد بترميز Base64، ثم وضعه قيمةً للمفتاح invoice في جسم طلب بصيغة JSON يُرسل إلى نظام الفوترة الوطني.
هل أرمّز ملف JSON كاملًا أم ملف XML فقط؟
يقع الترميز في مخطط الدليل التقني على ملف XML وحده، ويبقى نص JSON غلافًا مقروءًا يحمل المفتاح invoice وقيمته المرمّزة.
هل يوضع رقم المستخدم والمفتاح السري داخل ملف JSON؟
يذكرهما الدليل بين مكونات الإرسال الثلاثة، لكن مثاله في ص96 يرسلهما في ترويسة الطلب باسمي Client-Id وSecret-Key، ويترك الجسم للفاتورة وحدها.
هل يحمي ترميز Base64 بيانات الفاتورة؟
لا يحميها، فهو ترميز يغيّر طريقة كتابة الملف ولا يجعله سريًا. والحماية التي يطلبها الدليل هي حماية رقم المستخدم والمفتاح السري وعدم كتابتهما مكشوفتين في الشيفرة.
هل توجد بيئة تجريبية لاختبار الطلب قبل الإرسال الفعلي؟
لا يذكر الدليل التقني (الإصدار 1.5) بيئة تجريبية مفتوحة للمكلفين أو لمزودي البرامج، والعنوان الوحيد الذي يورده للإرسال هو https://backend.jofotara.gov.jo/core/invoices/.
ماذا أفعل بحقل الفاتورة الموقعة الذي يعود مرمّزًا؟
احفظه كما وصل. يعيد النظام الفاتورة التي وقّعتها الدائرة بترميز Base64، لكن الدليل لا يشرح بنيتها بعد فك الترميز، فلا تبنِ عليها منطقًا في برنامجك قبل أن تتحقق منه.
المراجع
- دائرة ضريبة الدخل والمبيعات، الدليل التقني للربط مع نظام الفوترة الوطني من خلال واجهة برمجة التطبيقات (API)، الإصدار 1.5، 2026.
