Product Discounts

Product discounts are used to change certain product prices.

A product price can be discounted in two ways:

  • with a relative or an absolute product discount, which will be automatically applied to all prices in a product that match a discount predicate.
    A relative discount reduces the matching price by a fraction (for example 10 % off). An absolute discount reduces the matching price by a fixed amount (for example 10€ off). If more than one product discount matches a price, the discount sort order determines which one will be applied.
  • with an external product discount, which can then be used to explicitly set a discounted value on a particular product price.

The discounted price is stored in the discounted field of the Product Price.

Note that when a discount is created, updated or removed it can take up to 15 minutes to update all the prices with the discounts.

The maximum number of ProductDiscounts that can be active at the same time is 200.

ProductDiscount Predicate

The predicate offers a flexible way to define which product prices should be reduced.

Predicate Identifiers

The following field identifiers can be used in a predicate. They reference a field in a Product or a field in the Product Price.

  • product.id - UUID
  • product.key - String
  • productType.id - UUID
  • variantId - Number
  • sku - String
  • categories.id - Array of UUID
  • categoriesWithAncestors.id - Array of UUID
    Identifies categories of a product and all the ancestors of those categories. It is used to match all categories that are in a subtree of a specific category.
  • price - Money
  • amount - Number - The amount in the specified currency.
  • centAmount - Number - The amount in cents (the subunit) of the specified currency.
  • currency- String - Currency code
  • country - String - Country code
  • customerGroup.id - UUID
  • customerGroup.key - String
  • channel.id - UUID
  • attributes.<attr-name>
    Matches a product attribute by its name. Only boolean, text, number, datetime, date, time, enum and lenum attribute types are supported. The set of these types is supported also. In case of enum and lenum type attributes only the key can be used in predicates. If a field name contains a dash (-) or starts with a digit, it needs to be escaped with backticks (`), e.g., attributes.`average-count`.

Predicate Operators

The operators combine field identifiers with concrete values to construct predicates. The operators use the infix notation with the general notation field-identifier operator value (for example sku = "AB-123" where the field identifier is sku, the operator is = and the value is "AB-123"). Collection values are separated with , and enclosed in parentheses, for example categories.id = ("f6a19a23-14e3-40d0-aee2-3e612fcb1bc7", "abcd9a23-14e3-40d0-aee2-3e612fcbefgh").

  • simple field with simple value or collection field with collection value: =, !=
  • simple field with simple value: >, >=, <, <=
  • simple field: is defined, is not defined,
  • simple field with collection value: in, not in
  • collection field: is empty, is not empty
  • collection field with simple value: contains
  • collection field with collection value: contains all, contains any
  • logical operators: and, or, not
    Parentheses are used to nest logical operators.

Predicate Examples

// match a specific variant in the specific product
product.id = "f6a19a23-14e3-40d0-aee2-3e612fcb1bc7" and variant.id = 1

//match a product that is in the given category
categories.id contains "f6a19a23-14e3-40d0-aee2-3e612fcb1bc7"

//match a product that is in all of the the given categories
categories.id contains all ("f6a19a23-14e3-40d0-aee2-3e612fcb1bc7", "abcd9a23-14e3-40d0-aee2-3e612fcbefgh")

//match a product that is in one of the the given categories
categories.id contains any ("f6a19a23-14e3-40d0-aee2-3e612fcb1bc7", "abcd9a23-14e3-40d0-aee2-3e612fcbefgh")

//match a product that is in the two given categories and in no others
categories.id = ("f6a19a23-14e3-40d0-aee2-3e612fcb1bc7", "abcd9a23-14e3-40d0-aee2-3e612fcbefgh")

//match a product that is not in a given category
categories.id != ("f6a19a23-14e3-40d0-aee2-3e612fcb1bc7")

//match the prices above 12€ for any countries except France that do not have a customer group set
centAmount > 1200 and currency = "EUR" and country != "FR" and customerGroup.id is not defined

//match all product variants that have size "L" and have the color white and black   
//size is an EnumType attribute for which the key is specified in the predicate,
//color is a SetType of Enums for which the keys are listed in the predicate.
attributes.size = "L" and attributes.colors contains all ("black", "white")

//match all product variants with the given sku, the boolean attribute available set to true and the number attribute weight less than 100
sku = "AB-12" and attributes.available = true and attributes.weight < 100

//match all products that are in the given category or in a category that is a descendant of the given category
categoriesWithAncestors.id contains "abcd9a23-14e3-40d0-aee2-3e612fcbefgh"

Representations

ProductDiscount

  • id - String
    The unique ID of the product discount
  • version - Number
    The current version of the product discount.
  • createdAt - DateTime
  • lastModifiedAt - DateTime
  • name - LocalizedString
  • description - LocalizedString - Optional
  • value - ProductDiscountValue
  • predicate - String
    A valid ProductDiscount Predicate.
  • sortOrder - String
    The string contains a number between 0 and 1. A discount with greater sortOrder is prioritized higher than a discount with lower sortOrder. A sortOrder must be unambiguous.
  • isActive - Boolean
    Only active discount will be applied to product prices.
  • validFrom - DateTime - Optional
    The time from which the discount should be effective. Please take Eventual Consistency into account for calculated product discount values.
  • validUntil - DateTime - Optional
    The time from which the discount should be ineffective. Please take Eventual Consistency into account for calculated undiscounted values.
  • references - Array of Reference
    The platform will generate this array from the predicate. It contains the references of all the resources that are addressed in the predicate.

ProductDiscountDraft

  • name - LocalizedString
  • description - LocalizedString - Optional
  • value - ProductDiscountValue
  • predicate - String
    A valid ProductDiscount Predicate.
  • sortOrder - String
    The string must contain a decimal number between 0 and 1. A discount with greater sortOrder is prioritized higher than a discount with lower sortOrder.
  • isActive - Boolean
    If set to true the discount will be applied to product prices.
  • validFrom - DateTime - Optional
    The time from which the discount should be effective. Please take Eventual Consistency into account for calculated product discount values.
  • validUntil - DateTime - Optional
    The time from which the discount should be effective. Please take Eventual Consistency into account for calculated undiscounted values.

ProductDiscountValue

Defines discount type with the corresponding value. The type can be relative, absolute or external.

Relative

  • type - relative
  • permyriad - Number
    Per ten thousand. The fraction the price is reduced. 1000 will result in a 10% price reduction.

Absolute

  • type - absolute
  • money - Array of Money
    The array contains money values in different currencies. An absolute ProductDiscount will only match a price if this array contains a value with the same currency. If it contains 10€ and 15$, for example, the matching € price will be decreased by 10€ and the matching $ price will be decreased by 15$.

External

  • type - external

The external discount is used by the setDiscountedPrice update action and enables the client to explicitly set a discounted value for a particular price.

Get ProductDiscount by ID

Endpoint: /{projectKey}/product-discounts/{id}
Method: GET
OAuth2 Scopes: view_products:{projectKey}
Response Representation: ProductDiscount

Query ProductDiscounts

Endpoint: /{projectKey}/product-discounts
Method: GET
OAuth2 Scopes: view_products:{projectKey}
Response Representation: PagedQueryResult with the results array of ProductDiscount
Query Parameters:

Create a ProductDiscount

Endpoint: /{projectKey}/product-discounts
Method: POST
OAuth2 Scopes: manage_products:{projectKey}
Request Representation: ProductDiscountDraft
Response Representation: ProductDiscount

Update ProductDiscount

Endpoint: /{projectKey}/product-discounts/{id}
Method: POST
OAuth2 Scopes: manage_products:{projectKey}
Response Representation: ProductDiscount
Fields:

  • version - Number - Required
    The expected version of the ProductDiscount on which the changes should be applied. If the expected version does not match the actual version, a 409 Conflict will be returned.
  • actions - Array of UpdateAction - Required
    The list of update actions to be performed on the ProductDiscount.

Update Actions
Please find below the individual update actions provided on this endpoint.


Change Value

Change Predicate

Change Is Active

  • action - String - "changeIsActive"
  • isActive - Boolean

Set Valid From

  • action - String - "setValidFrom"
  • validFrom - DateTime - Optional
    The time from which the discount should be effective. Please take Eventual Consistency into account for calculated product discount values.

Set Valid Until

  • action - String - "setValidUntil"
  • validUntil - DateTime - Optional
    The time from which the discount should be ineffective. Please take Eventual Consistency into account for calculated undiscounted values.

Change Name

Set Description

  • action - String - "setDescription"
  • description - LocalizedString - Optional

Change Sort Order

  • action - String - "changeSortOrder"
  • sortOrder - String
    The string must contain a number between 0 and 1. A discount with greater sortOrder is prioritized higher than a discount with lower sortOrder.

Delete ProductDiscount

Endpoint: /{projectKey}/product-discounts/{id}
Method: DELETE
OAuth2 Scopes: manage_products:{projectKey} Query Parameters:

  • version - Number - Required