Not sure, I think you need to add this line in your Invoice
<?xml version="1.0" encoding="UTF-8"?>
and resigned your XML.
Your xml
Your xml + encoding tag
For your code, as you use Zatca.eInvoice.SDK you can try this simple code to signing, Create Api Payload, get InvoiceHash and get base64QrCode.
using Newtonsoft.Json;
using System;
using System.IO;
using System.Text;
using System.Xml;
using Zatca.EInvoice.SDK;
using Zatca.EInvoice.SDK.Contracts.Models;
namespace ConsoleApp2
{
internal class Program
{
static void Main()
{
string x509CertificateContent = "MIID3jCCA4SgAwIBAgITEQAAOAPF90Ajs/xcXwABAAA4AzAKBggqhkjOPQQDAjBiMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxEzARBgoJkiaJk/IsZAEZFgNnb3YxFzAVBgoJkiaJk/IsZAEZFgdleHRnYXp0MRswGQYDVQQDExJQUlpFSU5WT0lDRVNDQTQtQ0EwHhcNMjQwMTExMDkxOTMwWhcNMjkwMTA5MDkxOTMwWjB1MQswCQYDVQQGEwJTQTEmMCQGA1UEChMdTWF4aW11bSBTcGVlZCBUZWNoIFN1cHBseSBMVEQxFjAUBgNVBAsTDVJpeWFkaCBCcmFuY2gxJjAkBgNVBAMTHVRTVC04ODY0MzExNDUtMzk5OTk5OTk5OTAwMDAzMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEoWCKa0Sa9FIErTOv0uAkC1VIKXxU9nPpx2vlf4yhMejy8c02XJblDq7tPydo8mq0ahOMmNo8gwni7Xt1KT9UeKOCAgcwggIDMIGtBgNVHREEgaUwgaKkgZ8wgZwxOzA5BgNVBAQMMjEtVFNUfDItVFNUfDMtZWQyMmYxZDgtZTZhMi0xMTE4LTliNTgtZDlhOGYxMWU0NDVmMR8wHQYKCZImiZPyLGQBAQwPMzk5OTk5OTk5OTAwMDAzMQ0wCwYDVQQMDAQxMTAwMREwDwYDVQQaDAhSUlJEMjkyOTEaMBgGA1UEDwwRU3VwcGx5IGFjdGl2aXRpZXMwHQYDVR0OBBYEFEX+YvmmtnYoDf9BGbKo7ocTKYK1MB8GA1UdIwQYMBaAFJvKqqLtmqwskIFzVvpP2PxT+9NnMHsGCCsGAQUFBwEBBG8wbTBrBggrBgEFBQcwAoZfaHR0cDovL2FpYTQuemF0Y2EuZ292LnNhL0NlcnRFbnJvbGwvUFJaRUludm9pY2VTQ0E0LmV4dGdhenQuZ292LmxvY2FsX1BSWkVJTlZPSUNFU0NBNC1DQSgxKS5jcnQwDgYDVR0PAQH/BAQDAgeAMDwGCSsGAQQBgjcVBwQvMC0GJSsGAQQBgjcVCIGGqB2E0PsShu2dJIfO+xnTwFVmh/qlZYXZhD4CAWQCARIwHQYDVR0lBBYwFAYIKwYBBQUHAwMGCCsGAQUFBwMCMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwMwCgYIKwYBBQUHAwIwCgYIKoZIzj0EAwIDSAAwRQIhALE/ichmnWXCUKUbca3yci8oqwaLvFdHVjQrveI9uqAbAiA9hC4M8jgMBADPSzmd2uiPJA6gKR3LE03U75eqbC/rXA==";
string privateKeyContent = "MHQCAQEEIL14JV+5nr/sE8Sppaf2IySovrhVBtt8+yz+g4NRKyz8oAcGBSuBBAAKoUQDQgAEoWCKa0Sa9FIErTOv0uAkC1VIKXxU9nPpx2vlf4yhMejy8c02XJblDq7tPydo8mq0ahOMmNo8gwni7Xt1KT9UeA==";
string xmlPath = @"C:\Tmp\testxml.xml";
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(xmlPath);
// Make sure xml has encoding tag and not linearized to avoid Hasing Error by Zatca Server
xmlDocument = PrettyXml(xmlDocument);
// Call GenerateRequestApi and capture the results
var (requestResult, invoiceHash, base64QrCode) = GenerateRequestApi(xmlDocument, x509CertificateContent, privateKeyContent);
// Print all results
Console.WriteLine("Request Result: \n" + JsonConvert.SerializeObject(requestResult.InvoiceRequest));
Console.WriteLine("\nInvoice Hash: " + invoiceHash);
Console.WriteLine("\nBase64 QR Code: " + base64QrCode);
Console.ReadLine();
}
public static (RequestResult requestResult, string InvoiceHash, string Base64QrCode) GenerateRequestApi(XmlDocument document, string x509CertificateContent, string privateKey)
{
SignResult signedInvoiceResult = new EInvoiceSigner().SignDocument(document, x509CertificateContent, privateKey);
if (signedInvoiceResult.IsValid)
{
// Get InvoiceHash and QrCode from Signed Invoice
var (invoiceHash, base64QrCode) = ExtractInvoiceHashAndBase64QrCode(signedInvoiceResult.SignedEInvoice);
var requestResult = new RequestGenerator().GenerateRequest(signedInvoiceResult.SignedEInvoice);
return (requestResult, invoiceHash, base64QrCode);
}
else
{
// Handle the case when the signing is not valid
return (null, null, null); // Adjust as needed
}
}
public 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");
// Extracting specific DigestValue for invoiceSignedData
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);
}
public 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))) // false to exclude BOM
{
XmlWriterSettings settings = new XmlWriterSettings()
{
Indent = true,
IndentChars = " ",
OmitXmlDeclaration = false,
Encoding = Encoding.UTF8,
};
using (XmlWriter xmlWriter = XmlWriter.Create(streamWriter, settings))
{
inputXml.Save(xmlWriter);
}
}
// Get the UTF-8 encoded string from the MemoryStream
string utf8Xml = Encoding.UTF8.GetString(memoryStream.ToArray()).Trim();
// Load the UTF-8 XML string into the new XmlDocument
formattedXml.LoadXml(utf8Xml);
}
return formattedXml;
}
}
}