{“validationResults”:{“infoMessages”:[{“type”:“INFO”,“code”:“XSD_ZATCA_VALID”,“category”:“XSD validation”,“message”:“Complied with UBL 2.1 standards in line with ZATCA specifications”,“status”:“PASS”}],“warningMessages”:,“errorMessages”:[{“type”:“ERROR”,“code”:“invalid-invoice-hash”,“category”:“INVOICE_HASHING_ERRORS”,“message”:“The invoice hash API body does not match the (calculated) Hash of the XML”,“status”:“ERROR”}],“status”:“ERROR”},“reportingStatus”:null,“clearanceStatus”:“NOT_CLEARED”,“qrSellertStatus”:null,“qrBuyertStatus”:null}
Dear @Walidsharaf2022 ,
Are you submitting a standard invoice or simplified invoice? if standard invoice can you please explain how did you generate the hash? if simplified can you please explain how did you sign the invoice?
However, the below might help you in generating hash process and sign invoice process using JAVA SDK:
Please note that you can sign the invoices and generate the hash using the SDK.
Generating the hash process is applied for standards invoices. you can generate the hash using this command:
Fatoora -generateHash -invoice “invoice.xml”
You will have to take the hash value from the CLI and replace the first digest value in the invoice with the new generated Hash.
Unlike standard tax invoice, simplified tax invoice & its associated notes must be signed with the taxpayer X.509 certificate (CSID), there are 2 returned X.509 certificates in the taxpayer’s EGS onboarding process.
First X.509 certificate: CCSID, which is returned after completing the first API (Compliance CSID), It’s returned as a security binary token which will be used as a username in the authorization, it’s also used as a signing certificate (X.509) after we decode it using base64 (we decode the binarysecurityToken) using base64 decoder and the output is the X.509 certificate, we use this certificate to sign the simplified tax invoices in the compliance invoice API (Compliance checks phase).
Second X.509 Certificate: PCSID, which is returned after completing the third API on the onboarding process (Production CSID), it’s also returned as a binary security token, and will be used as the username in te authorization for both reporting & clearance API, it’s also used as a signing certificate (X.509) after we decode it using base64 (we decode the binarysecurityToken) using base64 decoder and the output is the X.509 certificate, we use this certificate to sign the simplified tax invoices in the reporting API.
Please refer to the steps of manual signing using ZATCA’s JAVA SDK below:
- After sending the CSR in the Compliance request CSID API, a Binarytoken & secret will be returned
- Take the Binarytoken output, and decode it using base64 decoder, the decoded value is the x.509 certificate
- Go to the SDK file to the following path: SDK/Data/Certificates/Cert.pem
- Replace the value with your obtained x.509 certificate
- Go to the SDK and use the command: fatoora -sign -invoice “invoice.xml”
- Now the invoice will be signed & can be submitted successfully in the compliance checks phase (Compliance invoice API)
- Redo the same steps above with the returned PCSID from the third API in the onboarding process and sign your simplified tax invoices with before sending to Reporting API
If you are implementing the signing process in your own code, please refer to This document:
SigningProcessUpdated.pdf (392.7 KB)
If you require any additional support other than the mentioned steps above, please do not hesitate to reach out.
i use new sdk version 238-R3.3.4 with c#
i use new sdk to generate csr
and use the following
that make hashing and invoice signinng also
SignResult signedEInvoice = SignDocument(einvoice, certificateContent, privateKeyContent);
if (signedEInvoice.IsValid)
{
Zatca.EInvoice.SDK.RequestGenerator request = new RequestGenerator();
RequestResult requestResult = request.GenerateRequest(signedEInvoice.SignedEInvoice);
if (!requestResult.IsValid)
return;
ValidateEInvoice(signedEInvoice.SignedEInvoice, certificateContent, PihContent);
ComplianceInvoice(requestResult);
}
and ComplianceInvoice return
{“validationResults”:{“infoMessages”:[{“type”:“INFO”,“code”:“XSD_ZATCA_VALID”,“category”:“XSD validation”,“message”:“Complied with UBL 2.1 standards in line with ZATCA specifications”,“status”:“PASS”}],“warningMessages”:,“errorMessages”:[{“type”:“ERROR”,“code”:“invalid-invoice-hash”,“category”:“INVOICE_HASHING_ERRORS”,“message”:“The invoice hash API body does not match the (calculated) Hash of the XML”,“status”:“ERROR”}],“status”:“ERROR”},“reportingStatus”:null,“clearanceStatus”:“NOT_CLEARED”,“qrSellertStatus”:null,“qrBuyertStatus”:null}
Maybe this sample project on Github Repository can help you.
I have test it, and work good in all process.
@eCloud
Most of us are facing issues with validation calls. even I called validate function in your given code but still facing error
Step: Validate EN Schematrons Status: Invalid Errors: - [Error] occurred in validating Schematrons. Step: Validate KSA Schematrons Status: Invalid Errors: - [Error] occurred in validating Schematrons.
one thing I need to mention same XML is validating through online validator and jdk validator. i haven’t seen any changes in parameters while calling validate in read me file.
If you mean validation using .NET ZatcaSDK Library, I agree with you, until now I am still waiting for Zatca Team or other members who have succeeded to be able to share examples or guides of how to use it to validate Invoice.
So far I still rely on Compliance Check Api to test or validate my Invoice before Reporting or Clearance, this is very helpful to reduce the possibility of our Invoice being Rejected by the server.
@eCloud
Yes, that’s what I mean—validating through the .NET SDK. if you find and solution please let us know too
I was having the same issue, invoice was not getting validated using SDK.
I end up changing with
fatooraNet Now everything is working smoothly.
Dear @eCloud @Ather @lalomar
We are signing using .Net SDK , below is my code
SignResult signresult = new SignResult();
EInvoiceSigner Sign = new EInvoiceSigner();
signresult = Sign.SignDocument(xDoc, certificateContent, privateKeyContent);
List<StepResult> lstStepResults = new List<StepResult>();
lstStepResults = signresult.Steps;
string InvoiceHash= lstStepResults[1].ResultedValue;
While using this Hash and sending the signed invoice to simulation environment shows an error “The invoice hash API body does not match the (calculated) Hash of the XML”
So i generated hash separately by
HashResult resHash = new HashResult();
EInvoiceHashGenerator HashGenerator = new EInvoiceHashGenerator();
resHash = HashGenerator.GenerateEInvoiceHashing(xDoc);
string InvoiceHash= resHash.Hash;
Now invoice hash error is solved and new error is generated “Invoice xml hash does not match with qr code invoice xml hash”. So i generated QR code separately using
QRResult QRresult = new QRResult();
EInvoiceQRGenerator QRGen = new EInvoiceQRGenerator();
QRresult = QRGen.GenerateEInvoiceQRCode(xDoc);
string strNamespace_cbc = “urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2”;
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable);
nsmgr.AddNamespace(“cbc”, strNamespace_cbc);
XmlNode NodeQR = xDoc.SelectSingleNode(“[local-name()=‘Invoice’]//[local-name()=‘AdditionalDocumentReference’][cbc:ID=‘QR’]//[local-name()=‘Attachment’]//[local-name()=‘EmbeddedDocumentBinaryObject’]”, nsmgr);
NodeQR.InnerText = QRresult.QR;
and replaced the QR code in signed XML , now QR error is solved new warning is came. “The timestamp in QR Code should be based on Invoice Issue Time (KSA-25) and Invoice Issue Date (BT-2). It can either be in format YYYY-MM-DD’T’HH:MM:SS (for local time in KSA) or YYYY-MM-DD’T’HH:MM:SS’Z’ (for UTC time or Zulu time)”
Please anyone advice on this, Thanks in advance.
Invoice Hash and QrCode will be automatically generated when you sign the Invoice. You can read the InvoiceHash and Base64QRCode Content from SignResult.SignedInvoice or you can also get the InvoiceHash from RequestResult.InvoiceRequest.InvoiceHash.
Make sure you don’t change anything on the signed Invoice, you only need to send it to the Server for Reporting or Clearance.
It’s hard to find what happened to your code from the code snippets and errors you provide.
Did you tried your code in simulation environment ?
Not yet, on the github code that I shared above.
I have finished all the processes on my other code.
Our problem here is the SignedInvoice Validation problem.
For SignedInvoice, the difference between Sandbox and Simulation is only in the VAT Number.
In Simulation, we must ensure that the VAT number we use in the Invoice is the same as the VAT number we registered when creating the CSR and PrivateKey, and the same as the one on our certificate, be it CCSID or PCSID.
Use a certificate from CCSID BinarySecurityToken for Compliance Check. And make sure we use a certificate from PCSID BinarySecurityToken to sign the Invoice for Clearance and Reporting.
If you have access to a simulation, you can try the above code using your VAT number in CsrGenerationDto and create a CleanInvoice instance with SupplierParty according to CsrGenerationDto and make sure you delete or comment out the Onboarding Process code after the first successful onboarding.
@Ather, can you provide the link to the latest version of FatooraNet? Also, is it compatible with the latest ZATCA versions 3.3.4 or 3.3.5?
You should not edit the signresult.SignedInvoice, Try to validate this signed invoice the validation process will give negative result and the error will be invalid EN schematrons (the reason is the xml version tag in the first line in the signed invoice)
There is an error in the sdk signing process
you can find fatooraNet in this folder.
…\zatca-einvoicing-sdk-238-R3.3.5\zatca-einvoicing-sdk-238-R3.3.5\Lib\Dot-Net3.1\Test
First Install the batch file install.net.bat to add the environment variables this file is located in this folder.
…\zatca-einvoicing-sdk-238-R3.3.5\zatca-einvoicing-sdk-238-R3.3.5\Lib\Dot-Net3.1
For Documentation
…\zatca-einvoicing-sdk-238-R3.3.5\zatca-einvoicing-sdk-238-R3.3.5\Readme.Net
fatooraNet sign options
-invoice [REQUIRED] E-Invoice file path
-signedInvoice Signed E-Invoice file path [default: SignedInvoice-{DateTime}.xml]
-certificate Certificate File Path [default: …...…pem]
-privateKey Private Key file path [default: …....-secp256k1-priv-key.pem]
-help Show help and usage information
fatooraNet validate options
-invoice [REQUIRED] E-Invoice file path
-certificate Certificate File Path [default: …...…pem]
-pih PIH file path [default: …...…txt]
-help Show help and usage information