Qoyod
Pricing

Knowledge Base

XML Invoice: The Technical Format of the E-Invoice

Every Phase Two-compliant e-invoice in Saudi Arabia is not merely an image or a PDF file, but a structured XML document that systems read before any human does. This document is built on a fixed, predefined structure: a specific order of elements, precise nesting between them, and main sections each with a clear role. If this order is broken or a mandatory element is missing, the Fatoora platform rejects the document or issues a warning.

This technical guide is aimed at developers and technical accountants who want to understand the structure of the e-invoice document from the inside: what the three major sections are, how they nest into a single XML tree, and the order of elements between them. Here we focus on the overall structure only. The deep details of each section (header fields, line-item composition, the XSD schema) have their own standalone guides, which we point to where relevant. This guide is part of the technical documentation for e-invoicing.

builds Qoyod E-Invoicing software this structure automatically behind the scenes, so you never need to write XML by hand. But understanding the structure helps you read the generated invoice, interpret validation messages, and confirm the data is complete before sending.

What is meant by e-invoice structure?

The invoice structure is the way invoice data is arranged inside a single XML document. This structure follows the UBL 2.1 standard (Universal Business Language), the global standard adopted by the Zakat, Tax and Customs Authority (ZATCA) for Phase Two of e-invoicing.

The document is not a flat list of fields, but a tree. It starts with a single root element that contains everything, then the sections branch off from it, and each section branches into smaller elements. This nesting is the heart of the idea: an element’s position within the tree determines its meaning. The same number means something different if it is placed in the header, inside a line item, or in the totals section.

To illustrate, here is the simplest possible structure of a tax invoice before filling in the details:

<Invoice>
  <!-- 1. Header: who, to whom, when, identification numbers -->
  <cbc:ID>INV-001</cbc:ID>
  <cbc:IssueDate>2026-06-23</cbc:IssueDate>

  <!-- 2. Line items: one line per product or service -->
  <cac:InvoiceLine> ... </cac:InvoiceLine>

  <!-- 3. Totals and tax + stamp extensions -->
  <cac:TaxTotal> ... </cac:TaxTotal>
  <cac:LegalMonetaryTotal> ... </cac:LegalMonetaryTotal>
</Invoice>

Notice two prefixes that recur: cbc: andcac:. The first is short for Common Basic Components and refers to simple fields with a single value (a number, date, or text). The second is short for Common Aggregate Components and refers to composite elements that contain other elements inside them. This distinction explains why some tags hold a direct value while others hold further tags.

These prefixes are not decoration, but namespace names (Namespaces) defined in the document header. Every invoice document opens by declaring these namespaces on the root element, so systems know which standard each tag came from. A missing namespace declaration, or an error in its URI, makes the document unreadable at its very core, before any content-level validation.

<Invoice
  xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
  xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
  xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
  xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2">
  ...
</Invoice>

The namespace declaration ext: is what later allows the cryptographic stamp extensions to be added. The default namespace (with no prefix), meanwhile, indicates that the document is of type Invoice in the UBL standard. These four lines are the document’s “wrapper” that encloses all three sections.

Explanation of the e-invoice document structure

From the printed invoice to the XML file
How the human-readable invoice is transformed into a structured XML file.
1

Human-readable invoice

2

Tagging each field with an XML element

3

Structured, machine-readable XML file

Converting the invoice into XML makes it processable and validatable by machine.

The three main sections of the invoice document

Whatever the invoice type (a B2B tax invoice for businesses or a simplified B2C invoice for consumers), the document is logically divided into three major parts. Understanding these three parts is the key to reading any e-invoice.

1. Header: the identity of the invoice and its parties

The header is the top part of the document. It carries the data that identifies the invoice as a whole: its number, type, date, and unique identifier, in addition to the seller’s and buyer’s data. This data applies to the entire invoice, not to any single line item.

The most prominent header elements in their natural order:

<cbc:ProfileID>reporting:1.0</cbc:ProfileID>
<cbc:ID>INV-2026-001</cbc:ID>
<cbc:UUID>3cf5ee18-ee25-4a3b-9b1c-1f2e3a4b5c6d</cbc:UUID>
<cbc:IssueDate>2026-06-23</cbc:IssueDate>
<cbc:IssueTime>14:30:00</cbc:IssueTime>
<cbc:InvoiceTypeCode name="0100000">388</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>SAR</cbc:DocumentCurrencyCode>

<cac:AccountingSupplierParty> ... </cac:AccountingSupplierParty>
<cac:AccountingCustomerParty> ... </cac:AccountingCustomerParty>

Here we see a live example of nesting. AccountingSupplierParty is a composite element that contains within it the seller’s name, tax number, and address. The header, then, is not made of flat fields, but contains composite elements that branch further. Each of these fields has its own mandatory rules and specific format, which we do not expand on here.

To understand nesting further, look at how the seller element is built internally. It does not carry the seller’s name alone, but contains a party element Party which in turn branches into the legal name, the tax number, the address, and the identification scheme:

<cac:AccountingSupplierParty>
  <cac:Party>
    <cac:PartyIdentification>
      <cbc:ID schemeID="CRN">1010101010</cbc:ID>
    </cac:PartyIdentification>
    <cac:PostalAddress> ... </cac:PostalAddress>
    <cac:PartyTaxScheme>
      <cbc:CompanyID>300000000000003</cbc:CompanyID>
    </cac:PartyTaxScheme>
    <cac:PartyLegalEntity>
      <cbc:RegistrationName>Example Trading Establishment</cbc:RegistrationName>
    </cac:PartyLegalEntity>
  </cac:Party>
</cac:AccountingSupplierParty>

This multi-layer nesting is what makes the header deeper than it appears. A single element on the surface (the seller) encompasses four layers of nested elements. The buyer element AccountingCustomerParty follows the same structure. The essential difference between them is that the tax invoice (B2B) requires a tax number for the buyer, while the simplified invoice (B2C) does not, because the buyer is an end consumer.

To go deeper into each header field (the unique identifier UUID, the invoice type code, the data of both parties, and the invoice counter ICV), see the dedicated guide “Invoice Header,” which addresses each element individually with its examples and rules.

2. Line Items: the details of products and services

The second section is the body of the invoice: the list of line items. Each line in the invoice (a product or service) is represented by an independent InvoiceLine element. If the business sells three items on a single invoice, the element is repeated three times within the same document.

<cac:InvoiceLine>
  <cbc:ID>1</cbc:ID>
  <cbc:InvoicedQuantity unitCode="PCE">2</cbc:InvoicedQuantity>
  <cbc:LineExtensionAmount currencyID="SAR">200.00</cbc:LineExtensionAmount>
  <cac:Item>
    <cbc:Name>Consulting service</cbc:Name>
  </cac:Item>
  <cac:Price>
    <cbc:PriceAmount currencyID="SAR">100.00</cbc:PriceAmount>
  </cac:Price>
</cac:InvoiceLine>

Each line item carries its serial number, quantity, unit of measure, price, line total, and item name, in addition to its own tax details. Notice the nesting again: Item andPrice two composite elements inside the line item, not two flat fields. This allows each line item to carry a tax rate different from the others (a 15% taxable item and an exempt item, for example) within a single invoice.

The order of line items matters: they are numbered ascending from 1, and the line totals must match the totals in the third section, otherwise arithmetic validation fails. As for the detailed rules of line-item composition (line-level discounts, tax codes, and units of measure), that is the subject of the dedicated guide “Invoice Lines.”

Explanation of the repetition of the line-item element within the document

The layers of the invoice XML file
The main parts that make up the invoice document in XML format.
XML file structure

Header: general invoice data

Invoice parties (seller and buyer)

Lines & Totals

Extensions and cryptographic stamp

Each layer is represented by specific XML elements in line with the standard.

3. Totals, Tax & Extensions: the legal stamp

The third section brings together the invoice figures in their final form, and carries the security data that proves its integrity. It splits in practice into two adjacent groups: the tax totals, and the legal monetary totals.

<cac:TaxTotal>
  <cbc:TaxAmount currencyID="SAR">30.00</cbc:TaxAmount>
  <cac:TaxSubtotal>
    <cbc:TaxableAmount currencyID="SAR">200.00</cbc:TaxableAmount>
    <cbc:TaxAmount currencyID="SAR">30.00</cbc:TaxAmount>
    <cac:TaxCategory>
      <cbc:Percent>15.00</cbc:Percent>
    </cac:TaxCategory>
  </cac:TaxSubtotal>
</cac:TaxTotal>

<cac:LegalMonetaryTotal>
  <cbc:LineExtensionAmount currencyID="SAR">200.00</cbc:LineExtensionAmount>
  <cbc:TaxExclusiveAmount currencyID="SAR">200.00</cbc:TaxExclusiveAmount>
  <cbc:TaxInclusiveAmount currencyID="SAR">230.00</cbc:TaxInclusiveAmount>
  <cbc:PayableAmount currencyID="SAR">230.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>

Here appears value-added tax at its rate (15%), the taxable amount, the total before and after tax, and the amount due for payment. These figures must be arithmetically consistent with the line-item totals in the second section. Any difference due to rounding is handled according to specific rules in the standard.

Alongside the totals, this part carries the mandatory security elements in Phase Two, usually placed in the signature extension at the top of the document within UBLExtensions:

<ext:UBLExtensions>
  <ext:UBLExtension>
    <ext:ExtensionContent>
      <!-- Cryptographic Stamp with a CSID key -->
      <!-- Document Hash -->
      <!-- Public key and digital signature -->
    </ext:ExtensionContent>
  </ext:UBLExtension>
</ext:UBLExtensions>

The cryptographic stamp is a digital signature using the ECDSA algorithm, created with the Cryptographic Stamp Identifier (CSID) issued by the Authority for each device or branch. Added to it are the document hash (Hash using the SHA-256 algorithm), the hash of the previous invoice to form a linked chain, and a QR code. Together, these elements make the invoice authenticated and tamper-resistant. Generating these extensions and managing the CSID certificate are done automatically in Qoyod.

How the sections nest within the document tree

Now that we know the three sections, let us look at the full picture. Everything lives inside a single root element named Invoice. Directly beneath it come the stamp extensions first, then the simple header fields, then the composite header elements (seller and buyer), then the tax totals, then the monetary totals, and finally the line items.

It may seem surprising that the line items come at the end of the document even though they are the visual “body” of the invoice. This is one of the most important differences between the invoice’s visual form and its actual structure in XML: the visual order for the reader differs from the order of elements in the tree. What matters to systems is an element’s position within the hierarchy, not its place on the page.

Here is the full structure simplified in the actual order of its elements:

<Invoice>
  <ext:UBLExtensions> ... </ext:UBLExtensions>   <!-- stamp and signature -->

  <cbc:ProfileID> ... </cbc:ProfileID>            <!-- start of header -->
  <cbc:ID> ... </cbc:ID>
  <cbc:UUID> ... </cbc:UUID>
  <cbc:IssueDate> ... </cbc:IssueDate>
  <cbc:InvoiceTypeCode> ... </cbc:InvoiceTypeCode>
  <cbc:DocumentCurrencyCode> ... </cbc:DocumentCurrencyCode>
  <cac:AccountingSupplierParty> ... </cac:AccountingSupplierParty>
  <cac:AccountingCustomerParty> ... </cac:AccountingCustomerParty>

  <cac:TaxTotal> ... </cac:TaxTotal>              <!-- start of totals -->
  <cac:LegalMonetaryTotal> ... </cac:LegalMonetaryTotal>

  <cac:InvoiceLine> ... </cac:InvoiceLine>        <!-- line items at the end -->
  <cac:InvoiceLine> ... </cac:InvoiceLine>
</Invoice>

This order is not optional. The UBL 2.1 standard imposes a specific sequence for elements within the parent element. Placing InvoiceLine before TaxTotal for example violates the schema and leads to the document being rejected at validation. This is why Qoyod always builds the tree in the correct sequence without any intervention from you.

Explanation of the order of elements within the invoice tree

Two paths for the invoice: XML versus PDF/A-3
Each format has a different destination and purpose in the e-invoice.
Standard XML file PDF/A-3 file
Destination The Fatoora platform and systems The customer
Readability Machine (for systems) Human (for display)
Purpose Processing and validation Displaying and reading the invoice
XML is sent to the Authority, while PDF/A-3 is delivered to the customer with the XML embedded.

The difference between structure and schema

Many people confuse the invoice structure with the invoice schema. The difference is fundamental. The structure is the actual order of elements in a specific invoice document. The schema , meanwhile, is the set of rules that govern that structure: which elements are mandatory, which are optional, what type of value is allowed in each field, and their correct order.

In other words: the schema is the template, and the structure is the document that follows the template. When you send your invoice to the Fatoora platform, the platform validates that your document’s structure matches the approved schema. Any violation (a missing mandatory element, a wrong order, or a value in an incorrect format) is detected at this stage. The details of the schema files and the XSD validation rules are the subject of the dedicated guide “Invoice Schema.”

The journey of the structure from creation to acceptance

The invoice structure passes through a series of steps from the moment it is created until it is accepted by the Authority. Understanding this journey completes the picture, because the structure is not static; it is built, stamped, and sent in a specific order.

  1. Building the tree: The document is generated with its three sections, ordered according to the mandatory UBL sequence, with the namespace declarations on the root element.
  2. Computing the hash (Hash): A SHA-256 hash is computed for the document after its canonicalization (Canonicalization), and is linked to the hash of the previous invoice to form the chain.
  3. The cryptographic stamp: The document is signed with the Cryptographic Stamp Identifier (CSID), so the signature and public key are added inside UBLExtensions.
  4. Generating the QR code: The QR code is built in TLV format and embedded in the structure, carrying the seller’s data, the tax number, the total, the hash, and the signature.
  5. Validation and submission: The document is sent to the Fatoora platform. The tax invoice undergoes clearance and returns stamped by the Authority, while the simplified invoice is reported within 24 hours.

Any error in the order of the sections is detected at validation before the journey is complete. This is why the document is built in the correct sequence from the start, rather than being reordered later. The invoice counter (ICV) and the hash of the previous invoice ensure that each invoice comes in its correct position within the business’s invoice chain, so an invoice cannot be deleted or another inserted without breaking the chain.

This interlinking between the hash, the counter, and the signature is what turns the document from an editable text file into an authenticated record. If someone changed a single number in any section after stamping, the computed hash would differ from the stored hash, and the tampering would be exposed immediately.

A complete example: reading an invoice from top to bottom

Let us bring together what we have covered into a single sequential reading of a complete invoice document. Start from the root element Invoice with its namespace declarations. The first thing you encounter is the UBLExtensions extension that carries the stamp and signature. This is the security part that proves the document’s authenticity.

After it, the simple header fields begin: the profile identifier ProfileID which determines whether the invoice is for clearance or reporting, then the invoice number, its unique identifier UUID, its date, its type code, and its currency. Next come the composite header elements: the seller with its four layers, then the buyer with its similar structure.

We then move on to the totals: TaxTotal carries the total tax and its breakdown by rate and taxable amount, then LegalMonetaryTotal with its four amounts (line total, the amount before tax, the amount including it, and the amount due). Finally come the line items InvoiceLine one after another, each line item with its quantity, price, item, and tax.

If you read any invoice in this order, you will know the position of each piece of data immediately. The date in the header, the item price in the line item, the total tax in the totals section, and the signature in the extension. This discipline in positions is what makes millions of invoices machine-processable without ambiguity.

Start today

Phase Two-compliant invoices without writing a single line of XML

Qoyod builds the complete e-invoice structure automatically: the header, line items, totals, and cryptographic stamp, in the order the Authority requires. You write the invoice, and Qoyod handles the rest.

Start your free trial and issue compliant invoices

Invoice types and their effect on the structure

Invoice types share the same overall structure, but they differ in some fields and in the way they are processed by the Authority. The two most prominent types:

  • The tax invoice (B2B): used between businesses. It is subject to “Clearance,” meaning it is sent to the Authority first, which returns it stamped, and it is not delivered to the buyer until after that.
  • The simplified tax invoice (B2C): used with the consumer. It is delivered to the buyer immediately, then reported to the Authority within 24 hours (“Reporting”).

Alongside them, the credit note and the debit note follow the same structure with additional fields that link them to the original invoice. The difference in structure between these types is usually limited to the invoice type code InvoiceTypeCode and some fields related to the other party, while the three major sections remain constant across all of them.

The position of the QR code in the structure

The QR code is an integral part of the invoice structure, not merely a visual addition on the page. In Phase Two, the code is embedded within the document in TLV format (Tag-Length-Value), that is, a series of tags each with a number, a length, and a value, encoded in Base64.

The QR code of the tax invoice carries nine tags: the seller’s name, the seller’s tax number, the timestamp, the invoice total including tax, the total tax, the document hash, the cryptographic stamp, the public key, and the signature. These nine tags are drawn from the three sections: the seller’s name and number from the header, the totals from the totals section, and the hash and stamp from the security extension.

That is, the QR code is not an independent fourth section, but an encoded summary of the data distributed across the three sections. This explains why it is generated at the end of the journey after the structure and stamp are complete: it cannot be built before the hash is computed and the document is signed, because it carries them.

Common structural errors and how to read them

Most validation messages arise from a flaw in the structure rather than in the numbers themselves. Knowing which section the error belongs to shortens the time to a solution. The most prominent patterns:

  • A missing mandatory element in the header: The absence of the seller’s tax number or the invoice type code halts validation immediately, because these fields identify the invoice as a whole.
  • A wrong order of sections: Placing InvoiceLine before TaxTotal violates the UBL sequence and is rejected, even if the values are correct.
  • Arithmetic inconsistency: If the sum of the line items does not equal the value of LineExtensionAmount in the totals, the conflict between the second and third sections is detected.
  • An incorrect identifier format: A commercial registration number or tax number with the wrong number of digits is caught at the field level in the header before submission.

The practical rule: read the validation message, identify the element mentioned, then ask which section it belongs to. This positioning leads you directly to the data source that needs correction, whether it is the business setup, the customer data, or a specific line item.

Why does understanding this structure matter to you?

Even if you never write XML by hand, understanding the structure benefits you practically in several situations:

  • Interpreting validation messages: When the Authority issues a warning, it usually points to a specific element in the tree. Knowing which section the element belongs to speeds up diagnosing the cause.
  • Reviewing data completeness: You realize which data belongs to the header (once per invoice) and which repeats with each line item, so you review the correct source when something is missing.
  • Software integration: If you connect an external system via an API, you need to understand the positions of elements to read the generated invoice or build your reports on it.
  • Verifying the integrity of the totals: You know that the line-item totals must equal the totals, so you catch data-entry errors before submission.

Ultimately, the structure is not an isolated technical detail, but the language your systems use to communicate with the Fatoora platform. The deeper you understand it, the fewer errors your invoices have and the faster you resolve any warning.

How Qoyod handles the invoice structure on your behalf

Qoyod is a solution compliant with Phase Two of e-invoicing. When any invoice is issued, Qoyod builds the complete XML document according to the UBL 2.1 standard: it orders the header, line items, and totals in the sequence the schema requires, generates the cryptographic stamp, the QR code, and the chain hash, and manages the CSID certificate for each branch.

Qoyod also validates the format of the identification numbers (the commercial registration, the tax number, and the other party’s identifiers) before submission, catching one of the most common causes of warnings early. It then handles the clearance path for business-to-business invoices, and the reporting path within 24 hours for simplified invoices. All of this without you writing a single line of XML.

Try Qoyod free for 14 days, with no credit card.

A structural summary of the three sections

To fix the picture in mind, here is what each section carries and its position in the tree. The header is at the top of the document after the security extension, and carries what applies to the whole invoice: identification numbers, dates, currency, and the seller’s and buyer’s data with their nested layers. Its data recurs once per invoice.

The totals section follows the header, and carries the tax figures and final amounts that must be arithmetically consistent with the line items. The line items, meanwhile, come at the end of the document; their element repeats for each item, and each line item carries its own quantity, price, and tax. The security extension at the top links everything with a stamp, a hash, and a signature that turns the document into an authenticated record.

These three sections, with their wrapper of namespaces and their security extensions, make up every e-invoice in Saudi Arabia. A difference in invoice type changes some fields, not the structure. And once you master reading this structure, diagnosing any warning and understanding any generated invoice becomes straightforward.

Frequently asked questions

What are the main sections in the structure of the e-invoice?
Three sections: the header (the identity of the invoice and its parties), the line items (one line per product or service), and the totals and tax with the cryptographic stamp extensions. All of them live inside a single root element named Invoice.

What is the structure standard adopted in Saudi Arabia?
The UBL 2.1 standard (Universal Business Language), the global standard adopted by the Zakat, Tax and Customs Authority for Phase Two of e-invoicing. The document format is XML.

Why do the line items come at the end of the document even though they are the body of the invoice?
Because the visual order for the reader differs from the order of elements in the XML tree. The UBL standard imposes a specific sequence in which the header and totals come before the line items. What matters to systems is an element’s position in the tree, not its place on the page.

Do I need to write XML myself to issue a compliant invoice?
No. Qoyod builds the complete XML structure automatically, so you enter the invoice data through a simple interface and Qoyod generates the compliant document in the correct order and with the cryptographic stamp.

What is the difference between the invoice structure and its schema?
The structure is the actual order of elements in a specific invoice. The schema (Schema) is the set of rules that govern that structure: the mandatory and optional elements, their formats, and their order. The schema is a template, and the structure is a document that follows the template.

Does the structure change with the invoice type?
The three major sections are constant across all types. Some fields and the invoice type code InvoiceTypeCode differ between the tax invoice (B2B), the simplified invoice (B2C), and the notes, but the overall structure is one.

Guides

Continue your learning journey

Explore the rest of Qoyod’s guides, or start applying what you’ve learned.

Live webinars hosted by the Qoyod team to help you use the software easily and answer your questions.

Discover Qoyod’s latest updates, ongoing improvements, and new features in one place.

Our team is ready to help you and provide instant support for any issue you face, around the clock.