Pricing and discounts overview

Ask about this Page
Copy for AI
View as Markdown

Overview of the concepts related to product pricing and discounts.

Pricing

A Price represents the purchase value of a Product Variant, or SKU, in a specific currency. The uniqueness of a Price is determined by the price scope (currency, country, Customer Groups, or Channels) assigned to it, and only one Price can exist for a price scope.
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.
In addition to the above, based on your business case, you can use discounts to add flexibility to your product pricing—such as for temporary promotion campaigns. Discounts reduce your effort in using and maintaining discounted and base prices as they can be deactivated when the promotion ends.
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.
To create an efficient Price model, follow our best practices.

Types of Prices

Two ways of storing your product prices are available. The prices can be embedded in the Product Variants or stored separately as standalone entities. Although a Product can have both types of Prices at the same time, we recommend having only one type of Price for a Product for better performance. For how to set the type of Price used by a Product with the API, see Pricing and discounts APIs overview.

Embedded Prices

Embedded Prices are stored within a Product Variant. For how to manage Embedded Prices with the API, see Pricing and discounts APIs overview. For the limits that apply to Embedded Prices, see Limits.

Changes to Embedded Prices can be staged before being published to the current representation of a Product.

Embedded Prices are only available in the Classic ProductCatalogModel. In the Modular ProductCatalogModel, pricing is exclusively handled through Standalone Prices.

Standalone Prices

Standalone Prices are not embedded within a Product Variant, but are standalone resources that are associated to a Product Variant through its SKU. For how to manage Standalone Prices with the API, see Pricing and discounts APIs overview. For the limits that apply to Standalone Prices, see Limits.

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.

Changes to Standalone Prices can be staged with StagedStandalonePrice before being published.

External Prices

External prices are stored and maintained in a third-party external system, except when using Custom Objects for storing your pricing data. For how to work with external prices with the API, see Pricing and discounts APIs overview.

Consider using external prices in the following cases:

  • Pricing data exceeds the limit of 50 000 Prices 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

Although you can specify product prices with different price scopes to serve all customers, you would want the most suitable price selected for your customer. The price displayed on a product detail page is determined using the product price selection parameters, and the price calculated on a Cart is determined using the line item price selection parameters.
For the query parameters used for Product price selection, see Product Projections. For the fields used for Line Item price selection, and how to read the selected Price in API responses, see Pricing and discounts APIs overview.

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.

  1. Checks for a price matching the Customer Group, Channel, and country.
  2. Checks for a price matching the Customer Group and Channel, with no country defined for the price.
  3. Checks for a price matching the Customer Group and country, with no Channel defined for the price.
  4. Checks for a price matching the Customer Group only, with no Channel or country defined for the price.
  5. Checks for a price matching the Channel and country, with no Customer Group defined for the price.
  6. Checks for a price matching the Channel only, with no Customer Group or country defined for the price.
  7. Checks for a price matching the country only, with no Customer Group or Channel defined for the price.
  8. 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.

If the Price has PriceTier, the Price tier valid for the Line Item quantity is selected. However, the tiered price will be ignored if the Price is already discounted (by a Product Discount). If no Price tier can be used, the base Price is used.

Fallback logic for multiple Customer Groups

When using multiple Customer Groups, eligible Customer Groups for price selection are determined from the following:
  • 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.
For how eligible Customer Groups are determined when a Business Unit has no Customer Groups assigned, see Pricing and discounts APIs overview.

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 GroupCountryChannelPrice
AlphaUSAZeta$123
BetaUSAZeta$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.

For how to search for Prices with an exact price scope with the API, see Pricing and discounts APIs overview.
Learn more about pricing in our self-paced Price calculation and Set static Prices modules.

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.

Product Discounts apply to both Embedded Prices and Standalone Prices. They are evaluated and applied to both the current and staged representations of a price. For how to read the discounted value of a Price with the API, see Pricing and discounts APIs overview.
For cases where the base prices are stored externally or when the built-in discounting logic cannot support your requirements, you can use external discounts. In these cases, the discounts are calculated by an external system and you need to set the discounted amounts via the API. For how to manage Product Discounts and external discounts with the API, see Pricing and discounts APIs overview.

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.
A Gift Line Item is automatically added to the Cart when a Discount Predicate evaluates as true.
If the gift Line Item becomes invalid (for example when the referenced Product, Product Variant, or Channel has been deleted) since creation, or if a Price cannot be selected for a Cart, the Discount does not apply to the Cart.
For which Cart Discount targets ignore Gift Line 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
For when Cart Discounts are recalculated, see Pricing and discounts APIs overview.
Unlike Product Discounts, multiple Cart Discounts can apply on a Cart at any given time, but in a ranked order. This includes Discount Codes applied during checkout, which are associated with Cart Discounts. You can avoid applying further Cart Discounts to the Cart by setting the stacking mode of the Cart Discount that must be applied last to stop further discounts.
The stacking mode does not control free shipping above a cart value as defined on a Shipping Rate. To avoid unwanted scenarios, we highly recommend not using Cart Discounts on shipping cost and free shipping above a cart value together.
Cart Discounts can be defined globally for a Project, or be specific to one or more Stores in a Project. In the latter case, the Discount is only applied to Carts that belong to one of the Stores of the Cart Discount. If the Cart Discount has no Stores, the Discount applies (globally) to all Carts. To apply a Cart Discount to only a single Cart or Order, you can use Direct Discounts.
For how to manage Cart Discounts with the API, see Pricing and discounts APIs overview.

Discount Codes

Discount Codes, also known as promo codes or coupon codes, are alphanumeric sequences of characters offered to specific Customers to receive a Cart Discount. The related discount is applied as soon as the Discount Code is added to a Customer's Cart.

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
Thus, based on the sort order, NEW CUSTOMERS is prioritized before SUMMER SALE, and a discount of €5 is applied first, followed by €10.
For how to manage Discount Codes with the API, see Pricing and discounts APIs overview.

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.

You can only group Cart Discounts if they are not specific to a Store and they target Line Items. For which Cart Discount targets count as targeting Line Items, see Pricing and discounts APIs overview. Cart Discounts with a Gift Line Item value cannot be used in Discount Groups.
When a Cart Discount belongs to a Discount Group, its individual sort order is treated as 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

Direct Discounts are Cart Discounts applied directly to a single Cart or Order, rather than applying automatically to all eligible Carts in a Project. They can also be applied on Quotes, where they are only valid for that Quote.

While most commonly used in B2B scenarios, Direct Discounts can also be used in B2C scenarios.

When an Order is created from a Cart, the Direct Discounts from the Cart are applied to the Order. For how to update or add Direct Discounts on an Order with the API, see Pricing and discounts APIs overview.

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 caseDescriptionSolution
Product or catalog discountPercentage or fixed value off the original price of items matching set conditions (these use predicates and can include categories).Product Discount
Product volume pricingReduced base Price for an item when multiple quantities of that item are purchased.Tiered prices
Time window discountTime-based discount.Cart Discount and Product Discount
Tiered percentage discount by spendExample: 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 spendExample: $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 CodePercentage 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 freeWhen customers buy x items, they get one quantity of a defined item for free.Cart Discount
Cart value is greater than x, get y freeWhen a Cart value is greater than a set target, customers get one quantity of a defined item for free.Cart Discount
Website-specific promotionsA merchant may want to discount only a specific website, in the case a Project supports multiple websites.Cart Discount
Bundle Product Type discountPercentage 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 discountOne-time fixed discount offered to customers who opt in (subscribe) for marketing emails.Cart Discount and/or External Discount
Create an account discountOne-time discount for customers who sign up for an account.Cart Discount and/or External Discount
For worked examples of Buy and Get discounts, see Cart Discounts.

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.

Discounts can interact in a Cart in two ways: between Product Discounts and Cart Discounts and between multiple Cart Discounts.

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

At the Project level, you can configure whether both Product Discounts and Cart Discounts apply to a Line Item in a Cart (stacking), or only one of them (best deal). In the best deal discount combination mode, Product Discounts and Cart Discounts can both be present on the same Cart, but only one discount type applies per Line Item. The platform can select the discount type that leads to the lowest cart total and offers the highest savings for the Customer. For how to read the discount combination mode of a Cart or Order with the API, see Pricing and discounts APIs overview.

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:

  1. All discounts except discounts on Cart total price
  2. 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:

  1. Discounts on (Custom) Line Items
  2. Gift Line Items
  3. Direct Discounts on (Custom) Line Items that do not participate in the best deal selection
  4. Discounts on shipping cost
  5. Discounts on Cart total price

The sort order and stacking mode are effective only among Cart Discounts with the above-mentioned targets.

Example 1: A product discount of US$30 applies to all shirts and jeans. Additionally, a cart discount of US$10 applies to all shirts, while a 50% discount applies to all jeans.
List pricePrice after product discountPrice after cart discount
ShirtUS$100US$70US$90
JeanUS$120US$90US$60
----------------
Total price (inclusive of all taxes)US$160US$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.

Example 2: A product discount of US$30 applies to all shirts and jeans. Additionally, a cart discount of US$40 applies to all shirts.
List pricePrice after product discountPrice after cart discount
ShirtUS$100US$70US$60
JeanUS$120US$90-
----------------
Total price (inclusive of all taxes)US$160US$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.

Example 3: A product discount of US$30 applies to all shirts. Additionally, a 10% cart discount applies on all (Custom) Line Items.
List pricePrice after product discountPrice after cart discount
ShirtUS$100US$70US$90
Custom Line ItemUS$50-US$45
----------------
Total price (inclusive of all taxes)US$120US$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.

Example 4: A 10% discount applies on all (Custom) Line Items in a Cart (with a stacking mode that stops further discounts) in addition to free shipping and US$10 discount on the total price of the cart.
List pricePrice after product discountPrice after cart discount
ShirtUS$100-US$90
----------------
ShippingUS$0US$0
Total price (inclusive of all taxes)US$90US$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.

Example 5: A product discount of US$30 applies to all shirts. A direct discount of US$10 also applies to all shirts, but it does not participate in the best deal selection.
List pricePrice after product discountPrice after both discounts
ShirtUS$100US$70US$60
----------------
Total price (inclusive of all taxes)US$70US$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

You can also configure to apply only one Cart Discount (offering the best deal), when multiple Cart Discounts are eligible. To achieve this, you must group the Cart Discounts into a Discount Group.

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.

Customer-specific pricing and discounts

You can also define prices and discounts specific to Customers using Customer Groups or Business Units. For more information, see Customer-specific products and prices.
Additionally, as Buyers, Customers can also negotiate prices with a Seller using Quotes. For more information, see Quotes overview.
For how to work with Prices and Discounts with the API, see Pricing and discounts APIs overview.
Learn more about discounts in our self-paced Product Discounts and Cart Discounts modules.