Skip to content

When a downstream recipient accepts UBL_PURCHASE_RECEIPT, the elected owner device generates a serialized UBL 2.4 XML document. When a recipient accepts UBL_INVOICE, that device can generate UBL Invoice XML instead or in addition.

The device includes only the accepted formats in that recipient's encrypted document bundle. Cheqi routes the ciphertext and final hashes; it does not receive the plaintext XML.

The ubl field is a string — parse it as XML to access the full receipt structure.

PurchaseReceipt schema

The XML conforms to the following schema:

definitionId: PurchaseReceipt

Key elements

ElementNullableDescription
idNoUnique receipt identifier
issueDateNoDate of issue (YYYY-MM-DD)
issueTimeYesTime of issue (HH:MM:SS)
transactionDateYesTransaction or tax-point date supplied by the issuer
transactionTimeYesTransaction or tax-point time
purchaseDateYesPurchase or delivery date supplied by the issuer
purchaseTimeYesPurchase or delivery time
documentCurrencyCodeNoISO 4217 currency code (e.g. EUR)
noteYesCompany-configured free receipt message
accountingSupplierPartyNoSeller/merchant party details
accountingCustomerPartyYesBuyer party details (B2B)
paymentYesCompleted payment metadata, including optional MID/TID
paymentMeansNoPayment method information
taxTotalsNoTax breakdown per rate
legalMonetaryTotalNoTotal amounts (tax-exclusive, tax-inclusive, payable)
purchaseReceiptLinesNoLine items with product, quantity, price, and tax details
verificationNonceNoNonce used for receipt verification

XML namespace

The root element uses the UBL 2.4 namespace:

urn:oasis:names:specification:ubl:schema:xsd:PurchaseReceipt-2

When jurisdictional legal text is present, the root also declares the standard UBL extension namespace and Cheqi's extension namespace:

xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:cheqi="urn:cheqi:ubl:extension:components:1"

Example

<?xml version="1.0" encoding="UTF-8"?>
<PurchaseReceipt
    xmlns="urn:oasis:names:specification:ubl:schema:xsd:PurchaseReceipt-2"
    xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
    xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
  <cbc:ID>INV-2026-001</cbc:ID>
  <cbc:IssueDate>2026-03-20</cbc:IssueDate>
  <cbc:Note>Thank you for shopping with us.</cbc:Note>
  <cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
  <cac:AccountingSupplierParty>
    <!-- Party details -->
  </cac:AccountingSupplierParty>
  <cac:Payment>
    <cbc:MerchantID>MID-123456</cbc:MerchantID>
    <cbc:PaymentTerminalID>TID-987654</cbc:PaymentTerminalID>
  </cac:Payment>
  <cac:PaymentMeans>
    <cbc:PaymentMeansCode listID="UN/ECE 4461">48</cbc:PaymentMeansCode>
    <cac:CardAccount>
      <cbc:PrimaryAccountNumberID>4242</cbc:PrimaryAccountNumberID>
      <cbc:NetworkID>VISA</cbc:NetworkID>
    </cac:CardAccount>
  </cac:PaymentMeans>
  <cac:LegalMonetaryTotal>
    <cbc:TaxExclusiveAmount currencyID="EUR">10.00</cbc:TaxExclusiveAmount>
    <cbc:TaxInclusiveAmount currencyID="EUR">12.10</cbc:TaxInclusiveAmount>
    <cbc:PayableAmount currencyID="EUR">12.10</cbc:PayableAmount>
  </cac:LegalMonetaryTotal>
  <cac:PurchaseReceiptLine>
    <cbc:ID>1</cbc:ID>
    <cac:Item>
      <cbc:Name>Coffee</cbc:Name>
    </cac:Item>
    <cac:Price>
      <cbc:PriceAmount currencyID="EUR">5.00</cbc:PriceAmount>
    </cac:Price>
  </cac:PurchaseReceiptLine>
</PurchaseReceipt>

Free receipt message and jurisdictional text

The company configures its free receipt message in the Cheqi app. The local engine places that text in CHEQI note and UBL cbc:Note. A merchant does not send it in each ReceiptPayload.

Jurisdictional wording has a different purpose and never uses cbc:Note. Values supplied through jurisdictionalData.legalTexts[] are preserved in CHEQI JSON and written to a structured extension in UBL PurchaseReceipt, Invoice, and CreditNote:

<ext:UBLExtensions>
  <ext:UBLExtension>
    <ext:ExtensionAgencyID>CHEQI</ext:ExtensionAgencyID>
    <ext:ExtensionVersionID>1</ext:ExtensionVersionID>
    <ext:ExtensionURI>urn:cheqi:ubl:extension:jurisdictional-legal-text:1</ext:ExtensionURI>
    <ext:ExtensionContent>
      <cheqi:JurisdictionalLegalTexts>
        <cheqi:LegalText
            code="BE:GKS_DOCUMENT_HEADING"
            displayRole="DOCUMENT_HEADING"
            languageCode="nl-BE">BTW-KASTICKET</cheqi:LegalText>
      </cheqi:JurisdictionalLegalTexts>
    </ext:ExtensionContent>
  </ext:UBLExtension>
</ext:UBLExtensions>

The extension URI and element shape are identical in UBL Invoice. A receiving application can use displayRole to render a heading, notice, or footer without interpreting general-purpose note text.

Merchant and payment terminal identifiers

For a card payment, recipient resolution can supply two optional payment metadata fields. They appear in the locally generated CHEQI JSON as:

{
  "paymentMeans": {
    "paymentMeansCode": "48",
    "cardProvider": "VISA",
    "cardLastFour": "4242",
    "merchantId": "MID-123456",
    "paymentTerminalId": "TID-987654"
  }
}

The Rust engine maps those fields natively in UBL 2.4 PurchaseReceipt:

CHEQI JSONPurchaseReceipt
paymentMeans.merchantIdcac:Payment/cbc:MerchantID
paymentMeans.paymentTerminalIdcac:Payment/cbc:PaymentTerminalID

Both values are optional. They are receipt metadata only and are never used to match a customer. paymentTerminalId is the card-payment terminal identifier; it is not a fiscal cash-register, fiscal-device, or jurisdictional terminal identifier.

Cheqi currently applies this native mapping to UBL PurchaseReceipt only. Do not assume that the same elements are present in UBL Invoice.