POS Product Configuration

PLU

The PLU is typically something that's easier for the customer to use, and it should be the same across all locations for the same product. The PLU is what will be used for mapping orders coming from the channels to your integrated POS.

Price

Price is stored as an int with 2 decimal digits, for example, 5 euros is stored as 500.

Price Levels

Products will have a base price field, where 'Price Levels' are optional variations to set for this price, e.g. apply a different price per channel or delivery type.

See the snippet below of a product set with a priceLevels object where the unique identifier (the posId) is the key, set along with a price integer value.

The library of priceLevels would then be defined giving a descriptive name to each posId used

After syncing products with priceLevels , they can be selected in the channel link settings. When previewing or pushing menus for these channel links, the selected pricelevel will be applied. See guide here for further information on testing this function.

📘

Use the same "posId" values

Please make sure the same "posId" values are used across different locations

Example

After defining a Burger price level on your burgers, sync products and apply the price level to a single (or any) channel to run the BurgerDeal on.

{
    "name": "Burger",
    "price": 1000,
    "priceLevels": {
        "channel_A": 1000,
        "channel_B":  900,
        "channel_C":  500
    }
}
{
    "name":  "Channel Awesome",
    "posId": "channel_A"
}

📘

Note that when no data is available on a product for the selected price level, the base price is applied.

❗️

Price format

Make sure the values of product price, tax and price level are sent as integers and not floats.

🚧

Null values

To prevent potential failures in product synchronization, please avoid sending null values. Instead, if the data type allows, utilize empty strings. Additionally, when dealing with prices, ensure that only integers are sent.

Overloads

Certain product structures can contain "overloads" which are effectively like surcharges which can be applied dependant on which grouping the product is offered in.

In the example below and also in samples 4 and 5 in the Insert/update products page, you can see both a product and modifier price being set this way.

The "overloads" array contains "scopes" which specify the group(s) in which either a"bundlePrice"(if a bundle group) or "price"(if not a bundle group) can be set differently.

In the first example below, an Avocado with base price 50, can be set to 0 if included in a group "FREE-TOP" and set to 100 if set in a group "XTRA-TOP"

The second example shows the same format for an Ice Cream with a base price 500, which can be set to 0 if included in a group "FREE-DESS" and 450 if set in a group "ADD-ON"it used the bundlePrice attribute as the group is not a modifier group (type:3) but bundle (type:4)

{
    "productType": 2,
    "plu": "AVO",
    "price": 50,
    "name": "Avocado",
    "overloads": [
        {
            "scopes": [
               "FREE-TOP"
            ],
            "price": 0
        },
        {
            "scopes": [
               "XTRA-TOP"
            ],
            "price": 100
        }
    ]
}
{
    "productType": 1,
    "plu": "AVO",
    "price": 500,
    "name": "Ice Cream",
    "overloads": [
        {
            "scopes": [
               "FREE-DESS"
            ],
            "bundlePrice": 0
        },
        {
            "scopes": [
               "ADD-ON"
            ],
            "bundlePrice": 450
        }
    ]
}

Tax

When syncing products to Deliverect, it is important to specify the sales tax rate which applies. The sales tax which applies can be differentiated between the order types of;

  • Delivery (deliveryTax)
  • Takeaway (takeawayTax)
  • Eat-in (eatInTax)

Tax rates are always stored as an int with 3 decimal digits e.g. 5% would be stored as 5000

It's acceptable to have products which have 0% tax, and even a 0 price.

{
  "productType": 1,
  "plu": "GB-02",
  "name": "Ginger Beer",
...
  "deliveryTax": 5000,
  "takeawayTax": 5000,
  "eatInTax": 5000,

📘

deliveryTax and takeawayTax

The above sales taxes are not the same as deliveryCostTax or serviceChargeTax which are seperate taxes applied by an ordering channel to the cost of delivery or service charge

Images

The image URL you provide here is cached and put behind a CDN. Images are cached on access for 24 hours. Channels will download the images and also cache them. Depending on the channel, images can/will be resized. Deliverect supports images of up to 16.8 megapixels in size.

Categories

A category is a way to organise products into a section to be referenced when building a menu. Products can be in one or more categories denoted by an array of posCategoryIds. It's important to have at least one category per product.

Overrides

Customers are able to overwrite certain details of products within the menu builder in Deliverect, including;

  • Names
  • Descriptions
  • Prices
  • Images

*Everything that is not overwritten in Deliverect can be updated via this endpoint

Product types

When pushing products to us, you need to specify the relevant value which represents the product type used

Product TypeInteger ValueInteger Value
ProductA 'top level' item on a menu (can also be grouped within a modifier group or bundle)1
ModifierOptions selectable when ordering a product, typically modifications of the product2
Modifier GroupA grouping of modifiers (can also group products)3
BundleCan only contain products which are offered as part of a 'Meal Deal' and which Deliverect will set to zero value. Exception to this is where ## Overloads are set, see example 'Bundles (Product price overloads)' on the right hand side.4

Modifier Groups

The first example below represents a simple Product (productType:1) with three modifier groups attached (productType:3) where each modifier group contains an amount of modifiers (productType:2)

Typical use case: This structure would support standard modifications to a product e.g. required modifiers of 'Rare', 'Medium' or 'Well Done' would be applied to a Steak product.

This same structure can also be applied to group together products (productType:1) within modifier groups (productType:3)

Typical use case: This structure is often applied as an "Upsell" where additional optional priced items are offered alongside a product.

Item Group Rules

Both Modifier Groups and Bundles allow certain ordering "rules" to be applied as follows;

RulePurpose
minSetting a minimum value to a group of options e.g. 0would be equivalent to 'optional'and1or more would be 'required'
maxSetting a maximum value limits how many items in a group can be ordered
multiMaxSetting the attribute multiMax allows control over the maximum quantity of any single item in a group.

A value of '2' for example, means that each item in a group can be selected at most 2 times. The selection of a single item will still be limited by the overall max value allowed in a group
defaultQuantityThis attribute makes a modifier preselected by default, where a value of 1 is equivalent to a pre-selected item. Most channels can handle a pre-selection, but not with a pre-selected quantity of more than 1

Maximum Total Limit on Product

Sometimes, merchants would like to restrict the number of products that can be sold within one order. For example, think of medicine products where only one of the medications is allowed to be sold per customer order. You can achieve that by adding the attribute "multiMax" under the product information under the product information. For example, "multiMax": 1, under a product means that this product can only be sold one time in a given order basket.

Meal Deals

In the payload examples on this page, shown on the right hand side, various product structures are depicted including combos and meal deals.

These examples use the structure below, where products are linked together using the subProducts field.

Meal Deal / Combo Structure

A meal deal or combo will typically have a set price, where a grouping of a 'Bundle' can contain products which normally have a price, but as part of a bundle will be zero-priced.

The diagram below shows that it is possible to contain the zero-priced 'Bundle' options as well as 'Modifier Groups' containing priced items.

❗️

Important Attribute for Combos/Meal Deals

Please ensure the attribute "isCombo": true is set on the main product "productType": 1, as certain channels need this flag to display these options correctly

Bundles cannot be nested under a sub-product and must be at the top-level of options.

The structure to form bundles could be as follows:

  • Combo product Type:1
  • Bundle Type:4
    • Product Type:1
      • Modifier group Type:3
        • Modifier Type:2

Nested Modifiers

A product configuration can include a sub-group of options to be selected. These options themselves can also contain their own sub-groups, this is reffered to as 'Nested Modifiers'.

Meal Deal with 'Upsell'

In the Meal Deal with upsell (example 3) we have a modifier group in addition to the bundles. This allows for Fries to be ordered which are not included as part of the deal and the customer will be charged accordingly. This is referred to as an 'upsell', which can be modifier groups containing products or modifiers.

It is also possible to construct combo products as follows:

  • Combo product Type:1
  • Modifier group Type:3
    • Modifier Type:2
      • Modifier group Type:3
        • Modifier Type:2

Click here to see examples of how orders with these meal deal examples are sent to your POS in an order.

Auto Apply

There can be a use case where products ordered online should be received with a pre-defined set of sub products applied. This is not the same as items being pre-selected in the menu interface via defaultQuantity, but is a mechanism for specific items to be auto-applied (by Deliverect) following a completed order.

This is shown in the example below, where the Parsley Garnish and Melted Butter are within a modifier group 'Garnishes' which is set to apply these items automatically when the Steak Frites is ordered.

Note that "defaultQuantity": 3 is shown below and defines how many of the item should be auto-applied to the order. The "sortOrder" attribute allows a 'stepped' order of the auto-applied items to appear, where 0 is the first item to be listed.

NB: Neither the channel platform or end-consumer will see these items, and as such there can be no price associated with them. If de-selection of pre-set items or charging for them is a requirement, see instead the above section for 'Selected by Default'

"autoApply": [
    {
        "plu": "PR1"
    },
    {
        "plu": "PR2"
    }
],
{
    "productType": 2,
    "plu": "PR1",
    "price": 0,
    "name": "Parsley",
    "posProductId": "PA_POS-0023",
    "posCategoryIds": "",
    "imageUrl": "",
    "description": "",
    "deliveryTax": 0,
    "takeawayTax": 0,
    "subProducts": [],
    "defaultQuantity": 3,
    "sortOrder": 1
}

Product translations

Translations of product names and descriptions can be provided in the JSON. A base name is always required but translations are optional. Translations are supported for all product types.

The translations are passed as a nested JSON object where the property names are language tags and the values are the translations themselves.

See the language tags supported in the page below;

▶ Language Tags

Example

{
    "productType": 1,
    "plu": "MEAT-02",
    "price": 200,
    "name": "Chicken",
    "nameTranslations": {
        "ar": "دجاج",
        "en": "Chicken",
        "es": "Pollo",
        "nl": "Kip"
    },  
    "description": "Grilled chicken",
    "descriptionTranslations": {
        "ar": "دجاج مشوي",
        "en": "Grilled chicken.",
        "es": "Pollo asado.",
        "nl": "Gegrilde kip."
    }
}

Product visibility

A product can be marked as invisible (disabled) by setting visible property to false. After this action the product will be hidden all menus where it was used and will not be pushed to channels until it marked as visible again.

{
    "productType": 1,
    "plu": "SI-01",
    "price": 100,
    "name": "Fries",
    "visible": false
}

Product tags: consumable types and allergens

A product can have one or more product tags. These are are contained inside productTags

See the link below for the complete list of consumable types/allergens with corresponding tag value

▶ Product Tags

Bag Fee

In certain regions, ordering platforms are required to process a specific payment for a bag fee. Deliverect will by default included this fee within the serviceCharge. It is also an option for the POS to sync a bag fee product with a unique PLU, this would need manually set per channel but will ensure the POS receives the bag fee as seperate item in the orders payload.

See guide on setting a bag fee PLU here

Calories

If POS supports syncing calories this should be sent in the payload as shown in table of attributes below

ParameterMeaning
caloriesThis is the base calorie amount, where a maximum calories is set, this should be interpreted as the 'minimum'
caloriesRangeHighThe maximum calorie amount of an item
posProductIdThe posProductId is the internal ID used for products. It is unique across locations but is entirely optional as a reference only.
"products": [
          {
               "productType": 1,
               "plu": "PR03",
               "price": 900,
               "name": "Cheese Lovers Pizza",
               ...
               "calories": 500,
               "caloriesRangeHigh": 750
               },
               ...
               ]
          },

Nutritional Information and Supplemental Info

You can pass the nutritional and supplemental information of the products with the payload via the object nutritionalInfo and supplementalInfo, look at the example below:

📘

The unit of the values is gram. Notice, that ingredients and additives are lists of strings. You can add food business operator (fbo) information if required as per local legislation.

         "nutritionalInfo": {
				"netQuantity": {
					"amount": 4,
					"countUnitDescription": "4"
				},
				"servingSize": {
					"countUnitDescription": "grams",
					"unitType": 1,
					"amount": 5
				},
				"salt": 15,
				"protein": 15,
				"carbohydrates": 15,
				"saturatedFat": 15,
				"sugar": 15,
				"fat": 15
		  	},
			  "packaging": {
				"reusable": true,
				"storageInstructions": "Keep Chilled",
				"count": 1
			  },
			  "supplementalInfo": {
				"instructionsForUse": "Cool before drink.",
				"ingredients": [
					"Water",
					"Sugar"
				],
				"fbo": {
					"name": "John Doe",
					"address": "61 Am Stadtpark, 81243 München, Germany"
				},
				"legalName": "Test Legal Name",
				"additives": [
					"Artificial Food Coloring",
					"Sodium Nitrite",
					"Salt",
					"Aspartame"
				],
				"prepackaged": true,
				"deposit": 0
			  },