Qoyod
الأسعار

 دليل المعرفة

بنية رمز QR التقنية في الفاتورة

كل فاتورة إلكترونية سعودية تحمل في زاويتها رمز QR صغيرًا. القارئ السطحي يراه صورة سوداء فقط، لكن خلفه بنية بيانات محكمة فرضتها هيئة الزكاة والضريبة والجمارك (ZATCA) بصياغة دقيقة بايتًا ببايت. هذا الدليل موجّه للمطوّرين والمحاسبين التقنيين: نفكّك البنية الداخلية للرمز، وترتيب وسومه التسعة، وكيف يُبنى النص من ترميز TLV ثم Base64، وأين يُحقن داخل ملف XML، وكيف تقرأه وتتحقق منه برمجيًا.

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

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

ماذا يحمل رمز QR على الفاتورة الإلكترونية؟

الرمز ليس رابطًا ولا صورة مضمّنة، بل سلسلة نصية مرمّزة تختصر هوية الفاتورة. تتكوّن هذه السلسلة من مجموعة حقول مرتبة، كل حقل يُكتب بصيغة TLV. كلمة TLV اختصار لثلاثة عناصر:

  • Tag (الوسم): رقم يعرّف نوع الحقل. مثلًا الوسم 1 يعني اسم البائع، والوسم 2 يعني الرقم الضريبي.
  • Length (الطول): عدد البايتات التي يشغلها محتوى الحقل.
  • Value (القيمة): المحتوى الفعلي للحقل بصيغة بايتات.

تُكتب الحقول واحدًا تلو الآخر بهذا الترتيب الثلاثي، ثم تُجمع السلسلة الناتجة وتُحوّل إلى نص Base64. هذا النص هو ما يُخزَّن داخل رمز QR ويظهر على الفاتورة.

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

للتعمّق في آلية ترميز TLV (Tag-Length-Value) وحدها، وفي تحويل Base64 وكيف يعمل، نخصّص لكل منهما دليلًا تقنيًا منفصلًا. هنا نركّز على البنية الكاملة لرمز الفاتورة وكيف تتجمّع هذه القطع معًا.

الوسوم التسعة في رمز الفاتورة بالترتيب

تحدّد مواصفة المرحلة الثانية تسعة وسوم لرمز QR على الفاتورة الضريبية المبسطة (B2C). الترتيب ملزم: يبدأ الوسم بالرقم 1 وينتهي بالرقم 9، ولا يجوز تبديل ترتيبها. الجدول التالي يعرضها كما تطلبها الهيئة:

وسوم رمز QR التسعة بالترتيب
الحقول التي يحملها رمز QR في المرحلتين الأولى والثانية.
الوسوم التسعة

1–5: اسم البائع، الرقم الضريبي، الوقت، الإجمالي، الضريبة (المرحلة الأولى)

6: تجزئة الفاتورة (SHA-256)

7: الختم التشفيري (التوقيع ECDSA)

8: المفتاح العام

9: ختم الهيئة

الوسوم 6–9 هي إضافات المرحلة الثانية المرتبطة بالتحقق.
الوسم (Tag) الحقل نوع القيمة المرحلة
1 اسم البائع (Seller name) نص UTF-8 الأولى والثانية
2 الرقم الضريبي للبائع (VAT registration number) نص رقمي (15 خانة) الأولى والثانية
3 الطابع الزمني للفاتورة (Timestamp) نص بصيغة ISO 8601 الأولى والثانية
4 إجمالي الفاتورة شامل الضريبة (Invoice total with VAT) رقم عشري الأولى والثانية
5 إجمالي ضريبة القيمة المضافة (VAT total) رقم عشري الأولى والثانية
6 بصمة الفاتورة (Hash of XML invoice) نص Base64 لتجزئة SHA-256 الثانية
7 الختم التشفيري للبائع (ECDSA signature) بايتات التوقيع الرقمي الثانية
8 المفتاح العام للبائع (Public key) بايتات المفتاح العام الثانية
9 ختم الهيئة على المفتاح العام (ZATCA stamp signature) بايتات توقيع الهيئة الثانية

الوسوم من 1 إلى 5 هي البيانات الأساسية التي ظهرت منذ المرحلة الأولى من الفوترة الإلكترونية. أما الوسوم من 6 إلى 9 فهي الطبقة التشفيرية التي أُضيفت في المرحلة الثانية (الربط والتكامل)، وتمنح الرمز قدرة التحقق المستقل من صحة الفاتورة دون الرجوع إلى أي خادم.

ملاحظة دقيقة على الوسم 9: هو توقيع الهيئة على المفتاح العام للبائع، وليس توقيع الفاتورة نفسها. وظيفته إثبات أن المفتاح العام في الوسم 8 صادر فعلًا عن جهاز معتمد سجّل شهادته (CSID) لدى منصة فاتورة. هكذا يربط الرمز الفاتورة بهوية موثّقة من الهيئة.

كيف تُبنى سلسلة TLV لكل وسم؟

كل وسم يُكتب على شكل ثلاث قطع متتالية من البايتات: بايت واحد للوسم، بايت واحد للطول، ثم بايتات القيمة. خذ الوسم 1 (اسم البائع) كمثال. لنفترض أن اسم البائع هو شركة قيود (تسعة بايتات في ترميز UTF-8 على سبيل التوضيح):

Tag    = 0x01            // رقم الوسم: 1
Length = 0x09            // طول القيمة: 9 بايت
Value  = D8 B4 D8 B1 ... // بايتات الاسم بترميز UTF-8

فتكون قطعة TLV الكاملة لهذا الوسم هي تسلسل البايتات: 01 09 [بايتات القيمة]. ينطبق المنطق نفسه على بقية الوسوم. مثال الوسم 4 (إجمالي الفاتورة) إذا كانت قيمته النصية 115.00 وطولها ستة بايتات:

Tag    = 0x04
Length = 0x06
Value  = "115.00"   // ستة بايتات ASCII

قاعدة الطول مهمة عند الحقول التشفيرية. الختم التشفيري في الوسم 7 وبايتات المفتاح في الوسم 8 ليست نصًا مقروءًا بل بايتات خام، لذا يحمل بايت الطول عددها الفعلي قبل كتابتها مباشرة. لا تحوّل هذه البايتات إلى نص قبل بناء سلسلة TLV، لأن التحويل سيغيّر طولها ويكسر التحقق.

تجميع السلسلة ثم تحويلها إلى Base64

بعد بناء قطعة TLV لكل وسم على حدة، تُجمع القطع التسع في سلسلة بايتات واحدة بالترتيب من الوسم 1 إلى الوسم 9. هذه السلسلة الثنائية لا تصلح للتخزين المباشر في رمز QR النصي، لذا تُحوّل إلى نص Base64.

// خطوات البناء بترتيبها
1. ابنِ قطعة TLV لكل وسم:  tag + length + value
2. اجمع القطع التسع بالترتيب:  tlv1 + tlv2 + ... + tlv9
3. حوّل سلسلة البايتات الناتجة إلى Base64
4. ضع نص Base64 داخل رمز QR

ترميز Base64 يحوّل البايتات الثنائية إلى نص آمن قابل للتخزين في الرمز. النص الناتج هو ما يقرأه أي قارئ QR، وهو نفسه ما يُحقن داخل ملف XML للفاتورة. للتعمّق في كيفية عمل تحويل Base64 ولماذا اختير تحديدًا، نخصّص له دليلًا تقنيًا منفصلًا.

كيف يُبنى رمز QR
من حقول الفاتورة إلى رمز QR جاهز للطباعة.
1

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

2

مقاطع TLV لكل حقل

3

سلسلة بايتات مدمجة

4

ترميز Base64 ← رمز QR

تُرمَّز الحقول بـTLV ثم تُدمَج وتُحوَّل إلى Base64 داخل الرمز.
ابدأ اليوم

رموز QR مطابقة للهيئة على كل فاتورة تلقائيًا

يبني قيود سلسلة TLV ويحوّلها إلى Base64 ويحقنها في رمز QR على كل فاتورة، مطابقة لمواصفة المرحلة الثانية، دون أي خطوة يدوية منك.

ابدأ تجربتك المجانية وأصدر فواتير متوافقة

مثال كامل خطوة بخطوة على بناء السلسلة

لنبنِ سلسلة TLV كاملة لفاتورة مبسطة بسيطة من البيانات الأساسية الخمسة، ثم نوضّح كيف تنضمّ إليها الحقول التشفيرية. افترض هذه القيم:

  • اسم البائع: شركة قيود
  • الرقم الضريبي: 300000000000003
  • الطابع الزمني: 2026-06-24T11:45:30Z
  • إجمالي الفاتورة شامل الضريبة: 115.00
  • إجمالي الضريبة: 15.00

نبني قطعة TLV لكل قيمة على حدة. القيم النصية تُحوّل أولًا إلى بايتات UTF-8، ثم نضع رقم الوسم وطول البايتات أمامها:

// الوسم 2: الرقم الضريبي (15 خانة = 15 بايت ASCII)
Tag    = 0x02
Length = 0x0F           // 15 بالنظام الست عشري
Value  = "300000000000003"

// الوسم 3: الطابع الزمني (20 بايت ASCII)
Tag    = 0x03
Length = 0x14           // 20
Value  = "2026-06-24T11:45:30Z"

// الوسم 5: إجمالي الضريبة (5 بايت)
Tag    = 0x05
Length = 0x05
Value  = "15.00"

لاحظ بايت الطول للوسم 2: قيمته 0x0F وهي 15 في النظام العشري لأن الرقم الضريبي السعودي 15 خانة. ولاحظ الوسم 3: طوله 20 بايتًا لأن صيغة ISO 8601 الكاملة بحرف Z في نهايتها تشغل 20 محرفًا ASCII، وكل محرف ASCII بايت واحد. هنا يتطابق عدد الأحرف مع عدد البايتات لأن المحارف لاتينية. أما الوسم 1 (اسم البائع العربي) فيختلف، إذ يشغل الحرف العربي الواحد في UTF-8 بايتين، فطول شركة قيود بالبايتات أكبر من عدد حروفه.

بعد بناء القطع الخمس نضمّها بالترتيب في سلسلة بايتات واحدة. تبدأ السلسلة ببايتات الوسم 1 (رقم الوسم، فالطول، فبايتات الاسم العربي)، تليها مباشرة بايتات الوسم 2، وهكذا حتى الوسم 5 في المرحلة الأولى، أو حتى الوسم 9 في المرحلة الثانية.

الحقول التشفيرية الأربعة بالتفصيل

الوسوم من 6 إلى 9 هي ما يحوّل الرمز من ملخّص بصري إلى وثيقة قابلة للتحقق. نفصّل كلًّا منها:

الوسم 6: بصمة الفاتورة (Hash)

قبل حساب البصمة، يُمرَّر ملف XML على عملية تقييس (Canonicalization) تضمن صيغة موحّدة للمسافات والترتيب. ثم تُحسب تجزئة SHA-256 للنتيجة، وتُخزَّن مرمّزة بصيغة Base64. أي تعديل لاحق على الفاتورة، ولو بحرف واحد، يغيّر هذه البصمة كليًا، فتفشل المقارنة عند التحقق. هذا ما يجعل البصمة أساس كشف العبث.

الوسم 7: الختم التشفيري (Signature)

الختم توقيع رقمي يُحسب على بصمة الفاتورة باستخدام المفتاح الخاص للبائع المخزَّن في شهادته. خوارزمية التوقيع منحنى بياني إهليلجي (ECDSA). الناتج بايتات خام تُكتب كما هي في سلسلة TLV دون تحويل إلى نص. وظيفته إثبات أن صاحب المفتاح الخاص هو من أصدر هذه الفاتورة تحديدًا.

الوسم 8: المفتاح العام (Public Key)

المفتاح العام هو النظير العلني للمفتاح الخاص. يحمله الرمز ليتمكّن أي قارئ من التحقق من الختم في الوسم 7 دون امتلاك المفتاح الخاص. هذا التصميم يتيح التحقق دون اتصال بأي خادم: كل ما يلزم موجود داخل الرمز نفسه.

الوسم 9: ختم الهيئة (ZATCA Stamp)

الوسم الأخير توقيع الهيئة على المفتاح العام للبائع. يربط هذا التوقيع المفتاح بشهادة الجهاز (CSID) التي سجّلها البائع لدى منصة فاتورة. بدونه يستطيع أي طرف توليد زوج مفاتيح وتوقيع فاتورة مزوّرة. وجود ختم الهيئة يثبت أن المفتاح العام في الوسم 8 صادر فعلًا عن جهاز معتمد اجتاز إجراءات التسجيل والامتثال.

شهادة الجهاز (CSID) وعلاقتها بالرمز

الوسوم التشفيرية لا تعمل دون شهادة معتمدة. للدخول إلى المرحلة الثانية، يولّد نظام البائع طلب توقيع شهادة (CSR)، ويرسله إلى منصة فاتورة مع رمز تحقق لمرة واحدة. تعيد المنصة شهادة امتثال (Compliance CSID) لاختبار النظام في البيئة التجريبية. بعد اجتياز فحوص الامتثال، يحصل البائع على شهادة الإنتاج (Production CSID)، وهي التي توقّع كل فاتورة حية.

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

تفاصيل الطابع الزمني وصيغته

الوسم 3 من أكثر مصادر التحذيرات شيوعًا عند البناء اليدوي. تتطلب المواصفة صيغة ISO 8601 الكاملة بصيغة التاريخ والوقت معًا. الصيغة الصحيحة على هيئة YYYY-MM-DDThh:mm:ssZ، مثل 2026-06-24T11:45:30Z. حرف T يفصل التاريخ عن الوقت، وحرف Z يدل على التوقيت العالمي المنسّق.

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

أين يُحقن رمز QR داخل ملف XML؟

الفاتورة الإلكترونية في المرحلة الثانية تُولَّد بصيغة XML قياسية (UBL 2.1). نص Base64 الذي يمثّل رمز QR لا يُكتب كصورة، بل يُخزَّن في حقل مخصّص داخل البنية باسم إضافي على مستوى المستند.

<cac:AdditionalDocumentReference>
  <cbc:ID>QR</cbc:ID>
  <cac:Attachment>
    <cbc:EmbeddedDocumentBinaryObject mimeCode="text/plain">
      [نص Base64 لرمز QR هنا]
    </cbc:EmbeddedDocumentBinaryObject>
  </cac:Attachment>
</cac:AdditionalDocumentReference>

المعرّف QR هو ما يميّز هذا الحقل عن مراجع المستندات الأخرى في الفاتورة. نظام النقطة المستقبِل (أو أداة العرض) يقرأ نص Base64 من هذا الحقل ويرسمه رمز QR مرئيًا على نسخة العرض، مثل ملف PDF/A-3 الذي يضمّن XML داخله.

يولّد قيود ملف XML كاملًا بصيغة UBL 2.1 مع رمز QR في موضعه الصحيح تلقائيًا، فلا تتعامل يدويًا مع وسوم XML ولا مع موضع الحقل.

كيف تقرأ رمز QR وتفكّ بنيته؟

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

// خطوات فكّ الرمز
1. اقرأ نص Base64 من رمز QR
2. فكّ ترميز Base64 إلى سلسلة بايتات
3. اقرأ أول بايت = رقم الوسم (Tag)
4. اقرأ البايت التالي = طول القيمة (Length)
5. اقرأ عدد (Length) من البايتات = القيمة (Value)
6. كرّر من الخطوة 3 حتى نهاية السلسلة

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

القراءة وحدها لا تكفي للتحقق. للتأكد من أن الفاتورة لم تُعدَّل، تحسب تجزئة SHA-256 لملف XML وتقارنها بقيمة الوسم 6. ثم تتحقق من الختم التشفيري في الوسم 7 باستخدام المفتاح العام في الوسم 8، وتتحقق من أن المفتاح نفسه موقّع من الهيئة عبر الوسم 9. نجاح هذه الفحوص الثلاثة يعني أن الفاتورة أصلية وغير معدّلة وصادرة عن جهاز معتمد.

كيف يُتحقَّق من رمز QR
ثلاث طبقات للتحقق من صحة الفاتورة عبر الرمز.
1

مطابقة تجزئة الفاتورة (الوسم 6)

2

التحقق من التوقيع بالمفتاح العام (7 و8)

3

التحقق من ختم الهيئة (الوسم 9)

اجتياز الطبقات الثلاث يؤكّد أصالة الفاتورة وسلامتها.

الفرق بين المرحلة الأولى والمرحلة الثانية في بنية الرمز

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

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

تفصيل آلية المصادقة (Clearance) للفواتير الضريبية بين المنشآت (B2B) مقابل الإبلاغ (Reporting) للفواتير المبسطة (B2C) يتجاوز نطاق هذا الدليل التقني للرمز. ما يهم هنا أن رمز QR على الفاتورة المبسطة يحمل الوسوم التسعة كاملة في المرحلة الثانية.

التحقق العملي من الرمز خطوة بخطوة

بعد فكّ الوسوم التسعة، يجري التحقق على ثلاث طبقات متتابعة، ولا يُعتمد الرمز إلا بنجاحها جميعًا. الطبقة الأولى مطابقة البصمة. تأخذ ملف XML للفاتورة، وتمرّره على عملية التقييس نفسها التي استخدمها المُصدِر، ثم تحسب تجزئة SHA-256 للناتج. تقارن القيمة الناتجة بقيمة الوسم 6. إن تطابقتا، فالفاتورة لم تتغيّر منذ توقيعها. أي اختلاف يعني أن المحتوى عُدِّل.

الطبقة الثانية التحقق من الختم. تستخرج المفتاح العام من الوسم 8، وتستخدمه للتحقق من التوقيع في الوسم 7 مقابل بصمة الفاتورة. نجاح التحقق يثبت أن صاحب المفتاح الخاص المقابل هو من وقّع الفاتورة، لا طرف آخر.

الطبقة الثالثة التحقق من ختم الهيئة. تتأكد من أن المفتاح العام في الوسم 8 موقّع فعلًا من الهيئة عبر الوسم 9. هذه الطبقة تمنع التزوير: لا يكفي أن يوقّع طرف فاتورة بمفتاحه الخاص، بل يجب أن يكون مفتاحه العام مختومًا من الهيئة، أي صادرًا عن جهاز معتمد.

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

هل يحمل كل أنواع الفواتير الرمز نفسه؟

رمز QR إلزامي على الفاتورة الضريبية المبسطة الموجّهة للمستهلك النهائي (B2C)، وهو يحمل الوسوم التسعة في المرحلة الثانية. هذه الفواتير تُسلَّم للمشتري فورًا ثم تُبلَّغ للهيئة خلال أربع وعشرين ساعة.

الفاتورة الضريبية القياسية بين المنشآت (B2B) تمرّ بمسار مختلف: تُرسل إلى الهيئة أولًا للمصادقة، وتعيدها الهيئة موقّعة بختمها قبل تسليمها للمشتري. تفصيل هذا المسار وما يضيفه إلى البنية يتجاوز نطاق هذا الدليل المركّز على رمز الفاتورة المبسطة. المهم أن آلية بناء سلسلة TLV وتحويلها إلى Base64 واحدة في الحالتين، والاختلاف في مسار المعالجة لا في صياغة الرمز.

لماذا اختيرت صيغة TLV تحديدًا؟

صيغة TLV ليست اختيارًا عشوائيًا. هي صيغة مدمجة لا تحتاج فواصل بين الحقول، لأن بايت الطول يحدّد أين ينتهي كل حقل ويبدأ التالي. هذا يجعل السلسلة قصيرة بما يكفي لتُخزَّن في رمز QR متوسط الكثافة يقرأه هاتف عادي بسرعة. الصيغ النصية البديلة (مثل JSON) ستضخّم حجم السلسلة وتزيد كثافة الرمز فيصعب مسحه.

كذلك تتعامل TLV مع البيانات الثنائية الخام (بايتات التوقيع والمفتاح) بسلاسة، بينما الصيغ النصية تتطلب ترميزًا إضافيًا لكل حقل ثنائي. هذا التوازن بين الإحكام ودعم البيانات الثنائية هو سبب تبنّي الهيئة لها في مواصفة الرمز.

أخطاء شائعة عند بناء الرمز يدويًا

إن كنت تبني الرمز في نظام خاص بدل الاعتماد على حلّ معتمد، فهذه أكثر الأخطاء تكرارًا:

  • تبديل ترتيب الوسوم: الترتيب ملزم من 1 إلى 9. أي تبديل يجعل أدوات الهيئة ترفض الرمز.
  • حساب الطول بعدد الحروف لا البايتات: الحقول العربية في ترميز UTF-8 يشغل الحرف فيها أكثر من بايت، فالطول يُحسب بالبايتات لا بعدد الأحرف.
  • تحويل بايتات التوقيع إلى نص قبل البناء: الوسوم 7 و8 و9 بايتات خام، وتحويلها يكسر التحقق.
  • إهمال ترميز Base64 النهائي: تخزين سلسلة البايتات الخام في الرمز بدل تحويلها إلى Base64 يجعل النص غير قابل للقراءة بشكل صحيح.
  • خطأ في صيغة الطابع الزمني: الوسم 3 يتطلب صيغة ISO 8601، وأي صيغة أخرى تسبب تحذيرًا عند التحقق.

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

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

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

كيف يساعدك قيود في رمز QR المطابق؟

لا تحتاج إلى كتابة سطر واحد من شيفرة بناء الرمز. يتولى قيود الدورة الكاملة لكل فاتورة:

  • يجمع حقول الفاتورة التسعة ويبني قطعة TLV لكل وسم بطولها الصحيح بالبايتات.
  • يحسب بصمة SHA-256 لملف XML ويوقّع الفاتورة بالختم التشفيري عبر شهادة الجهاز المسجّلة (CSID).
  • يجمع السلسلة ويحوّلها إلى Base64 ويحقنها في حقل XML الصحيح ضمن بنية UBL 2.1.
  • يرسم رمز QR على نسخة العرض، ويضمّن XML داخل ملف PDF/A-3 لعملاء المرحلة الثانية.

النتيجة فاتورة جاهزة للمصادقة أو الإبلاغ مع رمز QR مطابق لمواصفة الهيئة، دون أي تدخّل تقني منك.

الأسئلة الشائعة

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

ما الفرق بين بنية الرمز في المرحلة الأولى والثانية؟
المرحلة الأولى تحمل الوسوم الخمسة الأولى فقط. المرحلة الثانية تضيف الوسوم من 6 إلى 9 لتمكين التحقق التشفيري المستقل من أصالة الفاتورة.

هل يُحسب طول الحقل بعدد الأحرف أم البايتات؟
بعدد البايتات. الحرف العربي في ترميز UTF-8 يشغل أكثر من بايت، فالاعتماد على عدد الأحرف يكسر التحقق.

أين يُخزَّن نص Base64 لرمز QR داخل ملف XML؟
داخل عنصر AdditionalDocumentReference بمعرّف QR، ضمن حقل EmbeddedDocumentBinaryObject في بنية UBL 2.1.

ماذا يمثّل الوسم التاسع؟
ختم الهيئة على المفتاح العام للبائع، وهو يثبت أن المفتاح صادر عن جهاز معتمد سجّل شهادته (CSID) لدى منصة فاتورة. ليس توقيعًا على الفاتورة نفسها.

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

مركز المساعدة

لم تجد ما تبحث عنه؟

لا تقلق، لدينا المزيد من أدوات المساعدة.

ندوات مباشرة يقدمها فريق قيود لمساعدتك في استخدام البرنامج بسهولة والرد على أسئلتك.

تعرّف على أحدث تحديثات فيود والتحسينات المستمرة والخصائص الجديدة في مكان واحد.

فريقنا جاهز لمساعدتك وتقديم الدعم الفوري لأي مشكلة تواجهها على مدار الساعة