Serialization Algorithm
To ensure data transfer over network, potential newline symbols or spaces added removed between XML and JSON elements are not changing the signature value, the solution leverages specialized data document serialization approach to ensure only significant data (names and values of fields) is used as part of the signature.
Algorithm Overview
The algorithm to implement when serializing data to get hash code to sign is:
- Documents processed recursively, starting from the root element of the document. See the note below!
- All property names are converted to culture invariant uppercase.
- All property values are taken without any processing, just like those are in the input document. E.g., if original document has value
0.0
, it should be moved to serialized string as0.0
and cannot be moved as0
or0.00
. - All property names and simple type values (those, which are not objects) are enclosed into double quotes symbol
"
. - In JSON – entire array serialization result is prefixed with the array property name and every array element is preceded with the array property name. This is one place, where difference with XML exists, as in XML there would be one prefix for the entire array serialization output and other names for individual elements. E.g.:
- In JSON we would receive something like
“TAXABLEITEMS”“TAXABLEITEMS”<taxable item #1 serialization output>“TAXABLEITEMS”<taxable item #2 serialization output> …
- While in XML:
“TAXABLEITEMS”“TAXABLEITEM”<taxable item #1 serialization output>“TAXABLEITEM”<taxable item #2 serialization output> …
- In JSON we would receive something like
- Double quotes
"
in XML fields are replaced with the escape sequence\”
to prevent users from being able to create different documents with same serialization output. This is not needed in JSON as\”
is generally the way to store double quotes in the property values there.
As an example, see the document content without signature in XML and JSON and resulting strings that would be produced as a result of data serialization (XML and JSON) before applying SHA256 hashing.
Note!
eInvoicing:
The root of the document is not the root of the entire submission. For XML root of the document is
eReceipt:
Receipts are grouped into batches. Every batch is processed as one submission. Serialization is applied to the entire batch. Batches in JSON format only, are supported.
The JSON and XML files referenced here are just samples and might not contain the recent documents structure, always refer to the recent documents structure in Egyptian eInvoicing SDK.postman_collection.json (use right-click Save As…)
Pseudo Code Implementation
Implementation for JSON:
function string Serialize(documentStructure)
if documentStructure is simple value type
return """ + documentStructure.value + """
end if
var serializedString = ""
foreach element in the structure:
if element is not array type
serializeString.Append (""" + element.name.uppercase + """)
serializeString.Append ( Serialize(element.value) )
end if
if element is of array type
serializeString.Append (""" + element.name.uppercase + """)
foreach array element in element:
// use below line for JSON because subelements of array in JSON do not have own names
serializeString.Append (""" + element.name.uppercase + """)
serializeString.Append ( Serialize(arrayelement.value) )
end foreach
end if
end foreach
return serializedString
end function
Implementation for XML:
function string Serialize(documentStructure)
if documentStructure is simple value type
return """ + EscapeQuotes(documentStructure.value) + """
end if
var serializedString = ""
foreach element in the structure:
serializeString.Append (""" + element.name.uppercase + """)
serializeString.Append ( Serialize(element.value) )
end foreach
return serializedString
end function
function string EscapeQuotes(stringValue){
return Replace(stringValue, """, "\"")
}