Hello,
I’m facing an issue when validating the signed invoice with the compliance API.
The error returned is:
The invoice hash API body does not match the (calculated) Hash of the XML
Details:
-
The XML invoice is generated and signed according to ZATCA Phase 2 requirements.
-
After signing, I calculate the invoice hash and send it in the API body.
-
However, the compliance check returns the above error, meaning the API’s calculated hash doesn’t match mine.
HERE IS MY CODE .NETprivate async Task TestForCompliance(string invoice, EGSUnit egsUnit, CSID complianceCSID, CancellationToken cancellationToken)
{
string id = Guid.NewGuid().ToString();
var invoiceForEGS = invoice
.Replace(“EGS_UUID”, id)
.Replace(“VAT_NUMBER”, egsUnit.VAT.RegistrationNumber)
.Replace(“VAT_NAME”, egsUnit.VAT.Name);var signed = Crypto.SignInvoice(invoiceForEGS, complianceCSID.BinarySecurityToken, egsUnit.PrivateKey); // هنا نستخدم الـ UUID اللي فعلياً في الفاتورة الموقعة return await \_zatcaApiService.ComplianceCheck( signed.UniqueInvoiceId, egsUnit, complianceCSID, signed.Invoice, // XML النهائي signed.Hash, // الهاش النهائي المتوافق cancellationToken
);
}
public async Task ComplianceCheck(string uuid,EGSUnit egsUnit, CSID complianceCSID, string signedInvoice, string invoiceHash, CancellationToken cancellationToken = default)
{
SetPortal(egsUnit);
_ = complianceCSID ?? throw new ArgumentNullException(“Compliance CSID not found.\n\r Compliance CSID must be generated before compliance checks”);
var content = JsonContent.Create(new
{
Uuid = uuid,
InvoiceHash = invoiceHash,
Invoice = Convert.ToBase64String(Encoding.UTF8.GetBytes(signedInvoice))
});
AddAuthHeader(complianceCSID);
return await GetResponseWithRetry(() => _httpClient.PostAsync(“compliance/invoices”, content, cancellationToken), result => result.IsSuccessStatusCode || result.StatusCode == System.Net.HttpStatusCode.BadRequest);
}