Skip to main content

Example invoice (full UBL) and the values you supply

Example Oman Invoice (Full UBL)โ€‹

<?xml version="1.0" encoding="UTF-8"?>
<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">

<!-- Oman PINT OM -->
<cbc:CustomizationID>urn:peppol:pint:billing-1@om-1</cbc:CustomizationID>
<cbc:ProfileID>urn:peppol:bis:billing</cbc:ProfileID>

<cbc:ID>OM-INV-2026-001</cbc:ID>
<cbc:IssueDate>2026-02-08</cbc:IssueDate>
<cbc:IssueTime>12:00:00Z</cbc:IssueTime>
<cbc:DueDate>2026-03-10</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>OMR</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>PO-2026-456</cbc:BuyerReference>

<!-- Seller (Oman company) -->
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="0248">OM1100012345</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Al Haya Trading LLC</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Sultan Qaboos Street</cbc:StreetName>
<cbc:CityName>Muscat</cbc:CityName>
<cbc:PostalZone>100</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>OM</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>OM1234567890</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Al Haya Trading LLC</cbc:RegistrationName>
<cbc:CompanyID>1234567890</cbc:CompanyID>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingSupplierParty>

<!-- Buyer (Oman company) -->
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="0248">OM1100054321</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Oman National Corp</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Al Khuwair Road</cbc:StreetName>
<cbc:CityName>Muscat</cbc:CityName>
<cbc:PostalZone>200</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>OM</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>OM9876543210</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Oman National Corp</cbc:RegistrationName>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingCustomerParty>

<cac:PaymentMeans>
<cbc:PaymentMeansCode>30</cbc:PaymentMeansCode>
</cac:PaymentMeans>

<cac:TaxTotal>
<cbc:TaxAmount currencyID="OMR">200.000</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="OMR">4000.000</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="OMR">200.000</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>

<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="OMR">4000.000</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="OMR">4000.000</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="OMR">4200.000</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="OMR">4200.000</cbc:PayableAmount>
</cac:LegalMonetaryTotal>

<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="HUR">160</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="OMR">4000.000</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>IT Consulting Services - January 2026</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="OMR">25.000</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
</Invoice>

What GoRoute adds on the rendered-document pathsโ€‹

Applies only where GoRoute renders the document

This applies to the paths where GoRoute composes the UBL itself โ€” POST /api/v1/invoices, drafts, the ERP connectors and the pollers. It does not apply to UBL you submit to POST /api/v1/documents, which is transmitted exactly as submitted.

On the rendered-document paths GoRoute adds one element before Peppol transmission, and only on a B2C invoice:

  1. QR Code โ€” AdditionalDocumentReference[ID='QR'] with the Appendix D TLV
  2. A readable PDF (GET /api/v1/transactions/{id}/pdf) titled by document kind โ€” ูุงุชูˆุฑุฉ ุถุฑูŠุจูŠุฉ ู…ุจุณุทุฉ / Simplified Tax Invoice, ูุงุชูˆุฑุฉ ุถุฑูŠุจูŠุฉ / Tax Invoice, ุฅุดุนุงุฑ ุฏุงุฆู† / Credit Note โ€” with the same QR printed on it. "Fawtara" (ููˆุชุฑุฉ) names the programme; the document is a tax invoice.

No hash and no signature are added: Oman defines neither.

If a document already carries its own AdditionalDocumentReference[ID='QR'], the pipeline leaves it in place rather than adding a second one.

If you are submitting final UBL, generate whatever elements your invoice needs yourself.

Values you must supply yourselfโ€‹

Every value in the table below is one the Tax Authority requires on the document. Supply all of them. What happens when you leave one empty depends on which GoRoute service you are sending through, and the difference matters to you as the taxpayer:

  • Where the refusal is switched on, a rendered document missing one of these values is refused by name โ€” on a B2B, B2G, export, import or self-billing document and on every credit or debit note โ€” and nothing is sent or reported.
  • Where it is not, GoRoute fills the gap with a value of its own and files it as if it were yours: the party's name as its street, NA as its city and telephone, 000 as its postal code, the credit note's own number and date as the invoice it corrects, and so on.
Not on every service โ€” check yours before you rely on the refusal

Whether the refusal is on is a setting each GoRoute service chooses. Some services have it on. Others have deliberately left it off pending a decision, and there a document missing one of these values is still rendered with the invented values above, and those values are still filed with the Tax Authority as yours.

Check the service you actually use. POST the invoice to POST /api/v1/invoices/validate, which never sends anything:

  • BUS_034 comes back for the missing value โ†’ the refusal is live for you.
  • It does not โ†’ GoRoute is still filling that value in and filing it as yours. Supply it yourself.

Supplying every value in the table is correct on every service, whichever way the refusal is set. It is the only approach that is.

RequiredFieldRule
The seller's street, city and postal code (PO Box)seller.address.street, .city, .postal_codeIBR-010-OM
The seller's telephoneseller.phone or seller.contact.phoneIBR-011-OM
The buyer's street, city and postal codebuyer.address.street, .city, .postal_codeIBR-019-OM
A party's country, unless it is Omani by its 0248 Peppol ID or OM VAT numberseller.address.country, buyer.address.country
The invoice a credit or debit note corrects: its number, issue date, UUID and a reason codepreceding_invoice.number, .issue_date, .uuid, .reason_codeIBR-032-OM, IBR-023-OM
A profit-margin invoice's preceding invoicepreceding_invoiceIBR-175-OM
The prepayment invoice a prepayment invoice settlesprepayment_invoice_number, prepayment_invoice_uuidIBR-058-OM
A summary or continuous supply's periodinvoice_period_start, invoice_period_endIBR-037-OM
Where an export or an e-commerce supply is delivereddelivery_country (and delivery_street, delivery_city, delivery_postal_code for e-commerce), or the buyer's own addressIBR-014-OM, IBR-040-OM
A special-zone supply's zones and licence numbersseller.country_subdivision_code, buyer.country_subdivision_code, seller.identifier, buyer.identifier (scheme SZLN)IBR-150/151/152-OM
A third-party invoice's agent, with its address and Omani VAT numberthird_partyIBR-015-OM
A zero-rated or exempt line's reason codelines[n].tax_exemption_reason_codeIBR-069-OM

For an invoice issued before e-invoicing began, give 00000000-0000-0000-0000-000000000000 as preceding_invoice.uuid: GoRoute does not assume it. The buyer's telephone is not required, so a buyer without one is sent without one rather than with NA.

On a service where the refusal is switched on, a missing value is reported like this:

  • POST /api/v1/invoices, /validate and /preview-xml answer with validation error BUS_034, one error per missing value, its field set as in the table.
  • A CSV or Excel import rejects the row with the same sentence.
  • An invoice pulled from Odoo or Zoho Books is parked, with the reason, until it is corrected in the ERP. Zoho Books sends GoRoute no company address or telephone, so for a Zoho connection they are your company settings in GoRoute (street, city, postal code, telephone): set them there.
  • An import that reaches you over Peppol waits for the missing values, named, like the customs data. A foreign supplier's invoice often gives no telephone, and need not give your street: send them with the customs data to PATCH /api/v1/oman/imports/{transaction_id} as seller.phone, seller.address and importer.address (see Completing an import that is waiting).

B2C is unchanged. A simplified invoice, or an invoice to a buyer with no VAT number and no Peppol ID, keeps the values the Tax Authority prescribed for the general customer, as before, the seller's own included. That covers a government buyer with no VAT number and no Peppol ID too: it is addressed as the general customer, so such a B2G invoice is not refused either. Only the invoice a B2C credit or debit note corrects, and a B2C profit-margin invoice's preceding invoice, are required. Receipts issued through the POS counters (fuel, exchange, retail) are unchanged too.