# Pricing and discounts overview 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](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#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](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#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](https://docs.commercetools.com/learning-price-and-discount-your-products/price-calculation/best-practices.md). ### Types of Prices Two ways of storing your product prices are available. The prices can be [embedded](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#embedded-prices) in the Product Variants or stored separately as [standalone entities](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#standalone-prices). 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. The `priceMode` of a [Product](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AProduct) determines the type of Price used for [price Selection](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#price-selection). #### Embedded Prices Embedded Prices are stored within a [ProductVariant](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AProductVariant), and are associated to it through its `prices` field. With Embedded Prices, you can store up to 100 Prices for each Product Variant. For more flexibility with pricing your products with higher limits, see [Standalone Prices](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#standalone-prices). When using Embedded Prices, keep the JSON document size in mind. A Product and all its Prices are stored in a single JSON document. As Price count and Product Type complexity grow, you may approach the document size limit. Embedded Prices are managed and queried using the [Products API](https://docs.commercetools.com/api/projects/products.md). You can add Prices when [creating a Product](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Aendpoint%3A%2F%7BprojectKey%7D%2Fproducts%3APOST), or manage Prices of an existing Product using the [Add Price](https://docs.commercetools.com/api/projects/products.md#add-price), [Set Prices](https://docs.commercetools.com/api/projects/products.md#set-prices), [Change Price](https://docs.commercetools.com/api/projects/products.md#change-price), or [Remove Price](https://docs.commercetools.com/api/projects/products.md#remove-price) update actions. Changes to Embedded Prices can be staged before being published to the current representation of a [Product](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AProduct). Embedded Prices are only available in the `Classic` [ProductCatalogModel](https://docs.commercetools.com/api/projects/project.md#productcatalogmodel) . In the `Modular` [ProductCatalogModel](https://docs.commercetools.com/api/projects/project.md#productcatalogmodel) , pricing is exclusively handled through [Standalone Prices](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#standalone-prices). #### Standalone Prices Standalone Prices are not embedded within a Product Variant, but are standalone resources that are associated to a [ProductVariant](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AProductVariant) through its `sku` field. With Standalone Prices, you can store up to 50000 Prices for each Product Variant. Standalone Prices are managed and queried using the [Standalone Prices API](https://docs.commercetools.com/api/projects/standalone-prices.md), independent from your Products, thus contributing to better query performance. Changes to Standalone Prices can be staged with [StagedStandalonePrice](https://docs.commercetools.com/api/projects/standalone-prices.md#stagedstandaloneprice) before being published. #### External Prices External prices are stored and maintained in a third-party external system, except when using [Custom Objects](https://docs.commercetools.com/api/projects/custom-objects.md) for storing your pricing data. Since external prices are not part of the product catalog, they are not available on the [Product Search API](https://docs.commercetools.com/api/projects/product-search.md) as well as the [Product Projection Search API](https://docs.commercetools.com/api/projects/product-projection-search.md) for filtering, faceting, or sorting products by price. You can set an external price for the Line Item when [creating](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Aendpoint%3A%2F%7BprojectKey%7D%2Fcarts%3APOST) or updating a Cart using the following actions: [Add LineItem](https://docs.commercetools.com/api/projects/carts.md#add-lineitem), [Remove LineItem](https://docs.commercetools.com/api/projects/carts.md#remove-lineitem), [Change LineItem Quantity](https://docs.commercetools.com/api/projects/carts.md#change-lineitem-quantity), [Set LineItem Price](https://docs.commercetools.com/api/projects/carts.md#set-lineitem-price), or [Set LineItem TotalPrice](https://docs.commercetools.com/api/projects/carts.md#set-lineitem-totalprice). If the LineItem's `priceMode` is `ExternalPrice`, set the `externalPrice` value. The `totalPrice` of the LineItem is automatically calculated by multiplying the `externalPrice` by the quantity. If the LineItem's `priceMode` is `ExternalTotal`, set the `externalTotalPrice` value (unit price multiplied by the quantity). The `totalPrice` of the LineItem is set from the value defined in `externalTotalPrice`. Your code should be able to find the correct prices to display on your storefront and set the Line Item price when it's added to a Cart. Consider using external prices in the following cases: - Pricing data exceeds the limit of 50000 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](https://docs.commercetools.com/api/import-export//import-requests.md#for-standalone-prices) or [Embedded Prices](https://docs.commercetools.com/api/import-export/import-requests.md#for-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](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#price-selection) 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 [PriceTier](https://docs.commercetools.com/api/types.md#pricetier) `minimumQuantity` is reached, the Price tier is applied for the entire quantity of a Product Variant [added as Line Item](https://docs.commercetools.com/api/projects/carts.md#add-lineitem) 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. Both types of price selection add the additional `price` field to the [ProductVariant](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AProductVariant) and [LineItem](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ALineItem) respectively in API responses. The `price` field is not populated for [ShoppingListLineItem](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AShoppingListLineItem) because price selection is not supported in the Shopping List context. - Product price selection: When displaying a price on a product detail page, the `price` is determined by the [Product Projections API](https://docs.commercetools.com/api/projects/productProjections.md) and the [Product Projection Search API](https://docs.commercetools.com/api/projects/product-projection-search.md#with-get) based on the following parameters: - `priceCurrency`: maps to `value.currencyCode` of [Price](https://docs.commercetools.com/api/types.md#price) or [StandalonePrice](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AStandalonePrice) - `priceCustomerGroup`: maps to `customerGroup` of Price or StandalonePrice - `priceChannel`: maps to `channel` of Price or StandalonePrice - `priceCountry`: maps to `country` of Price or StandalonePrice - `priceRecurrencePolicy`: maps to `recurrencePolicy` of Price or StandalonePrice - `priceCustomerGroupAssignments`: maps to `customerGroup` of Price or StandalonePrice. For more information, see [Fallback logic for multiple Customer Groups](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#fallback-logic-for-multiple-customer-groups). [Product Projection Search](https://docs.commercetools.com/api/projects/product-projection-search.md) does not support multiple Customer Group prices. The returned [ProductVariant](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AProductVariant) `price` field—added in API responses—contains the Price that matches most of the Price-selection parameters. - Line Item price selection: When you [create a Cart](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Aendpoint%3A%2F%7BprojectKey%7D%2Fcarts%3APOST) or [add a LineItem to a Cart](https://docs.commercetools.com/api/projects/carts.md#add-lineitem), the `price` is determined by the Carts API based on the following parameters: - [Cart](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACart) `currency`: maps to `value.currencyCode` of [Price](https://docs.commercetools.com/api/types.md#price) or [StandalonePrice](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AStandalonePrice) - Cart `customerGroup`: maps to `customerGroup` of Price or StandalonePrice - [LineItemDraft](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ALineItemDraft) `distributionChannel`: maps to `channel` of Price or StandalonePrice - Cart `country`: maps to `country` of Price or StandalonePrice - [Customer](https://docs.commercetools.com/api/projects/customers.md) `customerGroupAssignments`: maps to `customerGroup` of Price or StandalonePrice. For more information, see [Fallback logic for multiple Customer Groups](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#fallback-logic-for-multiple-customer-groups). - [Business Unit](https://docs.commercetools.com/api/projects/business-units.md) `customerGroupAssignments`: maps to `customerGroup` of Price or StandalonePrice. For more information, see [Fallback logic for multiple Customer Groups](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#fallback-logic-for-multiple-customer-groups). Both `businessUnit.customerGroupAssignments` and `cart.businessUnit` fields must be defined (non-null) for B2B-specific prices to apply on the cart; otherwise, the platform selects B2C-specific prices. 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 (with `validFrom` and `validUntil`) take precedence over non-time-bound prices. The price is shown only when the timestamp of the request is within `validFrom` and `validUntil` range of [Embedded Price](https://docs.commercetools.com/api/types.md#price) or [StandalonePrice](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AStandalonePrice). If the Price has [PriceTier](https://docs.commercetools.com/api/types.md#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](https://docs.commercetools.com/api/customers-overview.md#customer-groups), eligible Customer Groups for price selection are determined from the following fields: - For Customers (B2C): [Cart](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACart) `customerGroup` and [Customer](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACustomer) `customerGroupAssignments` - For Business Units (B2B): [BusinessUnit](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ABusinessUnit) `customerGroupAssignments` - If the field includes any Customer Groups, only prices from those Customer Groups are considered during price selection. - If the field is an empty list (`[]`), the base price applies as no Customer Group-specific prices are available. - If the field is not set, the Cart `customerGroup` and Customer `customerGroupAssignments` fields are used (as a fallback) to determine eligible Customer Groups, provided the Cart has a `customerId`. If no `customerId` is set, the base price applies. 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 [Price](https://docs.commercetools.com/api/types.md#prices) `discounted` or [StandalonePrice](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AStandalonePrice) `discounted` field determines the cheapest price. If multiple prices have the same value, the first Customer Group in the [Customer](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACustomer) or [BusinessUnit](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ABusinessUnit) `customerGroupAssignments` array is used. - If the price matched from the Customer `customerGroupAssignments` and Cart `customerGroup` fields are equal, the Price matching the Cart `customerGroup` 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: (a CSV formatted table follows. The first line are the column names.) 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. ### Scoped Price search External prices cannot be used in the Product Projection Search endpoint for filtering, faceting, or sorting. Scoped Price search—that includes [filter](https://docs.commercetools.com/api/projects/product-projection-search.md#filter-by-scoped-price), [facet](https://docs.commercetools.com/api/projects/product-projection-search.md#facets), and [sort](https://docs.commercetools.com/api/projects/product-projection-search.md#sort-by-scoped-price) options—only works with [Embedded Prices](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#embedded-prices). Using these options on Products with `Standalone` [ProductPriceMode](https://docs.commercetools.com/api/projects/products.md#productpricemode) yields inconsistent results, as only Embedded Prices are taken into account. You can use the [Price-selection parameters](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#product-price-selection) on the [Product Projection Search](https://docs.commercetools.com/api/projects/product-projection-search.md#product-projection-search) endpoint to search for a Price with the exact scope as specified with the Price-selection parameters. In case of a full match—where a Price matching all Price-selection parameters provided with the search request exists—the [ProductVariants](https://docs.commercetools.com/api/projects/products.md#productvariant) returned with the search result contains the `scopedPrice` field. In case of a partial match, this field is not present. Scoped Price search does not have a fallback behavior, and does not take the Price validity dates into consideration. To ensure only Products with valid Prices are returned, [remove Prices](https://docs.commercetools.com/api/projects/products.md#remove-price) that are no longer valid. For Prices to become valid at a later time, do not [publish](https://docs.commercetools.com/api/projects/products.md#publish) them before their `validFrom` date, and [search](https://docs.commercetools.com/api/projects/product-projection-search.md#product-projection-search) for the [current](https://docs.commercetools.com/api/projects/productProjections.md#current--staged) Product Projection. To illustrate the difference to [price selection](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#product-price-selection), consider a Product Variant with two [Embedded Prices](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#embedded-prices) defined: - Embedded Price 1 with `country`: `US`, `value`: \{`centAmount`: `1000`, `currencyCode`: `USD`} - Embedded Price 2 with `country`: `US`, `value`: \{`centAmount`: `800`, `currencyCode`: `USD`}, `customerGroup`: `B2B` Consider that the Price-selection parameters, `priceCountry`: `US` and `priceCustomerGroup`: `B2C`, are provided in the [Product Projection Search](https://docs.commercetools.com/api/projects/product-projection-search.md#product-projection-search) request. Since these Price-selection parameters only match partially, the [ProductVariant](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AProductVariant) only contains the `price` field with 'Embedded Price 1' defined for the Product Variant, and not the `scopedPrice` field. 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). 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 [ProductDiscount](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AProductDiscount) `sortOrder` determines which one applies. Product Discounts apply to both [Embedded Prices](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#embedded-prices) and [Standalone Prices](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#standalone-prices). They are evaluated and applied to both the current and staged representations of a price. - For Embedded Prices, the discounted value is stored in the [Price](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3APrice) `discounted` field. - For Standalone Prices, the discounted value is stored in the [StandalonePrice](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AStandalonePrice) and [StagedStandalonePrice](https://docs.commercetools.com/api/projects/standalone-prices.md#stagedstandaloneprice) `discounted` fields. Product Discounts are managed and queried using the [Product Discounts API](https://docs.commercetools.com/api/projects/productDiscounts.md). 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. To use external discounts, set the [ProductDiscountDraft](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AProductDiscountDraft) `value` to `external`. ### 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 with [CartDiscountLineItemsTarget](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACartDiscountLineItemsTarget) or [CartDiscountCustomLineItemsTarget](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACartDiscountCustomLineItemsTarget) - A discount on the shipping cost of a cart with [CartDiscountShippingCostTarget](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACartDiscountShippingCostTarget) - A discount on a cart's total with [CartDiscountTotalPriceTarget](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACartDiscountTotalPriceTarget) - A 'Buy X, get Y free' discount with [CartDiscountValueGiftLineItemDraft](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACartDiscountValueGiftLineItemDraft) - A 'Buy X items, get Y of them at a discounted rate' discount with [MultiBuyLineItemsTarget](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AMultiBuyLineItemsTarget) or [MultiBuyCustomLineItemsTarget](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AMultiBuyCustomLineItemsTarget). Note that you can only apply a percentage-off discount on eligible items. You can also use [CartDiscountPatternTarget](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACartDiscountPatternTarget). It is a more powerful option and lets you apply an amount, a fixed price, or percentage discount to eligible items. Cart Discounts are recalculated every time a [Discount Code](https://docs.commercetools.com/api/projects/discountCodes.md), [LineItem](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ALineItem), or [CustomLineItem](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACustomLineItem) is added or removed from a [Cart](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACart), or when an [Order is created from a Cart](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Aendpoint%3A%2F%7BprojectKey%7D%2Forders%3APOST). Unlike Product Discounts, multiple Cart Discounts can apply on a Cart at any given time, but in a ranked order. This includes [Discount Codes](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#discount-codes) applied during checkout, which are associated with Cart Discounts. You can avoid applying further Cart Discounts to the Cart by setting the `stackingMode` to `StopAfterThisDiscount` on the [CartDiscount](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACartDiscount) that must be applied last. 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](https://docs.commercetools.com/api/projects/carts.md#cart) that belong to one of the Stores referenced in the [CartDiscount](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACartDiscount) `stores` array. If the array is empty or unspecified, the Discount applies (globally) to all Carts. To apply a Cart Discount to only a single Cart or Order, you can use [Direct Discounts](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#direct-discounts). Cart Discounts are managed and queried using the [Cart Discounts API](https://docs.commercetools.com/api/projects/cartDiscounts.md). #### 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 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 [CartDiscount](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACartDiscount) `sortOrder` of 0.05 - MYFIRSTPURCHASE: a Discount Code associated to a Cart Discount, NEW CUSTOMERS, that discounts the Cart by €5 with a [CartDiscount](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACartDiscount) `sortOrder` of 0.1 Thus, based on the `sortOrder`, NEW CUSTOMERS is prioritized before SUMMER SALE, and a discount of €5 is applied first, followed by €10. Discount Codes are managed and queried using the [Discount Codes API](https://docs.commercetools.com/api/projects/discountCodes.md). ### 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. You can only group Cart Discounts if they are not specific to a Store and they target Line Items (that is, CartDiscounts with `target` as `lineItems`, `customLineItems`, `multiBuyLineItems`, `multiBuyCustomLineItems`, or `pattern`). 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. To remove a Cart Discount from a Discount Group, use the [Set DiscountGroup](https://docs.commercetools.com/api/projects/cartDiscounts.md#set-discountgroup) action and set the sort order for the Cart Discount again. Discounts Groups are managed and queried using the [Discount Groups API](https://docs.commercetools.com/api/projects/discount-groups.md). ### 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. (a CSV formatted table follows. The first line are the column names.) 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 ### 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. To update or add Direct Discounts to an Order, use the [Set DirectDiscounts](https://docs.commercetools.com/api/projects/order-edits.md#set-directdiscounts) update action. Direct Discounts are always active and valid, use the default [StackingMode](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AStackingMode) `Stacking`, and do not have a sorting order. They apply in the order listed in the `directDiscounts` array of the Cart or Order. Direct Discounts and Discount Codes are mutually exclusive. If a Direct Discount is applied to a Cart or Order, any matching Cart Discounts in the Project are ignored. ## 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](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#between-product-discounts-and-cart-discounts) and [between multiple Cart Discounts](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#between-multiple-cart-discounts). ### Between Product Discounts and Cart Discounts At the Project level, you can [configure](https://docs.commercetools.com/api/projects/project.md#set-discounts-configuration) whether both Product Discounts and Cart Discounts apply to a Line Item in a Cart ([stacking](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#stacking)), or only one of them ([best deal](https://docs.commercetools.com/api/pricing-and-discounts-overview.md#best-deal)). In the `BestDeal` [DiscountCombinationMode](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ADiscountCombinationMode), 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. The discount combination mode for a [Cart](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3ACart) and for an [Order](https://docs.commercetools.com/urn?urn=ctp%3Aapi%3Atype%3AOrder) is indicated in the `discountTypeCombination` field. #### 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 (CartDiscountTotalPriceTarget) 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 Cart Discounts are evaluated and applied in the following order: 1. Discounts on (Custom) Line Items (CartDiscountLineItemsTarget, CartDiscountCustomLineItemsTarget, MultiBuyLineItemsTarget, MultiBuyCustomLineItemsTarget, or CartDiscountPatternTarget) 2. Gift Line Items 3. Discounts on shipping cost (CartDiscountShippingCostTarget) 4. Discounts on Cart total price (CartDiscountTotalPriceTarget) 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. (a CSV formatted table follows. The first line are the column names.) ,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. 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. (a CSV formatted table follows. The first line are the column names.) ,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 `chosenDiscountType` will be `CartDiscount`, 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. (a CSV formatted table follows. The first line are the column names.) ,List price,Price after product discount,Price after cart discount Shirt,US$100,US$70,US90 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. Example 4: A 10% discount applies on all (Custom) Line Items in a Cart (StackingMode: StopAfterThisDiscount) in addition to free shipping and US$10 discount on the total price of the cart. (a CSV formatted table follows. The first line are the column names.) ,List price,Price after product discount,Price after cart discount Shirt,US$100,-,US90 \----,----,----,---- 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. ### 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](https://docs.commercetools.com/api/projects/discount-groups.md). 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. ## 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](https://docs.commercetools.com/api/customers-overview.md#customer-specific-products-prices-and-discounts). Additionally, as Buyers, Customers can also negotiate prices with a Seller using Quotes. For more information, see [Quotes overview](https://docs.commercetools.com/api/quotes-overview.md). Learn more about discounts in our self-paced Product Discounts and Cart Discounts modules. ## Related pages - [Section overview page](https://docs.commercetools.com/api.md) - [Next page: Standalone Prices](https://docs.commercetools.com/api/projects/standalone-prices.md)