Overview of the concepts related to product pricing and discounts.
Pricing
For example, an SKU can cost €25 in Germany and €30 in Spain. Since the SKU has two Prices defined, the purchase Price for a Customer can depend on the country of purchase. For more information, see Price selection.
For example, you can create a base price for a new mobile phone for Customers in Germany who belong to your Platinum Customer Group. With Product Discounts, you can offer a discounted price for the same combination of dimensions (Germany and Platinum Customer Group). This provides flexibility in being able to utilize the base price together with the discounted price on your web interface, in addition to smooth reporting analytics.
Types of Prices
Embedded Prices
Changes to Embedded Prices can be staged before being published to the current representation of a Product.
Classic ProductCatalogModel. In the Modular ProductCatalogModel, pricing is exclusively handled through Standalone Prices.Standalone Prices
Unlike Embedded Prices, you can create Standalone Prices for Products that do not exist in the Project. In such cases, to link newly added Product Variants with a Standalone Price, both the Product Variant and Standalone Price must have the same SKU.
External Prices
Consider using external prices in the following cases:
- Pricing data exceeds the limit of
50 000Prices for a Product Variant. - Pricing data is stored externally in a Product Information Management (PIM).
In such cases, to display the Price on your storefront for a Product Variant or for a Line Item in the Cart, you would need to make API calls to the external system. Alternatively, you can also import your prices as Standalone Prices or Embedded Prices. - Pricing data is dynamic and changes frequently or is calculated on the fly based on some external values.
If pricing fluctuates frequently or is calculated based on external factors (like currency conversion rates), you need to obtain the data through API calls to the external system before displaying the prices on your storefront. - Pricing data is stored in some datastore that is colocated with your application code.
In such cases, to display Prices on your storefront or for Line Items in the Cart, you must make database calls rather than external API calls. - Pricing data is stored as Custom Objects.
Although Custom Objects are stored within commercetools API platform and you can access the data through API calls, the Prices are still considered external as your code needs to access the data when you need to display or add pricing information into the Cart. Additionally, you cannot take advantage of all the price selection logic used by Embedded and Standalone Prices.
Tiered pricing
Tiered pricing can be useful in bulk-purchasing scenarios to apply a different pricing when a certain quantity of an item is added and ordered from a cart. For example, if a product's base price is €5, when 100 items are added and ordered from the cart, a tiered Price of €3 can be used for each item. Tiered pricing is an alternate way to discount prices without using Product Discounts.
When the minimum quantity of a Price tier is reached, the Price tier is applied for the entire quantity of a Product Variant added as Line Item to a Cart. If no Price tier is found for the Order quantity, the base Price is used.
The Price tier is applied per Line Item of the Product Variant. For example, if the same Product Variant appears in the same Cart as several Line Items (which can be achieved by different values of a Custom Field on the Line Items), each Line Item must reach the minimum quantity to get the Price tier.
Both Embedded Prices and Standalone Prices provide support for tiered pricing.
Price selection
A price, for Products and Line Items, is selected based on a sequential fallback mechanism.
Fallback logic
For a given currency and recurrence policy, the platform selects a Price based on the following logic.
If no price matches a specified recurrence policy, the platform ignores this parameter and follows the sequence without it.
- Checks for a price matching the Customer Group, Channel, and country.
- Checks for a price matching the Customer Group and Channel, with no country defined for the price.
- Checks for a price matching the Customer Group and country, with no Channel defined for the price.
- Checks for a price matching the Customer Group only, with no Channel or country defined for the price.
- Checks for a price matching the Channel and country, with no Customer Group defined for the price.
- Checks for a price matching the Channel only, with no Customer Group or country defined for the price.
- Checks for a price matching the country only, with no Customer Group or Channel defined for the price.
- Checks for a price with no Customer Group, Channel, or country defined for the price.
Within each step, time-bound prices take precedence over non-time-bound prices.
The price is shown only within the validity period of the Embedded Price or Standalone Price.
Fallback logic for multiple Customer Groups
-
For Customers (B2C): the Customer Group of the Cart and the Customer Groups assigned to the Customer
-
For Business Units (B2B): the Customer Groups assigned to the Business Unit
- If the Business Unit has any Customer Groups assigned, only prices from those Customer Groups are considered during price selection.
The price selection occurs only between eligible Prices matching a priority of the fallback logic order.
If multiple prices match a priority, the cheapest Price—before Cart Discounts—is selected. If a Product Discount applies to a Product Variant, the discounted value of the Embedded Price or Standalone Price determines the cheapest price.
If multiple prices have the same value, the first Customer Group in the Customer Group assignments of the Customer or Business Unit is used.
- If the price matched from the Customer Groups assigned to the Customer and from the Customer Group of the Cart are equal, the Price matching the Customer Group of the Cart is used.
Tiered prices, if any, are ignored when selecting the lowest price for the Product Variant.
The following example shows how a price is selected if a Customer or Business Unit is a member of multiple Customer Groups:
| Customer Group | Country | Channel | Price |
|---|---|---|---|
| Alpha | USA | Zeta | $123 |
| Beta | USA | Zeta | $100 |
| Delta | * | Zeta | $99 |
| * | * | * | $23 |
According to the fallback logic, the API first checks for a price for the Customer Group, channel, and country—leaving us with $123 and $100. $100 is selected as it's the cheapest of the two prices. Since the first condition is met, the next checks in the price selection logic are ignored, although other cheaper prices exist.
Discounts
Discounts can assist in creating efficient pricing solutions for your business. For example, one best practice would be to take advantage of Product Discounts to display sale prices for your Products instead of using the available pricing solutions, which are better suited for storing base prices.
Typically, B2C business models have simple base pricing structures and rely on frequent promotional activities to drive sales. In contrast, B2B business models often have more complex pricing that involves high precision (sub-cent) prices and tiered pricing. Discounts play a less significant role in B2B as purchasing decisions are generally made by groups, reflecting a more structured decision-making process.
The following types of Discounts are available:
Product Discounts
Product Discounts can be used for product or catalog discounts to display a discounted Price for your Products before they are added to a Cart, for example, on product detail pages (PDPs) or product listing pages (PLPs).
Product Discounts are useful when creating Discounts for the following scenarios:
- Specific Products or SKUs, for example, a sale on a specific color of handbag
- Subsets of Customers, for example, a "platinum members-only" sale
- Subsets of Products, for example, a sale on all handbags or wallets
- Business-defined Attributes, for example, a sale on products by a certain designer
Only one Product Discount applies to any Price of a Product Variant at any given time. This means you can use different Product Discounts for different Product Variants within the same Product, and you can use multiple Product Discounts for the same Product Variant to offer discounts on different Prices. For example, one Product Discount with 10% off on the Product Variant Price in Euro, and another Product Discount with 20% off on the US Dollar Price of the same Product Variant.
If multiple active Product Discounts match a Price, then the sort order of the Product Discounts determines which one applies.
Cart Discounts
Cart Discounts can be used to discount different elements of a Cart, some of which include:
- A discount on any item in a cart
- A discount on the shipping cost of a cart
- A discount on a cart's total
- A 'Buy X, get Y free' discount
- A 'Buy X items, get Y of them at a discounted rate' discount. Note that you can only apply a percentage-off discount on eligible items.
For a more powerful option that lets you apply an amount, a fixed price, or percentage discount to eligible items, see Pricing and discounts APIs overview.
Cart Discounts are useful when creating Discounts for the following scenarios:
- Free shipping discounts or free shipping over a certain cart amount
- Seasonal sales for a group of products
- Membership or customer group discounts
Discount Codes
Discount Codes can be used to offer additional Cart Discounts to eligible Customers by use of unique codes during checkout. With Discount Codes, you can also control the number of times they apply on a Cart, and this limit can be configured to apply on a Customer's Cart or any Cart.
Discount Codes inherit their Store association from the Cart Discounts they reference.
Discount Codes are not ranked like Cart Discounts, but the order in which they apply on a Cart depends on the ranking of the Cart Discounts (the Discount Codes are associated to). For example, consider a scenario where the following discounts apply on a Cart:
- SUMMER SALE: a Cart Discount that discounts the Cart by €10 with a sort order of 0.05
- MYFIRSTPURCHASE: a Discount Code associated to a Cart Discount, NEW CUSTOMERS, that discounts the Cart by €5 with a sort order of 0.1
Discount Groups
A Discount Group acts as a container for multiple Cart Discounts. When used, it ensures that only the Cart Discount offering the highest savings to the Customer is applied to a Cart.
Discount Groups are useful for managing temporary campaigns or running time-sensitive promotions. For example, you can group seasonal sale promotions into a single Discount Group, and then deactivate all of them at once when the sale ends.
0.0. The Discount Group's sort order determines how the Cart Discount is applied. For how to manage Discount Groups with the API, see Pricing and discounts APIs overview.Direct Discounts
While most commonly used in B2B scenarios, Direct Discounts can also be used in B2C scenarios.
Direct Discounts are always active and valid, use the default stacking mode, and do not have a sorting order. They apply in the order in which they are listed on the Cart or Order.
By default, Direct Discounts take precedence over the other discounts on the Cart. If a Direct Discount is applied to a Cart or Order, any matching Cart Discounts in the Project are ignored, and Discount Codes cannot be added. For all three discount types to coexist, the Cart must be set so that Direct Discounts do not ignore Cart Discounts. The Direct Discounts then apply after all Cart Discounts, so they always act on prices that the Cart Discounts have already reduced.
They can also participate in best deal selection with Product Discounts and Cart Discounts when the best deal discount combination mode is used.
When the Product Discount offers the better deal, Direct Discounts are discarded since they are a form of Cart Discount. To avoid losing a negotiated reduction, the Direct Discount must be set to not participate in best deal selection. The Direct Discount is then left out of the comparison and applied on top of whichever discount type wins, including on top of a Direct Discount that took part and won.
This affects only Direct Discounts that target (Custom) Line Items. A Direct Discount that adds a Gift Line Item, or that targets the shipping cost or the Cart total price, is always applied after the best deal is selected. This setting has no effect in the stacking mode.
When the Cart is set so that Direct Discounts do not ignore Cart Discounts, and both Cart Discounts and Direct Discounts apply to the Cart, the two form a single candidate in the best deal comparison. They win or lose against the Product Discounts together.
Common discount use cases
The following table highlights how some of the most common discounts can be modeled with Product Discounts or Cart Discounts (this list is not exhaustive). Further discounting needs (such as geofencing, bulk discount codes, and stacked discounts) are also supported when combined with API Extensions.
| Use case | Description | Solution |
|---|---|---|
| Product or catalog discount | Percentage or fixed value off the original price of items matching set conditions (these use predicates and can include categories). | Product Discount |
| Product volume pricing | Reduced base Price for an item when multiple quantities of that item are purchased. | Tiered prices |
| Time window discount | Time-based discount. | Cart Discount and Product Discount |
| Tiered percentage discount by spend | Example: 10% off the Cart for customers who spend $30 or more, 15% off if they spend $50 or more, or 20% off if they spend $100 or more. | Cart Discount |
| Tiered fixed discount by spend | Example: $25 off the Cart total for customers who spend more than $150, $50 off if they spend more than $300, or $75 off if they spend more than $400. | Cart Discount |
| Discount by Discount Code | Percentage or fixed value off the Cart or a subset of Cart items when customers use a Discount Code. | Cart Discount + Discount Code |
| Buy x, get 1 free | When customers buy x items, they get one quantity of a defined item for free. | Cart Discount |
| Cart value is greater than x, get y free | When a Cart value is greater than a set target, customers get one quantity of a defined item for free. | Cart Discount |
| Website-specific promotions | A merchant may want to discount only a specific website, in the case a Project supports multiple websites. | Cart Discount |
| Bundle Product Type discount | Percentage or fixed value off the bundle to customers who purchase a custom Product Type of bundled Products. | Cart Discount and/or External Discount |
| Marketing opt-in discount | One-time fixed discount offered to customers who opt in (subscribe) for marketing emails. | Cart Discount and/or External Discount |
| Create an account discount | One-time discount for customers who sign up for an account. | Cart Discount and/or External Discount |
Discount interaction in Carts
Line item prices in a Cart can be influenced by Product Discounts and Cart Discounts, both of which impact the Cart's total.
With previous Discounts already applied, the target may already have a discounted Price. A relative Cart Discount is then calculated based on the already discounted Price.
Between Product Discounts and Cart Discounts
Stacking
In this case, both Product Discount and Cart Discounts can apply. The platform applies the Product Discount first, and then applies Cart Discounts to Line Item prices (that are already reduced by the Product Discount).
Cart Discounts are evaluated and applied in the following order:
- All discounts except discounts on Cart total price
- Discounts on Cart total price
The sort order and stacking mode are effective only among Cart Discounts within the above-mentioned targets.
Best deal
In this case, only one discount type can apply for a Line Item in a Cart. The platform calculates the cart total twice: once using the Product Discount and once using the Cart Discounts. It then applies the discount type that results in the lower cart total.
The discounts on the Cart are evaluated and applied in the following order:
- Discounts on (Custom) Line Items
- Gift Line Items
- Direct Discounts on (Custom) Line Items that do not participate in the best deal selection
- Discounts on shipping cost
- Discounts on Cart total price
The sort order and stacking mode are effective only among Cart Discounts with the above-mentioned targets.
| List price | Price after product discount | Price after cart discount | |
|---|---|---|---|
| Shirt | US$100 | US$70 | US$90 |
| Jean | US$120 | US$90 | US$60 |
| ---- | ---- | ---- | ---- |
| Total price (inclusive of all taxes) | US$160 | US$150 |
With a lower price (US$150), the Cart Discount is chosen as the best deal.
If the combination of discounts offers a better price, the Line Items' prices might increase—for example, the shirt's price will be US$90 instead of the US$70.
| List price | Price after product discount | Price after cart discount | |
|---|---|---|---|
| Shirt | US$100 | US$70 | US$60 |
| Jean | US$120 | US$90 | - |
| ---- | ---- | ---- | ---- |
| Total price (inclusive of all taxes) | US$160 | US$150 |
With a lower price (US$150), the Cart Discount is chosen as the best deal.
Since no Cart Discount applies for the jeans, the price (after Product Discount) is considered—US$90. In this case, the chosen discount type will be Cart Discount, and the Product Discount is only applied for Line Items with no Cart Discounts.
| List price | Price after product discount | Price after cart discount | |
|---|---|---|---|
| Shirt | US$100 | US$70 | US$90 |
| Custom Line Item | US$50 | - | US$45 |
| ---- | ---- | ---- | ---- |
| Total price (inclusive of all taxes) | US$120 | US$135 |
With a lower price (US$120), the Product Discount is chosen as the best deal.
Since no Product Discount applies for the Custom Line Item, the list price is considered—US$50.
| List price | Price after product discount | Price after cart discount | |
|---|---|---|---|
| Shirt | US$100 | - | US$90 |
| ---- | ---- | ---- | ---- |
| Shipping | US$0 | US$0 | |
| Total price (inclusive of all taxes) | US$90 | US$80 |
With a lower price (US$80), the Cart Discount is chosen as the best deal.
The shipping cost and discount on the total cart price is applied irrespective of the stacking mode.
| List price | Price after product discount | Price after both discounts | |
|---|---|---|---|
| Shirt | US$100 | US$70 | US$60 |
| ---- | ---- | ---- | ---- |
| Total price (inclusive of all taxes) | US$70 | US$60 |
The Product Discount wins the selection. The Direct Discount then applies to the reduced price, resulting in a total of US$60. If the Direct Discount had participated in the best deal selection, the total would be US$70 since the Direct Discount would have been discarded.
Between multiple Cart Discounts
If a Cart Discount (within a Discount Group) is associated with a Discount Code, it will be evaluated only when the code is added to the Cart, and applied if it provides the best deal.
An eligible Cart Discount that exists outside a Discount Group can still apply, based on its sort order. The sort order is unique globally across all Cart Discounts and Discount Groups.
When other Cart Discounts with different targets apply on a Cart, the Cart Total Price discount applies last, regardless of its sort order and ignoring the stacking mode that stops further discounts on the other Cart Discounts, if any. The sort order for a Cart Total Price discount only determines its ranking among other Cart Discounts targeting the Total Price. As a result, the stacking mode that stops further discounts takes effect for a Cart Total Price discount only when there are other Cart Discounts targeting the Total Price with a lower sort order.