Validating error when sign xml from zatca sdk

when i sign xml from cmd
fatooraNet sign -invoice c:\test\Zatca_Simplified_Invoice.xml -signedInvoice c:\test\Zatca_Simplified_Invoice_Signed.xml

and i check the signed xml with fatooraNet cmd it ok
fatooraNet validate -invoice c:\test\Zatca_Simplified_Invoice_Signed.xml
but when i use zatca dll to validate same file
ValidationResult validationResult = new EInvoiceValidator().ValidateEInvoice(Utilities.LoadXML(eInvoicePath), certificateFilePath, pihFilePath);
its failed with this two error
“Validate EN Schematrons”
“Validate KSA Schematrons”
what is the correct way to achieve validation with DLL
لقطة الشاشة 2024-09-19 205829

Dear @themasdev,

The given response means that the error is with the UBL2.1 scehma not the signature.

Please review your code, ensuring it’s complied with the EN & KSA schematrons, by comparing the output of the signing function in your code & output from SDK (That passed the validation).

Do this activity in the same invoice, one from SDK (VALID) one from code (FAILED), compare them and see what’s the difference to fix your code/errors accordingly

thank you,

@themasdev ,

The solution for schematrons error is to make sure we copy the ikvm folder from the Test folder (not from the dll folder) to where our application executable file directory is located.
.

@Aturkistani
There is no validation issue on Signed B2C Invoice signed using X509Certificate from CCSID BinarySecurityToken.

Processing Simplified Invoice...
Initialization Step (Simplified EInvoice) : True
Validate XSD : True
Validate EN Schematrons : True
Validate KSA Schematrons : True
Generate EInvoice Hash : True
Parse Certificate : True
Generate EInvoice QR : True
Validate QR Code : True
Validate EInvoice Signature : True
Validate EInvoice PIH : True
Overall Signed Invoice Validation : True!

Simplified Invoice processed successfully

I am still facing Validation issue for Signed B2C Invoice signed using X509Certificate from PCSID BinarySecurityToken ([Error] CODE: signatureValue, MESSAGE: Wrong signature value.).

But this Signed B2C Invoice is approved by Reporting Server without any error or warning.

Initialization Step (Simplified EInvoice) : True
Validate XSD : True
Validate EN Schematrons : True
Validate KSA Schematrons : True
Generate EInvoice Hash : True
Parse Certificate : True
Generate EInvoice QR : True
Validate QR Code : True
Validate EInvoice Signature : False
[Error] CODE: signatureValue, MESSAGE: Wrong signature value.
Validate EInvoice PIH : True

Overall Signed Invoice Validation : False!

Reporting Simplified Invoice

{
  "requestType": "Reporting",
  "requestUrl": "https://gw-fatoora.zatca.gov.sa/e-invoicing/developer-portal/invoices/reporting/single",
  "statusCode": "200-OK",
  "reportingStatus": "REPORTED",
  "validationResults": {
    "status": "PASS",
    "infoMessages": [
      {
        "status": "PASS",
        "type": "INFO",
        "code": "XSD_ZATCA_VALID",
        "category": "XSD validation",
        "message": "Complied with UBL 2.1 standards in line with ZATCA specifications"
      }
    ],
    "warningMessages": [],
    "errorMessages": []
  }
}

This is my code to Sign Document and perform Validation Test

public static RequestResult GenerateSignedRequestApi(XmlDocument document, string csidBinaryToken, string privateKey, string pih)
{
    string x509CertificateContent = Encoding.UTF8.GetString(Convert.FromBase64String(csidBinaryToken));
    SignResult signedInvoiceResult = new EInvoiceSigner().SignDocument(document, x509CertificateContent, privateKey);

    // Validate Signed Invoice *** just test ***
    EInvoiceValidator eInvoiceValidator = new();
    var validationResult = eInvoiceValidator.ValidateEInvoice(signedInvoiceResult.SignedEInvoice, x509CertificateContent, pih);
    if (validationResult != null) {
        foreach (var e in validationResult.ValidationSteps)
        {
            Console.WriteLine(e.ValidationStepName + " : " + e.IsValid);
            if (!e.IsValid)
            {
                foreach (var x in e.ErrorMessages)
                {
                    Console.WriteLine(x);
                }
            }
            else
            {
                foreach (var x in e.WarningMessages)
                {
                    Console.WriteLine(x);
                }
                //return new RequestGenerator().GenerateRequest(signedInvoiceResult.SignedEInvoice);
            }
               
        }
        Console.WriteLine($"Overall Signed Invoice Validation : {validationResult.IsValid}!");
    }

    return new RequestGenerator().GenerateRequest(signedInvoiceResult.SignedEInvoice);
}

Please advise, are there any steps I should take for this Signature Error problem on Validation. Thank you.

Dear all,

After almost a month of waiting for clarity regarding the use of eInvoice Validator on .Net8 Zatca eInvoice SDK.

Since no one including Zatca Team responded to the question about this,
then I assume that there is no problem with .Net 8 Zatca eInvoice SDK library running on Windows OS. (still has path Issue on Linux Ubuntu)

In NonProduction Environment,
eInvoice Validator from .Net 8 Zatca eInvoice SDK library only works on Invoices signed using Certificate and PrivateKey available in SDK.

Not sure if this is a bug from .Net 8 Zatca eInvoice SDK library or on Certificates provided by Production CSID Api.
Certificates from Compliance CSID Api work fine and there is no problem in Validation.

In Simulation Environment,
eInvoice Validator from .Net 8 Zatca eInvoice SDK library works fine and there is no problem in Validation.

Please let me know if my assumption is wrong.

I updated the Code example above based on this assumption.

public static RequestResult GenerateSignedRequestApi(XmlDocument document, CertificateInfo certInfo, string pih, bool isForCompliance = false)
{
    string x509CertificateContent = Encoding.UTF8.GetString(Convert.FromBase64String(isForCompliance ? certInfo.CCSIDBinaryToken : certInfo.PCSIDBinaryToken));
    string privateKey = certInfo.PrivateKey;

    //Test use Certificate and privatekey from Zatca eInvoice SDK
    if (certInfo.EnvironmentType == EnvironmentType.NonProduction)
    {
        x509CertificateContent = "MIID3jCCA4SgAwIBAgITEQAAOAPF90Ajs/xcXwABAAA4AzAKBggqhkjOPQQDAjBiMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxEzARBgoJkiaJk/IsZAEZFgNnb3YxFzAVBgoJkiaJk/IsZAEZFgdleHRnYXp0MRswGQYDVQQDExJQUlpFSU5WT0lDRVNDQTQtQ0EwHhcNMjQwMTExMDkxOTMwWhcNMjkwMTA5MDkxOTMwWjB1MQswCQYDVQQGEwJTQTEmMCQGA1UEChMdTWF4aW11bSBTcGVlZCBUZWNoIFN1cHBseSBMVEQxFjAUBgNVBAsTDVJpeWFkaCBCcmFuY2gxJjAkBgNVBAMTHVRTVC04ODY0MzExNDUtMzk5OTk5OTk5OTAwMDAzMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEoWCKa0Sa9FIErTOv0uAkC1VIKXxU9nPpx2vlf4yhMejy8c02XJblDq7tPydo8mq0ahOMmNo8gwni7Xt1KT9UeKOCAgcwggIDMIGtBgNVHREEgaUwgaKkgZ8wgZwxOzA5BgNVBAQMMjEtVFNUfDItVFNUfDMtZWQyMmYxZDgtZTZhMi0xMTE4LTliNTgtZDlhOGYxMWU0NDVmMR8wHQYKCZImiZPyLGQBAQwPMzk5OTk5OTk5OTAwMDAzMQ0wCwYDVQQMDAQxMTAwMREwDwYDVQQaDAhSUlJEMjkyOTEaMBgGA1UEDwwRU3VwcGx5IGFjdGl2aXRpZXMwHQYDVR0OBBYEFEX+YvmmtnYoDf9BGbKo7ocTKYK1MB8GA1UdIwQYMBaAFJvKqqLtmqwskIFzVvpP2PxT+9NnMHsGCCsGAQUFBwEBBG8wbTBrBggrBgEFBQcwAoZfaHR0cDovL2FpYTQuemF0Y2EuZ292LnNhL0NlcnRFbnJvbGwvUFJaRUludm9pY2VTQ0E0LmV4dGdhenQuZ292LmxvY2FsX1BSWkVJTlZPSUNFU0NBNC1DQSgxKS5jcnQwDgYDVR0PAQH/BAQDAgeAMDwGCSsGAQQBgjcVBwQvMC0GJSsGAQQBgjcVCIGGqB2E0PsShu2dJIfO+xnTwFVmh/qlZYXZhD4CAWQCARIwHQYDVR0lBBYwFAYIKwYBBQUHAwMGCCsGAQUFBwMCMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwMwCgYIKwYBBQUHAwIwCgYIKoZIzj0EAwIDSAAwRQIhALE/ichmnWXCUKUbca3yci8oqwaLvFdHVjQrveI9uqAbAiA9hC4M8jgMBADPSzmd2uiPJA6gKR3LE03U75eqbC/rXA==";
        privateKey = "MHQCAQEEIL14JV+5nr/sE8Sppaf2IySovrhVBtt8+yz+g4NRKyz8oAcGBSuBBAAKoUQDQgAEoWCKa0Sa9FIErTOv0uAkC1VIKXxU9nPpx2vlf4yhMejy8c02XJblDq7tPydo8mq0ahOMmNo8gwni7Xt1KT9UeA==";
    }

    SignResult signedInvoiceResult = new EInvoiceSigner().SignDocument(document, x509CertificateContent, privateKey);

    // Validate Signed Invoice *** just test ***
    // In Non Production Environment,
    // Look like Validation only work for Invoice signed using Certificate and Privatekey from Zatca eInvoice SDK
    
    EInvoiceValidator eInvoiceValidator = new();
    var validationResult = eInvoiceValidator.ValidateEInvoice(signedInvoiceResult.SignedEInvoice, x509CertificateContent, pih);

    if (validationResult != null)
    {
        foreach (var e in validationResult.ValidationSteps)
        {
            Console.WriteLine(e.ValidationStepName + " : " + e.IsValid);

            if (!e.IsValid)
            {
                foreach (var x in e.ErrorMessages)
                {
                    Console.WriteLine(x);
                }
            }
            else
            {

                foreach (var x in e.WarningMessages)
                {
                    Console.WriteLine(x);
                }
            }
        }
        Console.WriteLine($"\nOverall Signed Invoice Validation : {validationResult.IsValid}!");

        if (validationResult.IsValid)
        {
            return new RequestGenerator().GenerateRequest(signedInvoiceResult.SignedEInvoice);
        }
    }

    // SignedInvoice is not valid
    return null;
}

Hope this helps anyone having the same question or issue with eInvoice Validator from .Net8 ZatcaeInvoiceSDK library.

Thank you.

Dear @eCloud

the .net 8 no error of validation its working for signing and validation without any erro, but EN & KSA schematrons error in .net 4.8 while validating invoice, signing no error.

Yes, from my test, this error happens on version 3.3.4, 3.3.5 and 3.3.6

On Version 3.3.6 i also got same error in .Net 8 Zatca.eInvoice.SDK Library.

Not sure why…
There is no explanation from the admin or developer regarding this problem.

Dear,

Kindly you need to update the generated private key with the CSR
in the zatca-einvoicing-sdk-238-R3.3.5\Data\Certificates\ec-secp256k1-priv-key.pem

If you are still facing issue, reach out to our support teams via below emails:
E-invoicing@zatca.gov.sa
sp_support@zatca.gov.sa

Thank you.
@eCloud @bhattiasadlatif @themasdev

@eCloud ,@bhattiasadlatif, @themasdev ,
I think we all should attend the Zatca live session held every Thursday to raise our issues regarding validation. when multiple people raise the point in a live session it may effect. As no one is responding to emails regarding this issue.

1 Like

Dear @sehrish02101998,

at what time Zatca live session started and its link please?

Hello guys i am facing with the same issue about zatca dll, when i am using cmd its okay, but when i am using ValidateEInvoice method its getting some error which one of them its validate EN Schematrons, validate KSA Schematrons and validate EInvoice PIH


also my .net code source its in here…
cant validate at all, could you please help me?
using Zatca.EInvoice.SDK.Contracts.Models;
using System.Xml;
using System.Text;
using Zatca.EInvoice.SDK;
using ZatcaWebAPI.Models;
using System.Xml.Linq;
using System.ComponentModel.DataAnnotations;

namespace ZatcaWebApp.Services
{
public class InvoiceService
{
private const string FilePath = @“C:\Users\tr32040\Downloads\zatca-einvoicing-sdk-238-R3.3.6\Data\PIH\pih.txt”;

    public (RequestResult requestResult, string InvoiceHash, string Base64QrCode) GenerateInvoiceRequest(InvoiceRequestModel requestModel)
    {
        try
        {
            UpdatePihFile(requestModel.PIH);

            string correctedBase64 = requestModel.XmlContent;
            int mod4 = correctedBase64.Length % 4;
            if (mod4 > 0)
            {
                correctedBase64 += new string('=', 4 - mod4);
            }

            byte[] xmlBytes = Convert.FromBase64String(correctedBase64);

            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(Encoding.UTF8.GetString(xmlBytes));

            xmlDocument = PrettyXml(xmlDocument);

            var (requestResult, invoiceHash, base64QrCode) = GenerateRequestApi(xmlDocument, requestModel.X509CertificateContent, requestModel.PrivateKeyContent, requestModel.PIH);


            return (requestResult, invoiceHash, base64QrCode);
        }
        catch (Exception ex)
        {
            throw new Exception($"An error occurred: {ex.Message}");
        }
    }

    private void UpdatePihFile(string newContent)
    {
        try
        {
            System.IO.File.WriteAllText(FilePath, newContent);
        }
        catch (Exception ex)
        {
            throw new Exception($"An error occurred: {ex.Message}");
        }
    }

    private static (RequestResult requestResult, string InvoiceHash, string Base64QrCode) GenerateRequestApi(XmlDocument document, string x509CertificateContent, string privateKey, string PIH)
    {
        SignResult signedInvoiceResult = new EInvoiceSigner().SignDocument(document, x509CertificateContent, privateKey);


        Zatca.EInvoice.SDK.EInvoiceValidator validator = new Zatca.EInvoice.SDK.EInvoiceValidator();

        var validationResult = validator.ValidateEInvoice(signedInvoiceResult.SignedEInvoice, x509CertificateContent, PIH);

        if (validationResult != null)
        {
            foreach (var e in validationResult.ValidationSteps)
            {
                Console.WriteLine(e.ValidationStepName + " : " + e.IsValid);

                if (!e.IsValid)
                {
                    foreach (var x in e.ErrorMessages)
                    {
                        Console.WriteLine(x);
                    }
                }
                else
                {

                    foreach (var x in e.WarningMessages)
                    {
                        Console.WriteLine(x);
                    }
                }
            }
            Console.WriteLine($"\nOverall Signed Invoice Validation : {validationResult.IsValid}!");

            if (validationResult.IsValid)
            {
                var (invoiceHash, base64QrCode) = ExtractInvoiceHashAndBase64QrCode(signedInvoiceResult.SignedEInvoice);

                var requestResult = new RequestGenerator().GenerateRequest(signedInvoiceResult.SignedEInvoice);
                return (requestResult, invoiceHash, base64QrCode);
            }
            else
            {
                return (null, null, null);

            }
        }
        return (null, null, null);
    }

    private static (string invoiceHash, string base64QRCode) ExtractInvoiceHashAndBase64QrCode(XmlDocument doc)
    {
        XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
        nsmgr.AddNamespace("ext", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2");
        nsmgr.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
        nsmgr.AddNamespace("cbc", "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2");
        nsmgr.AddNamespace("cac", "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2");

        string invoiceHash = doc.SelectSingleNode("//ds:Reference[@Id='invoiceSignedData']/ds:DigestValue", nsmgr)?.InnerText;
        string base64QRCode = doc.SelectSingleNode("//cac:AdditionalDocumentReference[cbc:ID='QR']/cac:Attachment/cbc:EmbeddedDocumentBinaryObject", nsmgr)?.InnerText;

        return (invoiceHash, base64QRCode);
    }

    private static XmlDocument PrettyXml(XmlDocument inputXml)
    {
        XmlDocument formattedXml = new XmlDocument() { PreserveWhitespace = true };

        using (MemoryStream memoryStream = new MemoryStream())
        {
            using (StreamWriter streamWriter = new StreamWriter(memoryStream, new UTF8Encoding(false)))
            {
                XmlWriterSettings settings = new XmlWriterSettings()
                {
                    Indent = true,
                    IndentChars = "    ",
                    OmitXmlDeclaration = false,
                    Encoding = Encoding.UTF8,
                };

                using (XmlWriter xmlWriter = XmlWriter.Create(streamWriter, settings))
                {
                    inputXml.Save(xmlWriter);
                }
            }

            string utf8Xml = Encoding.UTF8.GetString(memoryStream.ToArray()).Trim();
            formattedXml.LoadXml(utf8Xml);
        }

        return formattedXml;
    }

}

}

Is there any .net repo that i can use?
thanks for helping

Just skip the self validation. Only the library from the zatca eInvoice SDK version 3.3.3 can work properly for validation.

Sign the Document, create an api request and submit it to the sandbox compliance check. If it is accepted without any errors and or warnings then it is safe for Clearance or Reporting.

Don’t let your project get hampered by this issue.

@eCloud, have you tried the validation step from SDK 3. 3.7? In the latest version, I am encountering an ‘unknown invoice type’ error along with a Schematron validation error. If anyone can resolve the validation issue in SDK versions 3.3.4 to 3.3.7, it would be greatly appreciated if you could update the status here.

@sehrish02101998

Zatca.eInvoice.SDK v.3.3.7 .Net8 –
Validation Not Work**, back to v3.3.5.

3.3.7 Work, with IKVM.runtime.dll from zatca-einvoicing-sdk-238-R3.3.7\Lib\Dot-Net8\DLL\Zatca.EInvoice.SDK\net8.0\runtimes\win\lib\net8.0

Zatca.eInvoice.SDK v.3.3.7 .NetFx 4.8 is work good.
The bad thing is the data folder must be placed backwards in the solution folder.

    internal static string UBL_File = ConfigurationManager.ReadResource("Zatca.EInvoice.SDK.Data.ubl.xml");
    internal static string relativePathKSA = "..\\..\\..\\Data\\Rules\\schematrons\\20210819_ZATCA_E-invoice_Validation_Rules.xsl";
    internal static string KSA_Schematrons = ConfigurationManager.ReadResourceFromPath(Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigurationManager.relativePathKSA)));
    internal static string relativePathEN = "..\\..\\..\\Data\\Rules\\schematrons\\CEN-EN16931-UBL.xsl";

This makes Integration difficult.


Onboarding Info Data has been serialized to the file.

Initialization Step (Simplified EInvoice) : True
Validate XSD : True
Validate EN Schematrons : True
Validate KSA Schematrons : True
Generate EInvoice Hash : True
Parse Certificate : True
Generate EInvoice QR : True
Validate QR Code : True
Validate EInvoice Signature : True
Validate EInvoice PIH : True

Overall Signed Invoice Validation : True!
Reporting Simplified Debit Note

{
  "requestType": "Reporting",
  "requestUrl": "https://gw-fatoora.zatca.gov.sa/e-invoicing/developer-portal/invoices/reporting/single",
  "statusCode": "200-OK",
  "reportingStatus": "REPORTED",
  "validationResults": {
    "status": "PASS",
    "infoMessages": [
      {
        "status": "PASS",
        "type": "INFO",
        "code": "XSD_ZATCA_VALID",
        "category": "XSD validation",
        "message": "Complied with UBL 2.1 standards in line with ZATCA specifications"
      }
    ],
    "warningMessages": [],
    "errorMessages": []
  }
}



Onboarding Info Data has been serialized to the file.



ALL DONE!

make sure we copy ikvm and runtime folder to bin/debug directory

1 Like

@eCloud where we must put Data folder exactly in ASP.NET Solution folder ?

@Eng.Osama

It seems like there is no way, I don’t really understand how an application can access folders before the root folder. The only possible way is to patch the library to change the relative path (this is not a good way).

The best way is to ask the developer to change the Relative path in their source code or use embedded resources like accessing other files needed by libraries.

There are some posts asking for it, but they don’t get a positive response from the developer, maybe the developer doesn’t want us to use their library in our application (this is just my guess) v3.3.3 is good library, v3.3.4 to v3.3.7 the use Relative path.

1 Like

where can i put trhis Relative path. and how tto use it
windows application 4.8

3 folders back from executable file folder, normally it should be in Solution Folder.