Managing a Promotion
After promotions are correctly created via SCAYLE Panel or via Admin API, they will have an effect on the customer's Basket and Orders.
Assigning a promotion to a Basket Item
Once a Basket with items are created, the Basket endpoint returns all applicable promotions that can be applied to that basket and to the items that belong to that basket.
Follow these steps to apply promotions to basket items:
- Fetch the basket with
with=applicablePromotionsto retrieve all promotions eligible for the current basket. - Iterate over the
applicablePromotionsarray. Each entry contains anitemId(the basket item the promotion applies to) and apromotionId. - Apply promotions based on the promotion type:
- For Automatic Discounts and Combo Deals: include the
promotionIdin the Add a Variant call or Update an Item call for the givenitemId. - For Buy X Get Y promotions where
itemIdisnull: the free gift is not yet in the basket. See Assigning a Free Gift (Buy X Get Y). - For Promotion Code-based promotions: these require the customer to first enter a code. See Applying a Promotion Code.
- For Automatic Discounts and Combo Deals: include the
- After each application, re-fetch the basket with
with=applicablePromotionsto check for conflicts or changes in eligibility before applying the next promotion.
We recommend applying promotions one by one and using the response of the updated basket item (with=applicablePromotions). This ensures there are no conflicts between the promotions.
We would also recommend running this logic generally in two cases:
- Upon the first initial load of the basket, to handle new promotions after a user comes back to the shop
- After any Basket Action like an Add to Basket or quantity update is done by the user
Understanding Applicable Promotions
The applicable promotions array consists of all promotions that meet the conditions for and can be applied to that item.
The following fields are present across all promotion types:
| Field | Format | Description |
|---|---|---|
| itemId | string | The Basket Item ID to which the promotion should be applied. This can be null in case of a buy_x_get_y effect where the free gift item is not in the basket yet. |
| promotion.id | string | Unique identifier of a promotion |
| promotion.name | string | The internal name of a promotion |
| promotion.displayName | string | The name of the promotion that will be displayed to the customers across the order lifecycle |
| promotion.schedule | object | Set dates which promotion are valid |
| promotion.isActive | boolean | Identifies if a promotion is active or not |
| promotion.conditions | Array of objects | Will describe all conditions that are attached to the promotion |
| promotion.customData | object | The object with custom fields that are added during promotion creation |
| promotion.priority | number | The priority of the promotion compared to other promotions. This can be used to decide which promotion to apply if there is a conflict between two |
The promotion.effect object and promotion.tiers differ by promotion type. See below for type-specific fields.
Buy X Get Y-Specific Fields
| Field | Format | Description |
|---|---|---|
| promotion.effect.type | string | buy_x_get_y |
| promotion.effect.additionalData.eligibleItemsQuantity | integer | Defines the quantity amount the customer needs to buy |
| promotion.effect.additionalData.maxCount | integer | Defines how many items a customer is entitled to get a discount from |
| promotion.effect.additionalData.maxCountType | string | Max Count Type defines how the quantity amount will be considered to make a promotion eligible for that basket or not.
|
| promotion.effect.additionalData.variantIds | Array | Variant IDs which participate in a promotion |
| promotion.effect.additionalData.discountType | String | Can be absolute or relative |
| promotion.effect.additionalData.discountValue | Integer | Discount amount of the promotion in cents |
| promotion.effect.additionalData.discountDistribution | String | Defines if a discount will be distributed pro_rata or not. In case of a proportional distribution, this value will be reflected as pro_rata. Else it will be described as none. |
| promotion.effect.additionalData.applicableItemSelectionType | String | Defines which item in the basket the discount will be applied to. Can be variant_ids or cheapest. |
| promotion.tiers | Not applicable for Buy X Get Y |
Combo Deal-Specific Fields
| Field | Format | Description |
|---|---|---|
| promotion.effect.type | object | combo_deal |
| promotion.effect.additionalData.eligibleItemsQuantity | integer | Defines the quantity amount the customer needs to buy |
| promotion.effect.additionalData.maxCountType | string | Max Count Type defines how the quantity amount will be considered to make a promotion eligible for that basket or not.
|
| promotion.effect.additionalData.price | Integer | Price of the deal in cents |
| promotion.tiers | Not applicable for Combo deals |
Automatic Discount-Specific Fields
| Field | Format | Description |
|---|---|---|
| promotion.effect.type | object | automatic_discount |
| promotion.effect.additionalData.type | string | absolute or relative |
| promotion.effect.additionalData.value | Integer | Discount amount of the promotion in cents |
| promotion.tiers | array of objects | MOV tiers related to the |
| promotion.tiers.id | number | The identifier of a tier. It is unique for tiers in this promotion |
| promotion.tiers.mov | number | The minimum order value that would activate a tier in cents |
| promotion.tiers.name | string | The name of a tier |
| promotion.tiers.effect.additionalData.type | string | The discount type of a tier. It could be absolute or relative |
| promotion.tiers.effect.additionalData.value | number | The discount amount of a tier in cents |
Assigning a Free Gift (Buy X Get Y)
When a Buy X Get Y promotion includes a free gift that is not currently in the customer's basket, the corresponding applicablePromotions entry will have itemId: null. This is the indicator that the free gift variant needs to be explicitly added to the basket before the promotion discount can be applied. This flow differs from automatic discounts, where the promotion is applied directly to an item that is already in the basket.
Follow these steps to assign a free gift:
- Identify entries in
applicablePromotionswithpromotion.effect.type: buy_x_get_yanditemId: null. - Retrieve the free gift variant(s) from
promotion.effect.additionalData.variantIds. If multiple variants are listed, present the selection to the customer (for example, different sizes or colors of the same gift item). - Add the chosen free gift variant to the basket using the Add a Variant call and include the
promotionIdin the request body to apply the promotion at the time of adding. - Re-fetch the basket with
with=applicablePromotionsto confirm the discount was applied correctly to the new item.
Applying a Promotion Code
Code-based promotions (Promotion Codes) are not applied automatically. They only become active after a customer enters a valid code in the storefront, making the flow different from automatic discounts that are applied as soon as eligibility conditions are met.
Follow these steps to apply a code-based promotion:
- Collect the promotion code entered by the customer.
- Fetch the basket with
with=applicablePromotionsto get all promotions currently eligible for the basket. - Filter the
applicablePromotionsarray for entries wherepromotion.codematches the entered code. - For each matching entry, include the
promotionIdin the Update an Item call for the correspondingitemIdto apply the discount. - If no matching promotion is found for the entered code, surface an appropriate error to the customer — the code may be invalid, expired, or not applicable to the current basket contents.
For a complete Storefront Application implementation including UI components, composables, and step-by-step integration instructions, see Promotion Codes.
Managing Orders with Promotions
Promotion Information on Checkout
All promotions that are applicable to an order are shown on item level on our Checkout UI.
We highly recommend the usage of a displayName in order for the customers to identify the promotions better, as this information can also be used on E-mail templates and Invoices.
Promotion Information on GET Order endpoint and Webhooks
Since promotions will always be applied to an item, the promotion information can be found inside the items array of the Order endpoints
| Field | Format | Description |
|---|---|---|
| promotion.id | string | Unique identifier of a promotion |
| promotion.name | string | The internal name of a promotion |
| promotion.version | string | The version of a promotion. |
| promotion.displayName | string | The name of the promotion that will be displayed to the customers across the order lifecycle |
| promotion.code | string | The code which was attached to a promotion |
Configuring a promotion on Storefront
For details see the Promotions & Campaigns.