Company-specific pricing

Scope a negotiated price to a single buyer organization using a distribution Channel on its Store, and design a clustering strategy that scales.

Ask about this Page
Copy for LLM
View as Markdown

After completing this page, you should be able to:

  • Scope a negotiated Price to a buyer using a distribution Channel attached to the buyer's Store and passed into price selection.

  • Model quantity-based bulk pricing with native Price tiers.

  • Apply a clustering strategy to stay within the Standalone Price scaling limit.

In the Price and discount your products path you priced Products for a broad market: list Prices, optionally varied by currency, country, or Customer Group. B2B inverts that driver. A price is not a published list rate a shopper discovers; it is the outcome of a contract negotiated with one company. Horizon Hotels and Pacific Property Group buy the same laptop from Zen Electron Trade at different prices because each negotiated its own rate. This page assumes you understand Prices and Channels, and focuses on how to bind a negotiated price to a single buyer.

Why discounts are not the B2B pricing model

In B2C, a buyer typically pays the list Price minus a discount earned at checkout. In B2B, the buyer pays a contract price agreed in advance. Discounts still exist, but they are the exception rather than the mechanism (covered in Price versus discount). The architectural question for this page is narrower: how do you attach a per-company negotiated price so that the right buyer sees it automatically?

Channels carry the negotiated price

The mechanism is a Channel with the 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:

  1. A Business Unit resolves to a Store (assigned directly or inherited).
  2. The Store carries a distribution Channel that is valid for that buyer context.
  3. Price-aware product and Cart requests use that Channel to select Channel-scoped Standalone Prices.
Because the Channel lives on the Store, the buyer does not choose a price scope manually. The commercial context narrows the valid choice: the Associate acts in their Business Unit, the Business Unit resolves to its Store, and the Store's distribution Channel is the Channel the storefront or middleware passes into price selection. For product browsing, use the Channel as 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.
A second Channel role, 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?".
The separate 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" }
}
When adding the Product to a Cart, pass the same Channel as the Line Item 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

Some negotiated agreements set a lower unit price above a quantity threshold: "AUD 1,299 each, or AUD 1,199 each from 25 units." This is a property of the Price itself, not a discount. A Standalone Price can carry Price tiers through its 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 } }
  ]
}
A Price tier is a native pricing feature, so it participates in price selection like any other Price. A tiered, Channel-scoped Standalone Price gives a buyer both a negotiated rate and volume breaks with no discount logic involved. For field-level rules for minimumQuantity, tier currency, and discounted Prices, see PriceTier.
Model bulk pricing as tiers or apply a discount, not both on the same Price. Keeping the volume break on the negotiated Price makes the commercial agreement easier to audit.

Pricing at scale: cluster, don't duplicate

A natural first instinct is one unique Standalone Price per buyer. That does not scale indefinitely: a Product Variant supports up to 50,000 Standalone Prices. A pure one-price-per-company model therefore caps at 50,000 companies for a single SKU, and long before that, the operational cost of maintaining a distinct price for every buyer becomes the real limit.
The modeling answer is clustering. Group companies that negotiated similar terms into shared pricing tiers (for example "standard," "preferred," and "strategic") and attach one distribution Channel per tier rather than per company. Buyers in the same tier share a Channel and its Standalone Prices. You still deliver differentiated pricing, but you maintain a handful of price sets instead of thousands.

Worked example: Horizon Hotels and Pacific Property Group

Zen Electron Trade has negotiated rates with two buyers and expects dozens more like them.

  1. Horizon Hotels negotiated a flat preferred rate across the catalog, with volume breaks on high-runner SKUs. Model a preferred-pricing distribution Channel, attach it to Horizon Hotels' Store, and create Channel-scoped Standalone Prices, adding tiers on the SKUs with agreed volume breaks.
  2. Pacific Property Group negotiated the same preferred rate. Rather than create a second identical price set, attach the same preferred-pricing Channel 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.
  3. When a third buyer negotiates a deeper "strategic" rate, create a strategic-pricing Channel and price set, and attach it to that buyer's Store.
The result is a small number of price clusters (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.
If no Price matches a buyer's context during product browsing (for example, no Channel-scoped Price exists for the SKU), the API returns no selected Price; the 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 both ProductDistribution and InventorySupply roles.
  • 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.

Test your knowledge