{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"da4f2ccc-6586-4ab2-a244-d2ad47a0702a","name":"Zonal Standard Loyalty - Documentation 🟢","description":"This document defines the Zonal standard loyalty interface supported by the POS Integration Engine. It forms part of the suite of Zonal Standard APIs.\n\nThird parties should implement this API to allow the Zonal POS system to integrate with their loyalty system.\n\n## Versioning\n\nThe POSint engine is a installed at site level this means that there could be the case that mutiple versions of the POSint could be installed in an estate.\n\nThis documentation relates to version 1.58 of the Zonal POS integration Engine.\n\n_Details of version 1.58 have been added as pre-release versions._\n\n| **Version** | **Change** | **Released** |\n| --- | --- | --- |\n| 1.55 | Initial version | 11 Sept 2024 |\n| 1.56 | Additional of Site ID, Site Ref and sale area to Ticket data. | 30 Sept 2024 |\n| 1.57 | No interface changes | 3 April 2025 |\n| 1.58 | Site Ref data included in post tickets, Auto apply rewards, Send promotions, Ablity to add open discounts to account, Ablity to send account when loyalty is not assigned.  <br>Ablity to send card payment token data | End of May 2025 |\n\n# Onboarding\n\nThe onboarding process, at a high level, generally follows the below steps. This process applies irrespective of whether you have a new integration or are looking to enhance an existing integration.\n\n1. **Planning**  \n    During this phase, the introduction to the integration is made either by you completing an enquiry form on the website or a client expressing interest via the Account Manager. Initial discussions are with the Partnerships team.\n    \n2. **Development**  \n    During this next phase, API credentials and documentation will be released. Access to a Zonal sandbox environment will be provided. You will also be given contact information of the team who you can consult with during development.\n    \n3. **Accreditation**  \n    Once you have finished your development and believe you have a production ready application, contact the Integrations team: [integrations@zonal.co.uk](https://mailto:integrations@zonal.co.uk)  \n    The demo will then be booked in. During the demo, your integration will be assessed to ensure you are using the Zonal API’s responsibly, and that it is clear the use cases that your integration does/does not support.\n    \n4. **Client Onboarding**  \n    Documentation of the integration is produced and production credentials can then be issued.\n    \n\n**Re-accreditation**  \nFrom time to time, you may wish to include new features in the API to your solution. When adding a new feature, you need use the Integration Sandbox for your deployment testing and not production. Once you have completed your development you may need to be re-accredited\n\n# Sandbox Access\n\nAfter a Statement of work has been signed, the integration team will setup access to the Zonal Integration Sandbox.\n\nWe are not able to supply integrators with their own hardware or test environment. There are many components & specific networking requirements in setting up an estate and it is a sizeable project just to deploy an Aztec Estate. The dataset in the environment would be undocumented and we would be unable to offer any support on issues. In the past integrators have had their own environments but they have all been abandoned by the integrator in favour of the Zonal Sandbox.\n\nWe are happy to support your development with the use of Zonal Integrator Sandbox estate, please contact us at [integrations@zonal.co.uk](https://mailto:integrations@zonal.co.uk) and we can either\n\n**It is not possible to gain early or ready only access to a clients production environment before accreditation has been completed.**\n\n## Documentation Context\n\nThis documenation is written from the context of the POS calling out to a third party platform. When the phrase \"Request\" is used this is the data sent from the POS out.\n\n\"Response\" is used when the third party replies to a request.\n\n# POS Operations\n\nThe POS system supports the below types operations:\n\n**Assign Loyalty Account**  \nTo allow a customer to assign their loyalty account to the POS account. This will be done by scanning a barcode/QR code, swiping a loyalty card or typing in some form of customer id. Rewards can be returned as part of the assignment process if required.\n\nOnly one Loyalty account can be assigned to one POS Account. It is possable to split a POS account in to two or more accounts, then a loyalty account can be assigned to each.\n\n<img src=\"https://content.pstmn.io/b6a91551-9f5a-477c-8c49-3b33f4d9537d/aW1hZ2UucG5n\" alt=\"Assign%20Loyalty%20Screen%20on%20POS\" width=\"535\" height=\"471\">\n\n**Lite Registration**  \nTo allow the POS operator to issue a loyalty id to a customer and record an e-mail address or mobile phone number against it, to allow a follow-up to obtain more customer details. Rewards can be returned as part of the registration process if required.\n\n**Request Earning Code Print Data**  \nTo generate an earning code, and corresponding text, to print on the customer’s receipt. The customer will be able to enter this code on an app or website supplied by the loyalty provider. This will allow them to get any points/rewards they should be due from their purchase, applied to their loyalty account. The code can be a bar code, QR code or just a text string depending on the site’s capabilities.\n\n**Upload Loyalty Ticket Details**  \nAllows the POS to upload all the details of the current pos account (and corresponding loyalty id) to the loyalty server for processing in order to credit the loyalty account with any earned rewards.\n\n**Balance Check**  \nAllows the POS to display to the end user, any rewards that have been added to the specified loyalty account.\n\n<img src=\"https://content.pstmn.io/6e9c0153-4621-4c78-8306-d04c085becd7/aW1hZ2UucG5n\" alt=\"Balance%20Check%20screen%20on%20POS\" width=\"459\" height=\"367\">\n\n**Redeem Reward**  \nUsed to redeem prizes on the POS either by selecting them from a list of all available rewards, or, if supported, by using the loyalty account to pay for some or all of the current pos account.\n\n<img src=\"https://content.pstmn.io/8087cece-d963-441f-ae8c-dd6d9917833d/aW1hZ2UucG5n\" alt=\"Redemption%20Screen%20on%20the%20POS\" width=\"470\" height=\"414\">\n\n<img src=\"https://content.pstmn.io/70a7dbf6-7084-4508-956c-14aebc5fc29b/aW1hZ2UucG5n\" alt=\"Currency%20Balance%20Redemption\" width=\"440\" height=\"374\">\n\n**Update Redemption**  \nUsed to increase the balance amount used in an initial redemption. The POS system will only use this call to add a tip amount to a loyalty payment.\n\n**Reverse Redemption**  \nUsed to reverse a previous redemption (including all of its updates).\n\n<img src=\"https://content.pstmn.io/81ccc691-f5f6-4ffa-b082-34271e32adbe/aW1hZ2UucG5n\" alt=\"Reversal%20Screen%20on%20the%20POS\" width=\"466\" height=\"405\">\n\n# Rewards\n\nLoyalty rewards, apart from loyalty payments, can optionally be given a points cost. If there is no cost then they can be redeemed at any time. If there is a cost, then the loyalty account must have enough points accrued to cover the cost and the points balance will be reduced in order to redeem the reward.\n\n| Reward Types | Description |\n| --- | --- |\n| AccountAmountDiscount | A discount which gives an amount reduction in the sale price of the entire account e.g., £5.00 off. For this type of discount, the loyalty system passes the amount to use to the PoS system. It doesn’t need to pass a discount id as this is defined within the Zonal system (In Aztec this is within the SiteSettings -> CLM tab in BaseData). |\n| ProductPercentageDiscount | A percentage reduction in the sale of a product line of the type specified by the product id field e.g., 50% off a can of Coca-Cola.  <br>Note – this only applies to a single product i.e., a second can of Coca-Cola on the account would be charged at full price unless a second discount reward is redeemed. |\n| ProductAmountDiscount | An amount reduction in the sale of a product line of the type specified by the product id field e.g., £1.00 off a can of Coca-Cola.  <br>Again, this only applies to a single product. |\n| FixedDiscount | A discount where the third-party system just provides the Zonal discount identifier. The amount/percentages are defined within the Zonal system. This type of discount will follow all of the Zonal rules e.g., limiting it to certain product types etc. |\n| CurrencyBalanceDiscount | Loyalty This is a special type of discount which can only be used with loyalty accounts which have a currency balance. The POS system converts the requested currency amount into a discount of the same amount. This is essentially the same as a loyalty payment except that it follows all the discount rules.  <br>The discount id is not passed for this type as this is defined within the Zonal system (In Aztec this is within the SiteSettings -> CLM tab in BaseData). |\n| Product | A product reward whereby the third-party system just provides a Zonal product identifier. |\n| Payment | A payment reward whereby the third-party system just provides a payment method identifier. This must be a Zonal fixed amount payment method identifier. |\n| Promotion | A promotion reward whereby the third-party system just provides a promotion identifier.  <br>Loyalty Payments Loyalty A reward type where the PoS system generates a payment by using some of the currency balance accrued on the loyalty account |\n\n### Rewards Example\n\n**£2.50 Off**\n\n``` json\n{\n    \"pointsCost\": null\n    \"rewardId\": \"74a57795-1abe-44f6-9d9a-345359f0a964\",\n    \"name\": \"£2.50 off\",\n    \"rewardType\": \"FixedDiscount\",\n    \"percentage\": null,\n    \"amount\": null,\n    \"productId\": null,\n    \"discountId\": \"13\",\n    \"promotionId\": null,\n    \"quantity\": 1\n}\n\n ```\n\n**£5 off**\n\n``` json\n{\n    \"pointsCost\": null\n    \"rewardId\": \"74a57795-1abe-44f6-9d9a-345359f0a965\",\n    \"name\": \"£5 off\",\n    \"rewardType\": \"FixedDiscount\",\n    \"percentage\": null,\n    \"amount\": null,\n    \"productId\": null,\n    \"discountId\": \"16\",\n    \"promotionId\": null,\n    \"quantity\": 1\n}\n\n ```\n\n**20% off Food**\n\n``` json\n{\n    \"pointsCost\": null\n    \"rewardId\": \"74a57795-1abe-44f6-9d9a-345359f0a967\",\n    \"name\": \" 20% off Food\",\n    \"rewardType\": \"FixedDiscount\",\n    \"percentage\": null,\n    \"amount\": null,\n    \"productId\": null,\n    \"discountId\": \"23\",\n    \"promotionId\": null,\n    \"quantity\": 1\n}\n\n ```\n\n**5% off Bill**\n\n``` json\n{\n    \"pointsCost\": null\n    \"rewardId\": \"74a57795-1abe-44f6-9d9a-345359f0a966\",\n    \"name\": \"5% off Bill\",\n    \"rewardType\": \"FixedDiscount\",\n    \"percentage\": null,\n    \"amount\": null,\n    \"productId\": null,\n    \"discountId\": \"25\",\n    \"promotionId\": null,\n    \"quantity\": 1\n}\n\n ```\n\n**25% off Drinks**\n\n``` json\n{\n    \"pointsCost\": null\n    \"rewardId\": \"74a57795-1abe-44f6-9d9a-345359f0a969\",\n    \"name\": \"25% off Drinks\",\n    \"rewardType\": \"FixedDiscount\",\n    \"percentage\": null,\n    \"amount\": null,\n    \"productId\": null,\n    \"discountId\": \"40\",\n    \"promotionId\": null,\n    \"quantity\": 1\n}\n\n ```\n\n**Peroni For Free**\n\n``` json\n{\n\"pointsCost\": null,\n\"rewardId\": \"74a57795-1abe-44f6-9d9a-345359f0a961\",\n\"name\": \"Free Peroni\",\n\"rewardType\": \"Product\",\n\"percentage\": 100,\n\"amount\": null,\n\"productId\": \"10000000131\",\n\"discountId\": null,\n\"promotionId\": null,\n\"quantity\": 1\n}\n\n ```\n\n**Budweiser For £1**\n\n``` json\n{\n    \"pointsCost\": null,\n    \"rewardId\": \"74a57795-1abe-44f6-9d9a-345359f0a962\",\n    \"name\": \"£1 Budweiser\",\n    \"rewardType\": \"Product\",\n    \"percentage\": null,\n    \"amount\": 1,\n    \"productId\": \"10000000131\",\n    \"discountId\": null,\n    \"promotionId\": null,\n    \"quantity\": 1\n}\n\n ```\n\n**50% off Risotto**\n\n``` json\n{\n    \"pointsCost\": null,\n    \"rewardId\": \"74a57795-1abe-44f6-9d9a-345359f0a987\",\n    \"name\": \"50% off Risotto\",\n    \"rewardType\": \"ProductPercentageDiscount\",\n    \"percentage\": 50,\n    \"amount\": null,\n    \"productId\": \"10000000236\",\n    \"discountId\": null,\n    \"promotionId\": null,\n    \"quantity\": null\n}\n\n ```\n\n**£5 off the Bill**\n\n``` json\n{\n    \"pointsCost\": null,\n    \"rewardId\": \"74a57795-1abe-44f6-9d9a-345359f0a912\",\n    \"name\": \"£5.00 off\",\n    \"rewardType\": \"AccountAmountDiscount\",\n    \"percentage\": null,\n    \"amount\": 5,\n    \"productId\": null,\n    \"discountId\": null,\n    \"promotionId\": null,\n    \"quantity\": null\n}\n\n ```\n\n### Loyalty Payments vs Currency Balance Discounts\n\nThese are very similar from the point of view of the loyalty system.  \nA CurrencyBalanceDiscount reward, if available, will be returned in the rewards list from balance check and presented as a reward button during a loyalty reward redemption. The user will then choose how much of their available balance to redeem and this will be debited from their loyalty account and applied to the POS account as a discount.  \nPaying by loyalty will be started via a payment button on the POS and follow the standard payment flow, including adding tips if supported. Again, the user will then choose how much of their available balance to pay with and this will be debited from their loyalty account and applied to the POS account as a payment.  \nBoth will result in exactly the same /redeem call to the API with a currency balance debit entry.\n\n## Auto Redeem rewards\n\nIn v1.58 of the POSint engine you are able to return rewards on the \"AssignLoyalty\" call, these will be automatically applied to the POS account. This enabled features like members pricing or a fixed discount to be applied automtically without further interaction for the POS user.\n\n| Field | **Data Type** | **Optional / Required** | **Description** |\n| --- | --- | --- | --- |\n| rewardId | GUID | Required | 8-4-4-4-12 format |\n| groupingRedemptionId | GUID | Conditional | The unique id for the current set of reward  <br>redemptions – this can just be the requestId or it can be a unique id  <br>generated by the loyalty system. This is only really needed to group all auto update (members pricing) style rewards together or to group all rewards that came from a single voucher redemption.  <br>For voucher redemptions this should be the same as the outer redemptionId.  <br>8-4-4-4-12 format |\n| rewardType | String | Required |  |\n| name | String | Required |  |\n| percentage | Decimal | Conditional |  |\n| amount | Decimal | Conditional |  |\n| quantity | Decimal | Conditional |  |\n| productId | Interger | Conditional |  |\n| promotionId | Interger | Conditional |  |\n| paymentId | Interger | Conditional |  |\n| discountId | String | Conditional |  |\n| pointsCost | Interger | Conditional |  |\n| validOnTicket | Interger |  |  |\n| ticketItemId | String | Conditional | This |\n\n**Fixed Value Auto Assigned reward**\n\n``` json\n{\n            \"rewardId\": \"6d5dc8a4-fe86-4bdb-a7b3-cb9dcedc08d4\",\n            \"groupingRedemptionId\": null,\n            \"rewardType\": \"AccountAmountDiscount\",\n            \"name\": \"Â£2.00 off\",\n            \"percentage\": null,\n            \"amount\": 2.0,\n            \"quantity\": null,\n            \"productId\": \"*\",\n            \"promotionId\": null,\n            \"paymentId\": null,\n            \"discountId\": \"null\",\n            \"pointsCost\": null,\n            \"validOnTicket\": null,\n            \"ticketItemId\": null\n        }\n\n ```\n\n**Members Pricing (deduct 33p from product)**\n\n``` json\n{\n            \"rewardId\": null,\n            \"groupingRedemptionId\": \"6bacefef-25e7-4fc8-8935-8c7a6229e00b\",\n            \"rewardType\": \"ProductAmountDiscount\",\n            \"name\": \"Members Price\",\n            \"percentage\": null,\n            \"amount\": 0.33,\n            \"quantity\": null,\n            \"productId\": null,\n            \"promotionId\": null,\n            \"paymentId\": null,\n            \"discountId\": \"47\",\n            \"pointsCost\": null,\n            \"validOnTicket\": null,\n            \"ticketItemId\": \"615726511578652\"\n        }\n\n ```\n\n## Aztec Configuration\n\nThe Aztec configuration is defined at site level in the Base data module.\n\n| **Field** | **Format** | **Description** |\n| --- | --- | --- |\n| Loyalty Auth Token URL | Alpha/Numeric/Special Characters | URL used during the token authentication. Not required for basic Auth |\n| Loyalty Client ID | Alpha/Numeric/Special Characters | The site username for token authentication or basic auth |\n| Loyalty Client Secret | Alpha/Numeric/Special Characters | The site password for token authentication or basic auth |\n| Loyalty Base URL | Alpha/Numeric/Special Characters | URL used for all calls, exluding the token authentication |\n| Enable Loyalty Earning Codes | Checkbox | Enabled the \"Request Earning Code\" call, which requests a code from the external loyalty platform, this code is then printed on the receipt and allows a guest to link up the account at a later date. |\n| Enable Loyalty Ticket Upload. | Checkbox | Enabled the uploading of tickets when a loyalty account is assigned to the POS account. |\n| Loyalty Background processing frequency (secs) | Integer | The frequency in seconds between Ticket uploads. Defaults to 5min if not value is entered. |\n| Loyalty Reversal Retry (days) | Integer | The number of days failed reversals will continue to retry before moving the ticket into an error log. |\n| Loyalty Ticket Retry (days) | Integer | The number of days failed tickets will continue to retry before moving the ticket into an error log. |\n| Upload Tickets with no Loyalty Id | Checkbox | Enabled the uploading of tickets for all POS account. |\n| Enable Loyalty Unassign | Checkbox | If enabled, when a Loyalty Id is removed (unassigned) from an POS account a call will be made to the Integrator to notify them. |\n\n## Print Data\n\nPrint data allows you to send information to the printer so that a print out of balances or possable future rewards can be printed.\n\nThe data is sent as a single string with control codes embedded in it. The control codes are in a universal format that the POS system will translate in to the format required by the specific printer the POS is configured to send the print out to.  \nAll control codes start with the ‘#’ character followed by descriptor defining the control code and ending with another ‘#’. If you actually want to print a ‘#’ character on the receipt then you should send ‘#ESCAPEESCAPECODE#’.\n\n| **Print Code** | Control Command |\n| --- | --- |\n| #PAPERCUT# | Paper cut if supported. |\n| #DOUBLEWIDTH# | Begin double width printing if supported. |\n| #NEWLINE# | New line |\n| #BOLD# | Begin bold printing |\n| #NORMAL# | Return printer to default mode |\n| #LINE# | Print a horizontal line |\n| #RESETPRINTER# | Reset text mode to default (used to turn off bold/double width/bar code etc.) |\n| #ALTERNATIVECOLOUR# | Begin printing on alternate colour if supported. |\n| #DOUBLEHEIGHT# | Begin double height printing if supported. |\n| #PERFORATION# | Perforation if supported. |\n| #POUNDSYMBOL# | Print UK pound symbol (£) |\n| #BARCODEUPCA# | Begin UPCA barcode printing |\n| #BARCODEEAN13# | Begin EAN13 barcode printing. The data to print should be sent as 12 characters as the printer will automatically generate the 13th (check) digit. |\n| #EUROSYMBOL# | Print euro symbol |\n| #QRCODE# | Begin QR Code printing |\n| #ESCAPEESCAPECODE# | Print # symbol |\n\nExample:\n\n`\"printData\": \"#BOLD# Balance #NEWLINE##NEWLINE# Currency: #POUNDSYMBOL#2.67#NEWLINE#Points:5893#NEWLINE# #NEWLINE# #BOLD# Earned Rewards #NORMAL# #NEWLINE# 50% off CheeseBurger #NEWLINE# Guinness #NEWLINE# John Smiths #NEWLINE# Tetleys #NEWLINE# Directors #NEWLINE# #RUNOUT#\"`\n\n---\n\n**Balance Statement**\n\nCurrency:£2.67  \nPoints:5893\n\n**Earned Rewards**  \n50% off CheeseBurger  \nGuinness  \nJohn Smiths  \nTetleys  \nDirectors\n\n---\n\n# Example Flows\n\n**POS user** - The Point of Sale user\n\n**POS** - The Point of Sale\n\n**POS Int** - Software that runs on the back off PC, that connects out to the third party\n\n**3rd Party loyalty provider** - The loyalty provider\n\n**Account Assignment**\n\n<img src=\"https://content.pstmn.io/ce331594-c2e9-447b-a8ab-46e2d8527f47/aW1hZ2UucG5n\" width=\"702\" height=\"345\">\n\n---\n\n**Upload Ticket**\n\n<img src=\"https://content.pstmn.io/3f20210f-f1fe-42f6-bd3c-cb0307f6b541/aW1hZ2UucG5n\" width=\"594\" height=\"472\">\n\n---\n\n**Balance Check**\n\n<img src=\"https://content.pstmn.io/d205fb61-2834-4792-9a3d-708346c6514e/aW1hZ2UucG5n\" width=\"644\" height=\"333\">\n\n---\n\n**Redeem from Loyaty**\n\n<img src=\"https://content.pstmn.io/4bc02649-c9c7-4b86-b87d-282ecc23358e/aW1hZ2UucG5n\" width=\"649\" height=\"462\">\n\n---\n\n**Loyalty Payment**\n\n<img src=\"https://content.pstmn.io/9cdc5940-74e5-42b8-a80c-43e14630bac9/aW1hZ2UucG5n\" width=\"657\" height=\"613\">\n\n---\n\n**Reward Reversal**\n\n<img src=\"https://content.pstmn.io/7d53f62c-7d28-4461-9e97-d48c2271a36e/aW1hZ2UucG5n\" width=\"623\" height=\"330\">\n\n---\n\n**Loyalty Payment Reversal**\n\n<img src=\"https://content.pstmn.io/bfebcc19-7ace-470d-95ed-adce71884792/aW1hZ2UucG5n\" width=\"634\" height=\"282\">\n\n# Other Information\n\n### **Accepted Cases**\n\nThe Zonal interface will always send data in Camel Case format. URL parameters are all sent lower case.\n\nThe interface will accept response both PascalCase or camelCase response fields.\n\n### **Null Values**\n\n‘null’ fields can be sent or omitted as preferred\n\n### Loyalty Identifyers\n\nAll loyalty ideitifers have the following restriction\n\n- Must have a defined prefix ie 1, the prefix mut be between 1-2 digits long.\n    \n- Must be between 2 and 40 character long (including prefix)\n    \n- The prefix & identifyer can include 0-9 A-Z (only captials), . (full stop), _(underscore) - (hyphen), @ (at symbol). No other character are supported.\n    \n\n# Standard Definitions\n\n## **Ticket Definition**\n\nNote: A single discount may be split across multiple ticket items. Each ticket item will reflect how much a single product item is discounted by.\n\n| Name | **Data Type** | Optional/Mandatory | Description |\n| --- | --- | --- | --- |\n| ticketId | string | Mandatory | Ticket ID |\n| loyaltyId | string | Conditional | The loyalty number currently associated  <br>with the account, if any. |\n| createdOn | DateTime | Mandatory | The time stamp for when the account was opened |\n| table | string | Conditional | The table number if added to a table |\n| accountNumber | string | Conditional | The POS account number |\n| employeeId | string | Conditional | The employee number |\n| coverCount | string | Conditional | Number of covers on a table |\n| customerName | string | Conditional | The guests name on the table |\n| isClosed | bool | Conditional | If the account is closed |\n| closed | DateTime | Conditional |  |\n| updated | DateTime | Conditional | if the account was updated |\n| updatedClosed | DateTime | Conditional |  |\n| table | string | Conditional | Guests table number |\n| ticketItems | Array | Mandatory | Array of Aztec Items on the account |\n| ticketItems > ticketItemId |  | Conditional |  |\n| ticketItems > itemId | string | Conditional | Product - Entity code  <br>Discount - Discount ID  <br>Promotion - Promotion ID |\n| ticketItems > portionId | string | Conditional | Portion ID - Products only |\n| ticketItems > destinationId | string | Conditional | The order detaination of the item |\n| ticketItems > isLoyaltyReward | bool | Conditional | Has been redeemed via loyalty:  <br>**True** - added via loyalty redemption  <br>**False** - added via the POS |\n| ticketItems > itemType | string | Conditional | Product, Discount,Promotion |\n| ticketItems > name | string | Conditional | Item name |\n| ticketItems > quantity | decimal | Conditional | quality of items |\n| ticketItems > amount | decimal | Mandatory | **Product** - Price of the item  <br>**Discount** - value of discount  <br>**Promotion** - value deduced via Promotion |\n| ticketItems > position | string | Mandatory | The purpose of this field is to identify which items on the check are parent items and which items are children e.g. a top level main meal may have a position of ‘2’ on the order whilst the first side choice for that meal would be ‘2.1’ and the second side choice ‘2.2’.Discounts and promotions are treated as children of the product lines they apply to e.g. a 20% account wide discount could have a position of ‘2.3’ on the main meal above, and ‘1.1’ on the preceding product line in the account. Top level items will be sent with just a single digit i.e. as ‘2’ and not as ‘2.0’ |\n| ticketItems > subCategory | string | Conditional | Aztec SubCategory - Product only |\n| ticketItems > category | string | Conditional | Aztec Category - Product only |\n| ticketItems > superCategory | string | Conditional | If this item is a product line, then the id of the super-category this product belongs to |\n| ticketItems > subDivision | string | Conditional | if this item is a product line, then the id of the sub-division this product belongs to |\n| ticketItems > division | string | Conditional | If this item is a product line, then the id of the division this  <br>product belongs to |\n| ticketItems > originalRingUpTime | DateTime | Mandatory | The local time (from the POS) showing when the line was rung up in format YYYY-MM-DDThh:mm:ss. |\n| ticketItems > discountReason | string | Conditional | A free text field of the discount reason, if this is a discount, and the POS has collected a reason for applying it to the POS account |\n| ticketItems > clmAccountType | string | Conditional | CLM Account Type if the item was applied by a external platfom  <br>Common IDs are:  <br>1 - Zonal Loyalty  <br>2 - Zonal gift card  <br>3 - Zonal Vouchers  <br>22 - Standard loyalty  <br>23 - Standard Vouching  <br>24 - Standard Gift |\n| ticketItems > parentItemId | string | Conditional | Only present for discount lines which have been apportioned to a specific product line. The Id of the  <br>orderline the discount applies to. |\n| ticketItems > parentTransactionId | string | Conditional | Only present for child/choice orderlines. This is the Id of the parent orderline that the choice applies to |\n| ticketItems > ShortDescription | string | Conditional | Descriptions of a product as configured in the Zonal system. |\n| ticketItems > LongDescription | string | Conditional | Descriptions of a product as configured in the Zonal system. |\n| ticketItems > isMoved | bool | Mandatory | True if this Ticket Item has been moved on to this ticket from another one e.g. a POS account has bene merged or split. |\n| ticketItems > orderLine | string | Conditional | Only present for promotion items. The Orderline Id of the orderline being modified by this promotion line |\n| transactionGuido | string | Conditional | A Zonal POS specific field containing a unique Id for the  <br>ticket item |\n| portionName | string | Conditional | The name of the orderline's portion if any |\n| destinationName | string | Conditional | The name of the orderline's destination if any |\n| discountName | string | Conditional | The name of the discount if any |\n| taxesDue | string | Conditional | Array of Tax information. Only exclusive taxes are dispalyed and not inclusive taxes like VAT. |\n| taxesDue > taxId | string | Conditional | The ID of the Tax rate applied |\n| taxesDue > name | string | Conditional | Name of the tax rate applied |\n| taxesDue > isServiceCharge | bool | Conditional | Is the tax a service charge  <br>**True** - Service charge  <br>**False** - Other tax rate |\n| taxesDue > amount | decimal | Conditional | Value of the tax rate |\n| payments | Array | Conditional | Array of Payments |\n| payments > paymentId | string | Mandatory | GUID for the payment |\n| payments > paymentMethodId | string | Mandatory | Payment method ID |\n| payments > name | string | Mandatory | Name of payment Method |\n| payments > receiptNumber | string | Mandatory | The Aztec Receipt Number |\n| payments > isLoyaltyReward | bool | Mandatory | True’ if this product was redeemed as a reward via the loyalty/voucher system. |\n| payments > voucherCode | string | Conditional | If this item was redeemed as a reward via the voucher system, then this the voucher code used. |\n| payments > redemptionId | string | Conditional | If this item was redeemed as a reward via the  <br>voucher/loyalty system, then this is the redemptionId GroupingRedemptionId issued. |\n| payments > amount | decimal | Conditional | Value of payment |\n| payments > position | string | Conditional | Postion of the payment in the Aztec account |\n| payments > originalRingUpTime | DateTime | Mandatory | Te local time (from the POS) showing when the  <br>payment was rung up in format YYYY-MM-DDThh:mm:ss. |\n| payments > taxesPaid | Array | Conditional | Array of Tax paid. Only exclusive taxes are dispalyed and not inclusive taxes like VAT. |\n| payments > taxesPaid > taxId | string | Conditional | The ID of the Tax rate applied |\n| payments > taxesPaid > name | string | Conditional | Name of the tax rate applied |\n| payments > taxesPaid > isServiceCharge | bool | Conditional | Is the tax a service charge  <br>**True** - Service charge  <br>**False** - Other tax rate |\n| payments > taxesPaid > amount | decimal | Conditional | Value of the tax paid |\n| payments > CardToken | string | Conditional | Card transaction card token data |\n| payments > eftProvider | string | Conditional | EFT payments only. The EFT provider. |\n| payments > eftPan | string | Conditional | EFT payments only. Last 4 digits of customer’s EFT  <br>card number. |\n| payments > tip | decimal | Conditional | The amount of any tip/gratuity added to this payment |\n| siteReference | string | Optional | A reference to the site from which ticket is sent |\n| siteId | string | Optional | The id of the site from which the ticket is sent.  <br>v1.57 int  <br>v1.58 string |\n| siteSalesAreaId | string | Optional | Sales area id of the site from which ticket is sent  <br>v1.57 int  <br>v1.58 string |\n| currency | string | Conditional | The currency of the ticket |\n\n## Reward Definition\n\n| Name | **Data Type** | Optional/Mandatory | Description |\n| --- | --- | --- | --- |\n| rewardId | string | Mandatory | A unique id for this reward. |\n| groupingRedemptionId | string | Conditional | The unique id for the current set of reward redemptions – this can just be the requestId or it can be a unique id  <br>generated by the loyalty system. This is only really needed to group all auto update (members pricing) style rewards together or to group all rewards that came from a single voucher redemption.  <br>For voucher redemptions this should be the same as the outer redemptionId. |\n| rewardType | DateTime | Mandatory | The type of the reward, see reward types. |\n| name | string | Mandatory | The name of the reward. Generally, the POS will use the names defined in the Aztec system to display to the end user, but this name will be used in the balance summary, and in error messages if a corresponding Aztec product/discount cannot be found. |\n| percentage | decimal | Conditional | Only populated for ProductPercentageDiscount types. This corresponds to the percentage amount to apply as a discount. |\n| amount | decimal | Conditional | Only populated for AccountAmountDiscount,ProductAmountDiscount and Payment types. This corresponds to the amount to apply as a discount/payment.  <br>This can be null for payments if the paymentId specified corresponds to an fixed amount payment in the Zonal system. |\n| quantity | Integer | Conditional | The number of items of this reward that can be added to the POS account. Only populated for Product types. |\n| productId | string | Conditional | Populated for ProductPercentageDiscount, ProductAmountDiscount (if ticketItemId is not populated) or Product types. This corresponds to the id of the product that is available as a reward or is being discounted |\n| ticketItemId | string | Conditional | Optionally populated for ProductAmountDiscount (if ProductId is not populated) types. This corresponds to the id of the ticket item that is being discounted.  <br>Note - The ticketItem referenced must be a top-level product type ticketitem. |\n| promotionId | string | Conditional | Only populated for Promotion type. This corresponds to the id of the promotion that is available as a reward. |\n| paymentId | string | Conditional | Only populated for Payment type. This corresponds to the id of the Aztec payment method that will be applied to the account. |\n| discountId | string | Conditional | Populated for FixedDiscount type and, optionally, for ProductAmountDiscount. This corresponds to the id of the Aztec discount that will be applied to the account |\n| pointsCost | decimal | Conditional | If this field contains a value then the guest will need to spend that many points from their points balance to obtain  <br>the reward. |","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"3146903","team":2971904,"collectionId":"da4f2ccc-6586-4ab2-a244-d2ad47a0702a","publishedId":"2sAYXCkKFW","public":true,"publicUrl":"https://documenter-api.postman.tech/view/3146903/2sAYXCkKFW","privateUrl":"https://go.postman.co/documentation/3146903-da4f2ccc-6586-4ab2-a244-d2ad47a0702a","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"documentationLayout":"classic-double-column","customisation":{"metaTags":[{"name":"description","value":""},{"name":"title","value":""}],"appearance":{"default":"light","themes":[{"name":"dark","logo":null,"colors":{"top-bar":"212121","right-sidebar":"303030","highlight":"FF6C37"}},{"name":"light","logo":null,"colors":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"}}]}},"version":"8.10.0","publishDate":"2025-02-13T12:43:01.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{"title":"","description":""},"logos":{"logoLight":null,"logoDark":null}},"statusCode":200},"environments":[],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/1fab4a54cf79099a5c158e2039991780c484ff3d227247fc8a002ae4c29e7154","favicon":""},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"}],"canonicalUrl":"https://documenter.gw.postman.com/view/metadata/2sAYXCkKFW"}