I hope this message finds you well. I am currently facing an issue with the PIH (Previous Invoice Hash) value during validation in the ZATCA e-invoicing system in TEST environment.
Here’s the scenario:
When I use the PIH value: NWZlY2ViNjZmZmM4NmYzOGQ5NTI3ODZjNmQ2OTZjNzljMmRiYzIzOWRkNGU5MWI0NjcyOWQ3M2EyN2ZiNTdlOQ==
it is successfully validated.
However, when I use the PIH value: JWJF1kw2SgDsAot6aF1OpPi/ZB7PIPa+iOqW5qIWptA=
(which was retrieved from a previous cleared invoice), the validation fails, and the response indicates:
3.*“[PIH] validation result: FAILED.”**
From my understanding:
The PIH should be unique for every invoice.
I used the PIH from the cleared invoice, which had the value: JWJF1kw2SgDsAot6aF1OpPi/ZB7PIPa+iOqW5qIWptA=,
yet the validation still failed.
Could anyone please guide me on:
How to properly calculate or retrieve the correct PIH value for validation?
Any best practices to ensure the integrity and correctness of the PIH?
Your insights and suggestions will be greatly appreciated.
Thank you in advance for your support!
I’m still awaiting a response, but I’d like to highlight a potential issue with the PIH calculation.
The documentation and data dictionary specify that the PIH should be the Base64-encoded SHA256 hash of the previous invoice, resulting in a maximum length of 44 characters (calculated as 4×32/3=44). However, it seems the calculation method has changed. The PIH in the current SDK produces a hash with double the length, suggesting a different process is being used.
From my observations, the new calculation appears to follow these steps:
Compute the SHA256 hash of the previous invoice, yielding 32 bytes.
Represent those 32 bytes as a hexadecimal string.
Encode the UTF-8 representation of the hexadecimal string into a Base64 string, resulting in an 88-character hash.
Despite this, I’m still using the original approach outlined in the documentation (directly encoding the SHA256 hash into a Base64 string). So far, invoices are being reported successfully with this method.
However, clarification from the ZATCA team is essential. Can we continue using the documented approach, or should we switch to the logic implemented in the SDK?