Why discounts are not the B2B pricing model
Channels carry the negotiated price
ProductDistribution role. A distribution Channel "can be used by a Cart to select a Product Price": it is a price scope you attach Prices to, and that the buyer's Store makes available as part of the buyer's commercial context.The chain reuses what you built in earlier modules:
- A Business Unit resolves to a Store (assigned directly or inherited).
- The Store carries a distribution Channel that is valid for that buyer context.
- Price-aware product and Cart requests use that Channel to select Channel-scoped Standalone Prices.
priceChannel; for Carts, use it as the Line Item distributionChannel. This is why Channels (not Customer Groups) are the recommended way to model negotiated B2B pricing: a Channel binds to the Store, so the implementation can derive the price scope from the buyer's context instead of maintaining an unrelated buyer-level price assignment.InventorySupply, scopes inventory rather than price. Because a Channel holds a roles array, a single Channel can carry both roles at once: the same Channel can act as the ProductDistribution scope for the negotiated price and the InventorySupply scope for warehouse stock, which is common when one facility both prices and fulfills a buyer's orders. You can also split the two across separate Channels on the Store when the price scope and the stock scope differ. Either way, keep the two roles distinct in your design: one answers "what does this buyer pay?", the other "where does stock come from?".Primary role is unrelated to holding both scopes. It marks a Channel as the default among Channels that share a role, and can be combined with another role such as InventorySupply, but it does not by itself grant pricing or inventory scope.Setting up channel-based pricing
First, create the distribution Channel for the buyer.
POST /{projectKey}/channels HTTP/1.1
Content-Type: application/json
{
"key": "horizon-hotels-pricing",
"roles": ["ProductDistribution"],
"name": { "en-AU": "Horizon Hotels pricing" }
}
Attach the Channel to the buyer's Store as a distribution Channel.
POST /{projectKey}/stores/key=horizon-hotels-store HTTP/1.1
Content-Type: application/json
{
"version": 2,
"actions": [
{
"action": "addDistributionChannel",
"distributionChannel": {
"typeId": "channel",
"key": "horizon-hotels-pricing"
}
}
]
}
Create a Standalone Price for the SKU, scoped to that Channel. The Price applies only when that Channel is used for price selection.
POST /{projectKey}/standalone-prices HTTP/1.1
Content-Type: application/json
{
"sku": "ZET-LAPTOP-14",
"value": { "currencyCode": "AUD", "centAmount": 129900 },
"channel": { "typeId": "channel", "key": "horizon-hotels-pricing" }
}
distributionChannel. If the Cart belongs to a Store with distributionChannels set, the Channel must be one of that Store's distribution Channels.POST /{projectKey}/carts/{cartId} HTTP/1.1
Content-Type: application/json
{
"version": 7,
"actions": [
{
"action": "addLineItem",
"sku": "ZET-LAPTOP-14",
"quantity": 10,
"distributionChannel": {
"typeId": "channel",
"key": "horizon-hotels-pricing"
}
}
]
}
Standalone Prices are the recommended choice for B2B in almost all cases. Embedded Prices are stored inside the Product Variant and are limited in number per Variant, which becomes a constraint when many companies each need their own price for the same SKU. Standalone Prices are independent entities, so they scale to many per-company prices and can be managed without editing the Product.
Embedded Prices still have a narrow place in B2B. When a Product's price is uniform and unnegotiated across every buyer, a single Embedded Price on the Variant is simpler than a Standalone Price and avoids maintaining an extra resource. As soon as pricing is negotiated per company, or one SKU needs several company-specific prices, move to Standalone Prices.
Bulk pricing with Price tiers
tiers field.POST /{projectKey}/standalone-prices HTTP/1.1
Content-Type: application/json
{
"sku": "ZET-LAPTOP-14",
"value": { "currencyCode": "AUD", "centAmount": 129900 },
"channel": { "typeId": "channel", "key": "horizon-hotels-pricing" },
"tiers": [
{ "minimumQuantity": 25, "value": { "currencyCode": "AUD", "centAmount": 119900 } }
]
}
minimumQuantity, tier currency, and discounted Prices, see PriceTier.Pricing at scale: cluster, don't duplicate
Worked example: Horizon Hotels and Pacific Property Group
Zen Electron Trade has negotiated rates with two buyers and expects dozens more like them.
- Horizon Hotels negotiated a flat preferred rate across the catalog, with volume breaks on high-runner SKUs. Model a
preferred-pricingdistribution Channel, attach it to Horizon Hotels' Store, and create Channel-scoped Standalone Prices, addingtierson the SKUs with agreed volume breaks. - Pacific Property Group negotiated the same preferred rate. Rather than create a second identical price set, attach the same
preferred-pricingChannel to Pacific's Store. Both buyers now use the preferred Channel from their Store context and resolve the preferred rate from one maintained price set. - When a third buyer negotiates a deeper "strategic" rate, create a
strategic-pricingChannel and price set, and attach it to that buyer's Store.
preferred, strategic) that many Business Units share through their Stores, rather than one bespoke price set per company. As Zen Electron Trade onboards more buyers, it assigns each to an existing cluster and only creates a new Channel when a genuinely new pricing tier is negotiated.price field is absent from the Product Variant in the response. Storefronts commonly render this state as "price on request." When adding a Line Item to a Cart, the same mismatch can return MatchingPriceNotFound. Treat either result as a configuration signal, not a platform error.Key takeaways
- B2B pricing is negotiated contract pricing per company, not list price minus a discount.
- A distribution Channel (
ProductDistribution) carries the negotiated Price; attaching it to a buyer's Store makes the Channel available from the buyer's commercial context, and product or Cart requests use that Channel for price selection. A single Channel can hold bothProductDistributionandInventorySupplyroles. - Use Standalone Prices for B2B; they scale to many per-company prices where Embedded Prices do not. Embedded Prices fit only the narrow case of a uniform, unnegotiated price shared by every buyer.
- Model quantity breaks as native Price tiers, which apply to the whole Line Item quantity once the threshold is reached.
- A Product Variant supports up to 50,000 Standalone Prices; cluster buyers into shared pricing tiers rather than creating one price per company.