All Release Notes

Introduced Standalone Prices in Beta

9 May 2022
Composable Commerce
HTTP API
New feature
Pricing and DiscountsCartsProduct catalogGraphQL

The Standalone Prices feature provides an alternative way to store your product prices as standalone resources. In comparison to prices embedded inside the Product, this new approach allows increasing the limit of prices per ProductVariant from 100 to 50.000. It also brings a more flexible way to query and manage your prices, separately from your Products, which contributes to better query performance.

The feature allows you to manage and query Standalone Prices through the Standalone Prices API, and to associate them to a ProductVariant via SKU. Additionally, a new priceMode has been introduced on the Product that controls whether the Prices of the ProductVariants are embedded into the Product resource or stored separately as Standalone Prices.

Please note that currently it is not possible to use filters, facets, and sorting on Standalone Prices via the Product Projection Search endpoint.

Read more on Standalone Prices and how to use them in the API reference.

Changes:

  • [API] Added Standalone Prices API.
  • [API] Added view_standalone_prices and manage_standalone_prices OAuth scopes.
  • [API] Added optional field priceMode to Product and ProductDraft.
  • [API] Added Set PriceMode update action to Product.
  • [API] Added DuplicateStandalonePriceScope and OverlappingStandalonePriceValidity 400 Bad Request errors specific to Standalone Prices.
  • [GraphQL API] Added the following types to the GraphQL schema: ChangeStandalonePriceValue, CreateStandalonePrice, PriceMode, SetProductPriceMode, SetStandalonePriceCustomFields, StandalonePrice, StandalonePriceCustomField, StandalonePriceQueryResult, StandalonePriceUpdateAction.
  • [GraphQL API] Changed the Query type:
    • Added the standalonePrice field to the Query type.
    • Added the standalonePrices field to the Query type.
  • [GraphQL API] Changed the Mutation type:
    • Added the createStandalonePrice field to the Mutation type.
    • Added the deleteStandalonePrice field to the Mutation type.
    • Added the updateStandalonePrice field to the Mutation type.
  • [GraphQL API] Changed the Product type:
    • Added the priceMode field to the Product type.
  • [GraphQL API] Changed the ProductDraft type:
    • Input field priceMode was added to ProductDraft type
  • [GraphQL API] Changed the ProductUpdateAction type:
    • Input field setPriceMode was added to ProductUpdateAction type

The following changes were introduced in terms of GraphQL SDL:

extend type Query {
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#beta-features"
standalonePrice(
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): StandalonePrice
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#beta-features"
standalonePrices(where: String, sort: [String!], limit: Int, offset: Int): StandalonePriceQueryResult!
}
extend type Mutation {
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#beta-features"
createStandalonePrice(draft: CreateStandalonePrice!): StandalonePrice
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#beta-features"
deleteStandalonePrice(version: Long!,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): StandalonePrice
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#beta-features"
updateStandalonePrice(version: Long!, actions: [StandalonePriceUpdateAction!]!,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String): StandalonePrice
}
extend type Product {
priceMode: PriceMode
}
extend input ProductDraft {
priceMode: PriceMode
}
extend input ProductUpdateAction {
setPriceMode: SetProductPriceMode
}
input ChangeStandalonePriceValue {
value: BaseMoneyInput!
}
input CreateStandalonePrice {
key: String
sku: String!
value: BaseMoneyInput!
country: Country
customerGroup: ResourceIdentifierInput
channel: ResourceIdentifierInput
validFrom: DateTime
validUntil: DateTime
tiers: [ProductPriceTierInput!] = []
custom: StandalonePriceCustomField
discounted: DiscountedProductPriceValueInput
}
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#beta-features"
enum PriceMode {
"The API looks up prices from Standalone Prices, stored separately from Products."
Standalone
"The API looks up prices from the `prices` field of the ProductVariant inside a Product."
Embedded
}
input SetProductPriceMode {
priceMode: PriceMode
}
input SetStandalonePriceCustomFields {
name: String!
value: String
}
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#beta-features"
type StandalonePrice implements Versioned {
id: String!
version: Long!
key: String
sku: String!
value: BaseMoney!
country: Country
customerGroupRef: Reference
channelRef: Reference
validFrom: DateTime
validUntil: DateTime
tiers: [ProductPriceTier!]
discounted: DiscountedProductPriceValue
custom: CustomFieldsType
createdAt: DateTime!
lastModifiedAt: DateTime!
createdBy: Initiator
lastModifiedBy: Initiator
}
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#beta-features"
input StandalonePriceCustomField {
typeId: String
typeKey: String
type: ResourceIdentifierInput
fields: CustomFieldsDraft!
}
type StandalonePriceQueryResult {
offset: Int!
count: Int!
total: Long!
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#beta-features"
exists: Boolean!
results: [StandalonePrice!]!
}
input StandalonePriceUpdateAction {
changeValue: ChangeStandalonePriceValue
setCustomType: CustomFieldsDraft
setCustomField: SetStandalonePriceCustomFields
}