Appearance
Bill Examples
Complete payload examples for the cases that are hardest to get right. They build on the structures described in the Bill Data Model.
Line items with all fields
The following data object uses every field of data.lines that is relevant for selling goods: a text line as group header, a fully populated item with GTIN, serial number, category, line discount and delivery period, a weighed item with a PLU, an item with a custom quantity unit and a key/value line. The amounts are consistent: the lines add up to data.vatAmounts and data.fullAmountInclVat. Other parts of the receipt (head, data.paymentTypes, security, misc) are omitted.
json
{
"currency": "EUR",
"fullAmountInclVat": 466.42,
"vatAmounts": [
{ "percentage": 19.0, "inclVat": 463.97, "exclVat": 389.89, "vat": 74.08 },
{ "percentage": 7.0, "inclVat": 2.45, "exclVat": 2.29, "vat": 0.16 }
],
"lines": [
{
"text": "Küchengeräte",
"extension:anybill": {
"type": "text",
"sequenceNumber": 0
}
},
{
"text": "Kaffeevollautomat EQ.6",
"additionalText": "Inkl. 2 Jahre Herstellergarantie",
"vatAmounts": [
{ "percentage": 19.0, "inclVat": 449.0, "exclVat": 377.31, "vat": 71.69 }
],
"fullAmountInclVat": 449.0,
"deliveryPeriodStart": "2026-11-03T08:00:00+01:00",
"deliveryPeriodEnd": "2026-11-03T12:00:00+01:00",
"item": {
"number": "100234567",
"quantity": 1.0,
"quantityMeasure": "Count",
"pricePerUnit": 449.0,
"extension:anybill": {
"gtin": "4012345000016",
"serialNumber": "SN-EQ6-2026-004711",
"externalCategory": "Electronics > Kitchen Appliances > Coffee Machines > Fully Automatic",
"pricePerUnitBeforeDiscounts": 499.0
}
},
"extension:anybill": {
"type": "default",
"sequenceNumber": 1,
"fullAmountInclVatBeforeDiscounts": 499.0,
"discounts": [
{
"sequenceNumber": 0,
"discountId": "DISC_EQ6_50EUR",
"vatAmounts": [
{ "percentage": 19.0, "inclVat": 50.0, "exclVat": 42.02, "vat": 7.98 }
],
"fullAmountInclVat": -50.0
}
]
}
},
{
"text": "Bananen",
"additionalText": "Herkunft: Ecuador",
"vatAmounts": [
{ "percentage": 7.0, "inclVat": 2.45, "exclVat": 2.29, "vat": 0.16 }
],
"fullAmountInclVat": 2.45,
"item": {
"number": "200118",
"quantity": 1.25,
"quantityMeasure": "Kilogram",
"pricePerUnit": 1.96,
"extension:anybill": {
"gtin": "200118",
"plu": "4011",
"externalCategory": "Food > Fruit & Vegetables > Fruit > Bananas"
}
},
"extension:anybill": {
"type": "default",
"sequenceNumber": 2
}
},
{
"text": "Sportsocken",
"additionalText": "Größe 43–46, schwarz",
"vatAmounts": [
{ "percentage": 19.0, "inclVat": 14.97, "exclVat": 12.58, "vat": 2.39 }
],
"fullAmountInclVat": 14.97,
"item": {
"number": "300457",
"quantity": 3.0,
"pricePerUnit": 4.99,
"extension:anybill": {
"gtin": "4012345000023",
"customQuantityMeasure": "Paar",
"externalCategory": "Fashion > Sports > Socks"
}
},
"extension:anybill": {
"type": "default",
"sequenceNumber": 3
}
},
{
"key": "Treuepunkte",
"value": "+466",
"extension:anybill": {
"type": "keyValue",
"sequenceNumber": 4
}
}
],
"extension:anybill": {
"fullAmountInclVatBeforeDiscounts": 516.42,
"discounts": [
{
"id": "DISC_EQ6_50EUR",
"name": "50 € Sofortrabatt",
"value": 50.0,
"type": "Monetary",
"vatAmounts": [
{ "percentage": 19.0, "inclVat": 50.0, "exclVat": 42.02, "vat": 7.98 }
],
"fullAmountInclVat": -50.0
}
]
}
}Fields of a default line
The default line (extension:anybill.type = default or omitted) represents a sold item or service. Its amounts follow one rule: item.pricePerUnit × item.quantity = sum of vatAmounts[].inclVat = fullAmountInclVat.
| Field | Required | Description |
|---|---|---|
text | Yes | Name of the item as printed on the receipt. Max. 100 characters. |
additionalText | No | Additional information printed as a second line below text, e.g. warranty, origin, size or colour. Max. 1028 characters. |
vatAmounts[] | Expected | Gross (inclVat), net (exclVat) and tax (vat) amount of the line per tax rate (percentage, e.g. 19.0). Send it on every default line, including 0 % lines. Each percentage may occur only once per line. If the receipt uses tax groups, every entry also carries the groupId defined in data.vatAmounts (see Bill Data Model). |
fullAmountInclVat | Yes | Gross total of the line after line discounts, up to 5 decimal places. |
deliveryPeriodStart, deliveryPeriodEnd | No | Delivery or service period if it differs from the receipt date, e.g. a delivery slot or a rental period. If one is set, the other must be set too. Max. 64 characters each; ISO 8601 timestamps are recommended. |
item | Yes | Details of the sold item, see below. |
extension:anybill | Yes | anybill-specific line data, see below. |
item
| Field | Required | Description |
|---|---|---|
number | Yes | Article number of the item in the merchant's system. Max. 50 characters. |
quantity | Yes | Sold quantity in the unit given by quantityMeasure, up to 5 decimal places (e.g. 1.25 kg). |
quantityMeasure | Yes, unless customQuantityMeasure is set | Unit of quantity, e.g. Count for pieces or Kilogram for weighed goods. See Possible QuantityMeasure values. |
pricePerUnit | Yes | Gross price per unit after line discounts, up to 5 decimal places. |
item.extension:anybill
| Field | Required | Description |
|---|---|---|
gtin | No | GTIN/EAN of the item (GTIN-8, -12, -13 or -14). For goods without a GTIN, such as loose fruit and vegetables, a merchant-specific article number can be sent instead. 1 to 14 characters; longer values are silently dropped and the receipt is stored without a GTIN. |
plu | No | Price look-up code, e.g. 4011 for bananas. 4 to 5 characters. |
serialNumber | No | Serial number of the individual item, printed below the line. Max. 50 characters. |
externalCategory | No | Product category from the merchant's own hierarchy, levels separated by >, e.g. Food > Dairy > Cheese. |
customQuantityMeasure | No | Free-text unit for quantities that do not fit any quantityMeasure value, e.g. Paar. Replaces quantityMeasure. Max. 32 characters. |
pricePerUnitBeforeDiscounts | With line discounts | Original gross price per unit before line discounts. |
extension:anybill of the line
| Field | Required | Description |
|---|---|---|
type | No | Line type: default (or omitted), text, discount or keyValue. Not case-sensitive. |
sequenceNumber | Yes | Position of the line on the receipt. Lines are displayed in ascending order. Discount lines reference default lines by this number via relatedLines. |
fullAmountInclVatBeforeDiscounts | With line discounts | Gross total of the line before line discounts. |
discounts[] | No | Discounts applied to this line, each referencing a definition in data.extension:anybill.discounts via discountId. See Discount for individual line items. |
lineReturnReference | For returns | Reference to the original receipt when the line is a returned item. See Returning a line item. |
equivalentValue | No | Line amount in a second currency as free text, displayed next to the amount. Used together with data.equivalentValueName. |
Fields of the other line types
- Text line (
type:text):text(mandatory, max. 100 characters) and optionallyadditionalText. Use it as a group header or for notes between items. - Key/value line (
type:keyValue):keyandvalue(both mandatory, max. 20 characters each) are printed left and right on one line, e.g. loyalty points or a table number. - Discount line (
type:discount): a discount on the whole receipt, see Discount for the whole receipt.
Discounts
A discount can either be set to each line item individually or to the whole receipt.
Discount for individual line items
To discount a single line item, fill the discounts array in the extension:anybill of the line. Each applied discount references a definition (see below) via its discountId. If multiple discounts are applied to one line item, the sequenceNumber can be set to show the consumer how the final price is composed.
A discounted line uses the following amounts:
fullAmountInclVat– the gross line total after all discounts.extension:anybill.fullAmountInclVatBeforeDiscounts– the gross line total before any discount.item.extension:anybill.pricePerUnitBeforeDiscounts– the original gross price per unit before discounts.
Each discount vatAmounts.percentage must also be present in the line's vatAmounts.
Sign of fullAmountInclVat
Both positive and negative values are accepted for a discount's fullAmountInclVat – the sign only affects how the amount is rendered on the (PDF) receipt. We recommend using negative values for discount amounts.
Example (one line item with a 20 % discount):
json
{
"text": "Baumwoll T-Shirt",
"vatAmounts": [
{ "percentage": 19.0, "inclVat": 16.0, "exclVat": 13.45, "vat": 2.55 }
],
"fullAmountInclVat": 16.0,
"item": {
"quantity": 1.0,
"pricePerUnit": 16.0,
"extension:anybill": {
"pricePerUnitBeforeDiscounts": 20.0
}
},
"extension:anybill": {
"sequenceNumber": 0,
"fullAmountInclVatBeforeDiscounts": 20.0,
"discounts": [
{
"sequenceNumber": 0,
"discountId": "DISC_TSHIRT_20",
"vatAmounts": [
{ "percentage": 19.0, "inclVat": 4.0, "exclVat": 3.36, "vat": 0.64 }
],
"fullAmountInclVat": -4.0
}
]
}
}To describe an applied discount, add a definition to data.extension:anybill.discounts and reference it by setting the line discount's discountId to the definition's id (the id is an arbitrary reference string and is not shown to the customer). If the same discount applies to multiple line items, define it once and reference it from each line. The definition's type is one of Percentage, Monetary, MonetaryReplacement or None, and value holds the percentage (e.g. 20) or the monetary amount (e.g. 5). fullAmountInclVatBeforeDiscounts on the data extension is the gross total of the whole receipt before any discounts.
json
{
"extension:anybill": {
"fullAmountInclVatBeforeDiscounts": 40.0,
"discounts": [
{
"id": "DISC_TSHIRT_20",
"name": "20 % Rabatt T-Shirt",
"value": 20.0,
"type": "Percentage",
"vatAmounts": [
{ "percentage": 19.0, "inclVat": 4.0, "exclVat": 3.36, "vat": 0.64 }
],
"fullAmountInclVat": -4.0
},
{
"id": "DISC_CAP_5EUR",
"name": "5 € Rabatt Cap",
"value": 5.0,
"type": "Monetary",
"vatAmounts": [
{ "percentage": 19.0, "inclVat": 5.0, "exclVat": 4.2, "vat": 0.8 }
],
"fullAmountInclVat": -5.0
}
]
}
}Discount for the whole receipt
To add a discount that is applied to the whole receipt the discount line can be used. Multiple discount lines can be used for different discounts.
To enhance the information from which line items the discount is made up the relatedLines property can be used. Either use it on the vatAmounts to link the to the line item by the sequenceNumber or set all lines on the root.
Example:
json
{
"text": "Wochenendrabatt 3 %",
"additionalText": "3 % Rabatt am Wochenende",
"vatAmounts": [
{
"percentage": 7,
"inclVat": 0.09,
"exclVat": 0.08411,
"vat": 0.00589,
"relatedLines": [
0
]
},
{
"percentage": 19,
"inclVat": 0.08,
"exclVat": 0.06723,
"vat": 0.01277,
"relatedLines": [
2
]
}
],
"fullAmountInclVat": 0.17,
"relatedLines": null,
"extension:anybill": {
"sequenceNumber": 3,
"type": "discount"
},
...
}Returning a line item
If you want to return a bills line item the following steps are necessary:
- Given an existing receipt
Awith a line itemA1. - Create a new receipt
Bwith an extra line itemB1which represents the returned line itemA1. - Set the
lineReturnReferenceobject in the anybill extension of line itemB1:returnCodeReferencetakes the value ofmisc.extension:anybill.returnBarcodeof receiptA,originalReceiptIdReferenceoptionally takes the anybill receipt id (billId) of receiptA. - Save receipt
B.
A line item is then displayed as "returned" in receipt B.
The return barcode of receipt A is printed on the receipt so that the cashier can scan it when the customer returns the goods. It requires returnBarcodeType (Ean8, Ean13, Text, Qr, Barcode, Code128ABarcode, Code128BBarcode or Code128CBarcode).
Example
Bill A:
json
{
"storeId": "8192538C-CC23-488B-B35B-0F16BE1B8F43",
"bill": {
"head": {
"date": "2020-06-20T13:00:00+00:00",
...
},
"data": {
"lines": [
{
"text": "A1",
"item": { "quantity": 1, ... },
"fullAmountInclVat": 1.00,
...
},
{
"text": "A2",
"item": { "quantity": 3, ... },
...
}
]
},
"misc": {
"extension:anybill": {
"returnBarcode": "123",
"returnBarcodeType": "Text",
...
},
...
},
...
}
}Bill B:
json
{
"storeId": "8192538C-CC23-488B-B35B-0F16BE1B8F43",
"bill": {
"head": {
"date": "2020-06-20T15:00:00+00:00",
...
},
"data": {
"lines": [
{
"text": "B1",
"item": { "quantity": 1, ... },
"fullAmountInclVat": -1.00,
"extension:anybill": {
"sequenceNumber": 0,
"lineReturnReference": {
"returnCodeReference": "123", // see returnBarcode of Receipt A
"originalReceiptIdReference": "5e952ea6-167d-4001-95d9-a759204c2943" // optional: billId of Receipt A
}
},
...
}
]
},
...
}
}Deprecated return fields
The line extension properties returnBarcodeReference and isReturn are deprecated. returnBarcodeReference maps to lineReturnReference.returnCodeReference; isReturn is implied by the presence of lineReturnReference.
Custom sections
Custom sections allow you to insert your own attributes between the defined areas in order to individualize the receipt and display the necessary information.
A custom section can be inserted either before or after a defined area, contains a title and a list of data which are displayed in the given order by the sequenceNumber. The title will not be displayed on pdf. May be used in digital display formats.
The customSectionId can be used if it should be needed again later via the SDK. Must be unique across all customSections.
Areas
The receipt is generally divided into the following areas:
HeadLinesPaymentDetailsVatDetailsAdditionalDataBuyerFooterTextTseInformationAfterSalesCouponsHospitalityInformation
A receipt with the marked sections can be downloaded here.
Types
Currently, data of type text, keyValue, barcode, qrCode or divider can be added to a custom section. type is mandatory for every entry; text, key/value and value are limited to 1024 (text) respectively 128 characters.
text
json
{
"sequenceNumber": 0,
"customSectionId": "NameId",
"type": "text",
"text": "text message",
"alignment": "Left|Center|Right"
}keyValue
json
{
"sequenceNumber": 1,
"customSectionId": "NameId",
"type": "keyValue",
"key": "LoyaltyCard number:",
"value": "123456789"
}barcode
json
{
"sequenceNumber": 0,
"customSectionId": "NameId",
"type": "barcode",
"barcodeType": "Barcode|Code128ABarcode|Code128BBarcode|Code128CBarcode",
"value": "Value of the barcode"
}qrCode
json
{
"sequenceNumber": 0,
"customSectionId": "NameId",
"type": "qrCode",
"value": "Value of the qrCode"
}divider
A horizontal separator line without further properties.
json
{
"sequenceNumber": 2,
"customSectionId": "NameId",
"type": "divider"
}Custom section example
json
"customSections": [
{
"position": "Before",
"section": "Head",
"title": "Title of the custom head section",
"data": [
{
"sequenceNumber": 0,
"type": "Text",
"text": "Before Head text"
},
{
"sequenceNumber": 1,
"type": "KeyValue",
"key": "LoyaltyCard number:",
"value": "123456789"
}
]
},
{
"position": "After",
"section": "VatDetails",
"title": "Title of the custom VAT details section",
"data": [
{
"sequenceNumber": 0,
"type": "barcode",
"barcodeType": "Code128ABarcode",
"value": "Value of the barcode"
},
{
"sequenceNumber": 1,
"type": "qrCode",
"value": "Value of the qrCode"
}
]
}
]