If the invoice contains the previous invoice hash (KSA-13), this hash must be base64 encoded SHA256. The hash shall be computed using the following method as described in the ds:transforms block in the XML Invoice Specifications: 1. Remove the <Invoice><ext:UBLExtensions/> block 2. Remove the <Invoice><cac:AdditionalDocumentReference/> block where <cbc:ID/> = QR 3. Remove the <Invoice><cac:Signature/> block 4. Canonicalize the Invoice using the C14N11 standard 5. Hash the resulting string using SHA256 to a binary object 6. Base64 encode the binary object to generate the digest value For the first invoice, the previous invoice hash is "NWZlY2ViNjZmZmM4NmYzOGQ5NTI3ODZjNmQ2OTZjNzljMmRiYzIzOWRkNGU5MWI0NjcyOWQ3M2EyN2ZiNTdlOQ==", the equivalent for base64 encoded SHA256 of "0" (zero) character.
ماذا يعني هذا؟
كل فاتورة في المرحلة الثانية تحمل بصمة الفاتورة التي قبلها في الحقل KSA-13، فتتكوّن سلسلة مترابطة تشفيريًا لا يمكن حذف فاتورة من وسطها دون أن ينكسر الترابط. هذا الكود يقول إن الحقل موجود، لكن قيمته ليست بالصيغة المطلوبة.
الصيغة المطلوبة: تجزئة SHA-256 بطول 32 بايت، مُرمَّزة بـ Base64 — أي نص بطول 44 حرفًا ينتهي بعلامة =. أي شيء غير ذلك يُرفض: التجزئة بصيغة hex (64 حرفًا)، أو القيمة الثنائية الخام، أو نص مقتطع.
لماذا يحدث؟
مرتّبة من الأشيع إلى الأقل شيوعًا — الأرجح أن سببك في الأول أو الثاني.
- إخراج التجزئة بصيغة hex بدلًا من Base64 — أشيع سبب على الإطلاق. الناتج 64 حرفًا من 0-9 و a-f، والمطلوب 44 حرفًا من حروف Base64.
- حساب التجزئة على ملف XML بعد التوقيع، أو قبل حذف الكتل الثلاث التي تشترط المواصفة حذفها.
- حساب التجزئة على XML غير مُقنَّن (Canonicalization) بمعيار C14N11 — فرق مسافة واحدة يغيّر البصمة كاملة.
-
إرسال
0أو قيمة فارغة في أول فاتورة، بدلًا من Base64 لتجزئة حرف الصفر. - أخذ البصمة من حقل خاطئ في رد الهيئة على الفاتورة السابقة.
كيف تصلحه
3 خطوات، ثم أعد إرسال الفاتورة.
-
1
احسب البصمة بالخطوات الست كما تنصّ المواصفة
من ملف XML للفاتورة السابقة: (١) احذف كتلة
<ext:UBLExtensions>. (٢) احذف كتلة<cac:AdditionalDocumentReference>التي قيمة<cbc:ID>فيها هيQR. (٣) احذف كتلة<cac:Signature>. (٤) قنّن الناتج بمعيار C14N11. (٥) احسب SHA-256 للنص الناتج ككائن ثنائي. (٦) رمّز الكائن الثنائي بـ Base64. -
2
في أول فاتورة استخدم القيمة الثابتة
أول فاتورة لا يوجد قبلها شيء، فتأخذ قيمة ثابتة تنصّ عليها المواصفة وهي Base64 لتجزئة SHA-256 لحرف الصفر:
NWZlY2ViNjZmZmM4NmYzOGQ5NTI3ODZjNmQ2OTZjNzljMmRiYzIzOWRkNGU5MWI0NjcyOWQ3M2EyN2ZiNTdlOQ== -
3
خزّن بصمة كل فاتورة أرسلتها، ولا تعد حسابها
أعِد حساب البصمة مرة واحدة عند الإرسال واحفظها في قاعدة بياناتك، ثم استخدم المحفوظة في الفاتورة التالية. إعادة الحساب لاحقًا من ملف مُخزَّن بصيغة مختلفة قليلًا هو ما يكسر السلسلة بعد أشهر من العمل السليم.
هذا الكود لا يمنع القبول، فالفاتورة الحالية نظامية. صحّح البيانات لتختفي التحذيرات من الفواتير القادمة.
هل يمنعه ZATCA Tools؟
نعم. ZATCA Tools يحسب البصمة ويخزّنها ويربط كل فاتورة بالتي قبلها تلقائيًا — لا يوجد حقل PIH تكتبه أنت، ولا خطوة تنساها.
أكواد لها علاقة
أسئلة شائعة
هل الفاتورة المرفوضة تدخل في السلسلة؟ +
ماذا يحدث لو أصدرت من جهازين في نفس الوقت؟ +
هل أستطيع التحقق من البصمة بنفسي؟ +
ZATCA Tools يبني التوقيع والبصمة والعدّاد والترميز عنك، ويتحقق من البيانات قبل الإرسال. مجاني بالكامل حاليًا، وبدون بطاقة ائتمانية.
ابدأ مجانًا