Receipt creation begins with a definitive merchant-supplied ReceiptPayload. This plaintext object exists only in merchant-controlled memory. The SDK serializes and encrypts it separately for each owner device returned by recipient resolution; Cheqi never receives it in plaintext.
The current Java and JavaScript SDKs expose this object as ReceiptPayload. In the digital flow it is an input to local encryption and on-device generation; it is not sent to a plaintext template endpoint.
The issuer supplies these values:
| Field | Meaning |
|---|---|
documentNumber | Issuer-assigned receipt number |
issueDate | Date and time the issuer created the receipt |
currency | ISO 4217 currency code |
receiptSubtotal | Issuer-calculated subtotal |
totalBeforeTax | Issuer-calculated total excluding tax |
totalTaxAmount | Issuer-calculated tax total |
totalAmount | Issuer-calculated final amount |
taxesApplied | Whether taxes apply to this receipt |
products | Receipt line items |
The SDK and mobile generator do not calculate fiscal totals, tax, signatures, sequences, or QR values for the issuer. Supply the legally definitive values from the POS or commerce system.
Common optional fields include:
identifiersfor issuer and transaction referencesdiscountsandchargestaxesfor the receipt-level tax breakdowntransactionDateandpurchaseDateperiodfor billing or service periodsbarcodespaymentDetailsjurisdictionalDatafor country-specific fiscal and legal information
The free receipt message is configured on the company in the Cheqi app. It is not supplied in each ReceiptPayload. The local engine uses that configured message for CHEQI note and UBL cbc:Note.
paymentDetails is the definitive issuer-supplied payment object. It remains inside the encrypted receipt payload. The owner device passes it unchanged to the local generator; server-known matching data does not replace or merge into it.
Use jurisdictionalData when your POS, fiscal device, or invoicing system has country-specific data that must remain attached to the receipt. This includes external regime identifiers, exact legal wording, fiscalization evidence, authority references, and namespaced extension fields.
Cheqi preserves supplied country data but does not decide which local regime applies to a transaction or manufacture authority data. See Country Support for the supported country set and Supplying Jurisdiction Data for the request shape.
The exact schema is available as ReceiptPayload in the API reference. A minimal illustrative payload looks like this:
{
"documentNumber": "INV-2026-001",
"issueDate": "2026-08-02T14:35:02Z",
"currency": "EUR",
"receiptSubtotal": 10.00,
"totalBeforeTax": 10.00,
"totalTaxAmount": 2.10,
"totalAmount": 12.10,
"taxesApplied": true,
"products": [
{
"name": "Coffee",
"identifier": "SKU-COFFEE-001",
"quantity": 2,
"unitCode": "C62",
"unitPrice": 5.00,
"subtotal": 10.00,
"total": 12.10,
"taxes": [
{
"rate": 21.0,
"type": "VAT",
"taxableAmount": 10.00,
"amount": 2.10
}
]
}
],
"taxes": [
{
"rate": 21.0,
"type": "VAT",
"taxableAmount": 10.00,
"amount": 2.10,
"label": "VAT 21%"
}
],
"paymentDetails": {
"paymentMeansCode": "48",
"description": "Card",
"cardProvider": "VISA",
"cardLastFour": "4242"
}
}This example is plaintext for explanation only. Do not send this JSON directly to /receipt/encrypted.
For every temporary owner-device recipient returned by POST /recipient/resolve:
- serialize the same definitive
ReceiptPayload - generate a fresh AES-256 content key
- encrypt the serialized payload with AES-GCM
- wrap that content key with the recipient's public key
- submit the recipient ID, ciphertext, and wrapped key as one
deviceDeliveriesentry
Do not reuse a symmetric key across devices. Submit exactly one entry for every device returned by the match and no additional recipients.
Every product line requires an identifier: the SKU, article number, or other issuer-controlled key for that line. Make it unique within the receipt.
That identifier is also the durable key used in return flows. When a customer returns an item, it comes back as the lineItemId, allowing the issuer to map the return to the original line. See Receiving Return Requests.
After decryption, the owner device combines the merchant payload with the current supplier, customer, optional store, and routing context that Cheqi already knows. The shared Rust engine then generates and hashes the local CHEQI receipt.
The one device holding the downstream distribution lease also generates the UBL formats required by the resolved recipients. Those final documents are bundled and encrypted on the device. The backend receives ciphertext and hashes, not the plaintext CHEQI JSON or UBL XML.
Continue with Sending Receipts for the submission contract.