JSR Tax Advisors logoAPI
Developer APIsReference documentation

Invoice QR Code and Seller UUID


Marmin automatically generates a Seller UUID and QR code when you create invoice-family documents. Both follow the latest rules and regulations defined by Oman Tax Authority.

Overview

The following document types receive QR code and Seller UUID generation on create:

  • Sales invoices

  • Sales credit notes

  • Sales debit notes

  • Purchase invoices

  • Purchase credit notes

Two fields are returned in the API response:

FieldDescription
seller_uuidSeller identity UUID (UBL BTOM-004)
qr_code_base64Base64-encoded PNG image of the QR code

You may optionally supply seller_uuid in the create request. If provided, Marmin preserves your value and uses it in the QR TLV payload (tag 9 or 10). If omitted, Marmin derives the Seller UUID deterministically from document fields.

Note: seller_uuid (BTOM-004 / QR identity) is distinct from uuid (Peppol network integration identifier).

Generation pipeline

  1. Extract and format QR input fields from the document.

  2. Generate or preserve the Seller UUID.

  3. Build ordered TLV bytes and Base64-encode them — this string is the QR content.

  4. Render a 300×300 PNG QR image and Base64-encode it as qr_code_base64.

Required input fields

API fieldQR roleNotes
document_numberInvoice number (tag 3)Required
accounting_supplier_party.party_name or .nameSeller name (tag 4)party_name is preferred when both are present
accounting_supplier_party.party_tax_scheme.company_idSeller VATIN (tag 5)Required
issue_dateTag 6Format yyyy-MM-dd
issue_timeTag 7Format HH:mm:ss
tax_inclusive_amountTag 8 (standard only)3 decimal places
tax_amountTag 9 (standard only)3 decimal places
payable_amountTag 8 (profit margin only)3 decimal places

Missing required fields cause a validation error at document create time.

Standard vs profit margin invoice type

  • QR version is always 1.1 (TLV tag 1).

  • Invoice type (TLV tag 2): 01 for standard invoices, 02 for profit margin invoices.

  • Profit margin is detected when the transaction_type character at index 9 or 10 is 1 (positions 10–11 in the transaction type table).

When profit margin applies, the QR schema switches: tag 8 carries total amount due (payable_amount) instead of tax-inclusive total and VAT total, and the Seller UUID moves to tag 9.

Seller UUID generation rules

  • Algorithm: UUID v5 (RFC 4122), name-based, SHA-1

  • Namespace UUID: e0bc4ac8-b025-46e5-a76d-0c893fc3027e

  • Input string: Pipe-separated (|) field values, then uppercased

  • The Seller UUID itself is excluded from the input string

  • Deterministic: identical inputs always produce the same UUID

Standard invoice input (9 fields)
1.1|01|{invoiceNumber}|{sellerName}|{sellerVatin}|{issueDate}|{issueTime}|{taxInclusiveAmount}|{vatTotal}
Profit margin input (8 fields)
1.1|02|{invoiceNumber}|{sellerName}|{sellerVatin}|{issueDate}|{issueTime}|{payableAmount}
Golden example — standard invoice
InputExpected Seller UUID
Invoice INVOICE-01, seller بائع, VATIN OM1234567891, date 2026-05-13, time 18:31:00, total 302.340, VAT 14.520454cb7ea-f1f7-5b69-9e0b-756f002efa52
Golden example — profit margin invoice
InputExpected Seller UUID
Invoice INVOICE-01, seller بائع, VATIN OM1234567892, date 2026-05-13, time 18:30:00, due 1032.2109724a780-2360-502a-b6a2-201bf0f068c6
QR code TLV encoding rules

Each TLV field is encoded as:

[tag: 1 byte][length: 1 byte][value: UTF-8 bytes]

Additional constraints:

  • Maximum value length: 255 UTF-8 bytes per tag

  • Field order is fixed (see tables below)

  • TLV bytes are Base64-encoded; the resulting string is encoded into the QR image

  • Maximum TLV Base64 length: 700 characters

Standard invoice TLV tags (`01`)
TagFieldExample value
1QR Version1.1
2Invoice Type01
3Invoice NumberINVOICE-01
4Seller Nameبائع
5Seller VATINOM1234567891
6Issue Date2026-05-13
7Issue Time18:31:00
8Invoice Total with VAT302.340
9VAT Total14.520
10Seller UUIDUUID string
Profit margin TLV tags (`02`)

Tags 1–7 match the standard schema. Differences:

TagFieldExample value
8Total Amount Due1032.210
9Seller UUIDUUID string

There is no tag 10 and no separate VAT total tag in the profit margin schema.

Golden TLV Base64 examples

Standard invoice:

AQMxLjECAjAxAwpJTlZPSUNFLTAxBAjYqNin2KbYuQUMT00xMjM0NTY3ODkxBgoyMDI2LTA1LTEzBwgxODozMTowMAgHMzAyLjM0MAkGMTQuNTIwCiQ0NTRjYjdlYS1mMWY3LTViNjktOWUwYi03NTZmMDAyZWZhNTI=

Profit margin invoice:

AQMxLjECAjAyAwpJTlZPSUNFLTAxBAjYqNin2KbYuQUMT00xMjM0NTY3ODkyBgoyMDI2LTA1LTEzBwgxODozMDowMAgIMTAzMi4yMTAJJDk3MjRhNzgwLTIzNjAtNTAyYS1iNmEyLTIwMWJmMGYwNjhjNg==
Amount formatting

All monetary values in the TLV payload use 3 decimal places with half-up rounding (HALF_UP). Null amounts are formatted as 0.000.

API response and UBL mapping

API fieldUBL location
seller_uuidAccountingSupplierParty/AdditionalAccountID (BTOM-004)
qr_code_base64AdditionalDocumentReference with ID QR-CODE, embedded PNG attachment

Downloaded PDFs render the QR code from qr_code_base64.

Validation and compliance notes

When required QR input fields are missing, the API returns a validation error. Common field paths:

Missing fieldError path
Invoice numberdocument_number
Seller nameaccounting_supplier_party.party_name
Seller VATINaccounting_supplier_party.tin
Issue dateissue_date
Issue timeissue_time
Tax-inclusive total (standard)tax_inclusive_amount
VAT total (standard)tax_amount
Total amount due (profit margin)payable_amount

IBR-173-OM: When the buyer electronic address (IBT-049) is 997770000099, the Seller UUID (BTOM-004) must be present and match ^[A-Za-z0-9-]+$.

If the TLV Base64 string exceeds 700 characters, the API returns a validation error on qr_code.


  • Do supply a complete seller party (party_name, VATIN) and issue date/time before create.

  • Do set profit-margin flags in transaction_type when applicable so the correct QR schema is used.

  • Do treat qr_code_base64 as the PNG image for display, PDF, and UBL embedding.

Behaviours to avoid (Don'ts)

  • Don't confuse qr_code_base64 (PNG image Base64) with the TLV Base64 string encoded inside the QR code.

  • Don't manually set seller_uuid without reason — Marmin derives it deterministically from the same fields used in the QR payload.

  • Don't omit issue_time — it is required for QR generation even when optional elsewhere.

  • Don't mix up uuid (Peppol) and seller_uuid (BTOM-004) — they serve different purposes.