Promotions Configuration
Groups
Groups allow it to split sets of rules and attach conditions to them. This eases the design of promotions and improves the evaluation performance. For example allows this to create a group for the promotion rules which are shared between all stores and to create groups for individual shops, i.e. the store that have just opened.
When evaluation the configuration the promotion engine first merges the rules of all groups which either have no condition or for which the cart matches the condition, into a list of active rules.
Ranks
Ranks define the order of promotion rule evaluation and determine the strategy how the rules are applied. Each rule is linked to a rank.
When evaluating promotions configuration the engine groups the active rules according to their rank. The rules for each rank are then executed according to the evaluation mode. Each rule evaluation might change the cart, i.e. it adds a discount to the cart. Hence the order of the rule evaluation has great effect on the final result.
When evaluating the rules of a rank two modes can be used: selectBest
and applyAll
. The selectBest
only applies
the rule in rank which result in the maximal reduction of the total. The applyAll
mode just applies all rules one
after another.
Conditions
Compositions: and
and or
Compositions allow to build complex expressions. They can be freely nested. The supported compositions are: Conjunction
and
and disjunction or
.
Example: Match items with SKU "1", which are referred to by a coupon with id "coupon-id"
{
"type": "and",
"children": [
{
"type": "hasSKU",
"args": {
"equals": "1"
}
},
{
"type": "isReferredToByCoupon",
"args": {
"value": "coupon-id"
}
}
]
}
Predicate hasSKU
Match line items with the given or one of the given SKUs.
Name | Type | Optional | Description |
---|---|---|---|
equals | string | yes | Matched SKU |
oneOf | string[] | yes | List of SKUs |
Example:
{
"type": "hasSKU",
"args": {
"oneOf": ["1", "2"]
}
}
Predicate amountGreaterOrEqual
Match line items with amount greater or equal to the given value.
Name | Type | Optional | Description |
---|---|---|---|
value | integer | no | Amount |
Example: Match line items with amount greater two
{
"type": "amountGreaterOrEqual",
"args": {
"value": 2
}
}
Predicate isExclusiveForLineItem
Match line items for which no promotion was already applied.
Example:
{
"type": "isExclusiveForLineItem"
}
Predicate isReferredToByCoupon
Match line items which are referred by a not already redeemed coupon with the given id.
Name | Type | Optional | Description |
---|---|---|---|
equals | string | no | Id of the coupon |
Example:
{
"type": "isReferredToByCoupon",
"args": {
"value": "id"
}
}
Predicate hasAdditionalAttribute
Match line items based on additional attributes. Either by specifying included values through the equals
or oneOf
property. Or by excluding some values through the notEquals
or noneOf
property.
Name | Type | Optional | Description |
---|---|---|---|
name | string | no | Name of the attribute |
notEquals | string | yes | Excluded value |
noneOf | string[] | yes | List of excluded values |
equals | string | yes | Included value |
oneOf | string[] | yes | List of included values |
Example: Match line items with the property prodcut group set to "05"
{
"type": "hasAdditionalAttribute",
"args": {
"name": "productGroup",
"equals": "05"
}
}
Example: Exclude line items with the property product group either "05" and "10"
{
"type": "hasAdditionalAttribute",
"args": {
"name": "productGroup",
"noneOf": ["05", "10"]
}
}
Predicate hasLoyaltyCard
The customer presented a valid loyalty card.
Example:
{
"type": "hasLoyaltyCard"
}
Predicate hasCoupon
The cart contains a not redeemed coupon with the given id.
Name | Type | Optional | Description |
---|---|---|---|
equals | string | yes | Id of the matched coupon |
oneOf | string[] | yes | List of ids of matched coupons |
Example:
{
"type": "hasCoupon",
"args": {
"equals": "id"
}
}
Predicate hasCouponCode
The cart contains a not redeemed coupon with the given code.
Name | Type | Optional | Description |
---|---|---|---|
equals | string | yes | Code of the matched coupon |
oneOf | string[] | yes | List of codes of matched coupons |
Example:
{
"type": "hasCouponCode",
"args": {
"equals": "code"
}
}
Predicate totalGreaterThan
The total of the cart is greater than the given value.
Name | Type | Optional | Description |
---|---|---|---|
value | string | no | Total of the Cart |
Example:
{
"type": "totalGreaterThan",
"args": {
"value": "100"
}
}
Predicate totalGreaterThanOrEqual
The total of the cart is greater than or equal to the given value.
Name | Type | Optional | Description |
---|---|---|---|
value | string | no | Total of the Cart |
Example:
{
"type": "totalGreaterThanOrEqual",
"args": {
"value": "100"
}
}
Predicate discountableTotalGreaterThanOrEqual
The total of the discountable items of the cart is greater than or equal to the given value.
Name | Type | Optional | Description |
---|---|---|---|
value | string | no | Total of the Cart |
Example:
{
"type": "discountableTotalGreaterThanOrEqual",
"args": {
"value": "100"
}
}
Predicate hasShopID
Shop has the given id.
Name | Type | Optional | Description |
---|---|---|---|
equals | string | yes | Id of the shop |
oneOf | string[] | yes | List of ids of the matched shops |
Example:
{
"type": "hasShopID",
"args": {
"equals": "100"
}
}
Predicate hasExternalShopID
Shop has the given external id.
Name | Type | Optional | Description |
---|---|---|---|
equals | string | yes | Id of the shop |
oneOf | string[] | yes | List of ids of the matched shops |
Example:
{
"type": "hasShopID",
"args": {
"equals": "1012"
}
}
Predicate hasProductInCart
Match carts containing the given number of a product.
Name | Type | Optional | Description |
---|---|---|---|
equals | string | no | SKU of the matched product |
amount | integer | no | Number of products |
Example: Cart contains six of the product
{
"type": "hasProductInCart",
"args": {
"equals": "1",
"amount": 6
}
}
Predicate isCurrentlyActive
Match if the current time is in the given time range.
Name | Type | Optional | Description |
---|---|---|---|
from | string | no | Begin of the time range (Format RFC3339) |
to | string | no | End of the time range (Format RFC3339) |
Example:
{
"type": "isCurrentlyActive",
"args": {
"from": "2025-03-15T00:00:00+01:00",
"to": "2025-03-22T00:00:00+01:00"
}
}
Actions
Action: addCartDiscount
Grant a relative or absolute discount for the cart.
The discount is only granted to discountable line items and does not exceed the total price of the cart.
Name | Type | Optional | Description |
---|---|---|---|
name | string | no | Name of the discount created |
value | string | no | Discount granted |
absolute | boolean | no | Value represents an absolute discount or a relative discount in percent |
isMultiusable | boolean | no | Apply discount multiple times |
attributes | object | yes | Additional attributes added to the discount |
Example: Grant 10% discount on the cart
{
"type": "addCartDiscount",
"args": {
"name": "Opening Discount",
"value": "10",
"absolute": false,
"isMultiusable": false
}
}
Action: modifyPrice
Modifies the price of the line item.
If the action is marked as multiusable it will be applied to all matching line items. Otherwise, it is applied to the cheapest line item.
Name | Type | Optional | Description |
---|---|---|---|
name | string | no | Name of the Price Modifier created |
value | string | no | Absolute price or percentage of the price |
absolute | boolean | no | Value represents an absolute price or is relative to the current price (in percent) |
isMultiusable | boolean | no | Apply discount multiple times |
Example: Set price of one item to 1.99
{
"type": "modifyPrice",
"args": {
"name": "Discount",
"value": "1.99",
"absolute": true,
"isMultiusable": false
}
}
Example: Set price to 80% of the original price
{
"type": "modifyPrice",
"args": {
"name": "Discount",
"value": "80",
"absolute": false,
"isMultiusable": true
}
}
Action: addLineItemDiscount
Grants an absolute or relative discount to the matched line items.
If the action is marked as multiusable it will be applied to all matching line items. Otherwise, it is applied to the cheapest line item.
If the amount specifies the number of items for which the discount should be applied. The required amount specifies the number of items which are required to qualify for this amount. For example:
- Buy 1 get 1 free: The amount is one and the required amount is one (or not set)
- Buy 6 get 2 free: The amount is two and the required amount is six
Name | Type | Optional | Description |
---|---|---|---|
name | string | no | Name of the discount created |
value | string | no | Discount granted |
absolute | boolean | no | Value represents an absolute discount or a relative discount in percent |
amount | integer | no | Number of items to reduce |
requiredAmount | integer | yes | Required number of items |
isMultiusable | boolean | no | Apply discount multiple times |
attributes | object | yes | Additional attributes added to the discount |
Example: Reduce a line item by 20%
{
"type": "addLineItemDiscount",
"args": {
"name": "20% off",
"value": "20",
"absolute": "false",
"amount": 1,
"isMultiusable": true
}
}
Example: Get two bottles free, when buying a box once
{
"type": "addLineItemDiscount",
"args": {
"name": "Buy six get two free",
"value": "100",
"absolute": "false",
"amount": 2,
"requiredAmount": 6,
"isMultiusable": false
}
}
Action: reduceItem
Adds a discount which reduces the price of the price of the line item to given one.
If the price is lower than the given price, the line item is not reduced.
Name | Type | Optional | Description |
---|---|---|---|
name | string | no | Name of the discount created |
value | string | no | Reduced price |
attributes | object | yes | Additional attributes added to the discount |
Example:
{
"type": "reduceItem",
"args": {
"name": "Discount",
"value": "1.99"
}
}
Action: addForceControl
Forces a control of the cart by an employee.
Example:
{
"type": "addForceControl"
}
Action: redeemReferringCoupon
Redeems the all coupons with the given id referring to the matched line items.
Name | Type | Optional | Description |
---|---|---|---|
id | string | no | Identifier of the coupon |
Example:
{
"type": "redeemReferringCoupon",
"args": {
"id": "123"
}
}
Action: redeemCouponID
Redeems all coupons with the given id in the cart.
Name | Type | Optional | Description |
---|---|---|---|
id | string | no | Identifier of the coupon |
Example:
{
"type": "redeemCouponID",
"args": {
"id": "123"
}
}
Action: redeemCouponCode
Redeems all coupons with the given code in the cart.
Name | Type | Optional | Description |
---|---|---|---|
code | string | no | Code of the coupons to redeem |
Example:
{
"type": "redeemCouponCode",
"args": {
"code": "2123456789012"
}
}
Action: addAdditionalAttribute
Sets an additional on the matched line items.
Name | Type | Optional | Description |
---|---|---|---|
name | string | no | Name of the attribute |
value | string | no | Value of the attribute |
Example:
{
"type": "addAdditionalAttribute",
"args": {
"name": "property",
"value": "value"
}
}
Action: reduceBundle
Reduces a bundle of product to the given total price.
Name | Type | Optional | Description |
---|---|---|---|
name | string | no | Name of the discount created |
skus | string | no | List of SKUs of the products in the bundle |
value | string | no | Price of the bundle |
attributes | object | yes | Additional attributes added to the discount |
Example:
{
"type": "reduceBundle",
"args":{
"name": "Lunch bundle",
"skus": ["water", "bread"],
"value": "1.99"
}
}