- Promotions, sale prices, and discounts
Discounts
Discounts let you apply percentage-based price reductions with quantity tiers at the catalog, category, or product level. They support party-based assignments to buyer groups, buyers, and user groups.
When multiple discounts match the same item, OrderCloud applies the discount that gives the lowest price. Discounts do not stack.
This feature is currently in beta. Behavior and properties might change before general availability.
Discount model
Discount properties
| Property | Type | Description | Required |
|---|---|---|---|
ID | string | Unique identifier. | Yes |
Description | string | Optional description. Maximum length is 2000 characters. | No |
DiscountBreaks | array | Quantity tiers for discount percentages. | Yes |
CatalogID | string | Limits the discount to a catalog. | No |
CategoryID | string | Limits the discount to a category. | No |
ProductID | string | Limits the discount to a product. | No |
ProductFilter | string | Limits the discount to products that match a filter expression. | No |
xp | object | Extended properties. | No |
If CatalogID, CategoryID, and ProductID are all null, the discount is applied globally across all products available to the assigned party or parties.
Use ProductFilter to target products with specific values on an xp key. For example, create a discount for products where xp.color=red.
DiscountBreak properties
| Property | Type | Description | Required |
|---|---|---|---|
Quantity | int | Minimum quantity for this break. | Yes |
Amount | decimal | Discount percentage greater than 0 and less than or equal to 100. | Yes |
For each discount, OrderCloud selects the highest break where Quantity <= LineItem.Quantity.
Assignment model
Assignment properties
| Property | Type | Description | Required |
|---|---|---|---|
DiscountID | string | Discount to assign. | Yes |
BuyerGroupID | string | Buyer group to assign. | Conditionally |
BuyerID | string | Buyer to assign. | Conditionally |
UserGroupID | string | User group to assign. | Conditionally |
Assignment rules
Use one of these valid combinations:
- Buyer group assignment:
BuyerGroupID - Buyer assignment:
BuyerID - User group assignment:
BuyerIDandUserGroupID
API endpoints
Discount management
| Operation | Endpoint |
|---|---|
| List discounts | GET /v1/discounts |
| Get discount | GET /v1/discounts/{discountID} |
| Create discount | POST /v1/discounts |
| Replace discount | PUT /v1/discounts/{discountID} |
| Update discount | PATCH /v1/discounts/{discountID} |
| Delete discount | DELETE /v1/discounts/{discountID} |
Assignment management
| Operation | Endpoint |
|---|---|
| List assignments | GET /v1/discounts/assignments |
| Create assignment | POST /v1/discounts/assignments |
| Delete assignment | DELETE /v1/discounts/{discountID}/assignments |
When you call DELETE /v1/discounts/{discountID}/assignments, pass the target party in query parameters:
buyerGroupIDfor a buyer group assignmentbuyerIDfor a buyer assignmentbuyerIDanduserGroupIDfor a user group assignment
Authorization
| Role | Access |
|---|---|
PriceScheduleAdmin | Full CRUD access to discounts and assignments |
PriceScheduleReader | Read-only access to discounts and assignments |
Create and assign discounts
Create a volume discount
POST /v1/discounts
Assign to a buyer group
POST /v1/discounts/assignments
Buyer-side discount data
When a buyer requests products through GET /v1/me/products, OrderCloud evaluates applicable assignments and returns the selected discount in the product pricing payload.
Selection logic
- OrderCloud evaluates discounts assigned to the buyer group, buyer, and user group.
- If multiple discounts match, OrderCloud picks the discount that returns the lowest price.
- For the selected discount, OrderCloud picks the highest matching break where
Quantity <= LineItem.Quantity. - The ID of the selected discount is available in
PriceSchedule.Discount.ID;PriceSchedule.Discount.Descriptionis also available for display purposes. - If no discount matches,
PriceBreak.Discountedisnull.
Derived Price Breaks
When a discount's quantity tiers don't align with the price schedule's quantity tiers, the buyer response includes derived price breaks at the discount-break quantities. This ensures buyers always see distinct pricing for every meaningful quantity threshold, without requiring sellers to duplicate price break definitions.
Example: A price schedule has one price break at qty 1 ($100.00). A discount applies 10% at qty 1 and 15% at qty 20. The buyer sees two price breaks:
| Quantity | Price | Discounted.Price | Discounted.Percent |
|---|---|---|---|
| 1 | $100.00 | $90.00 | 10 |
| 20 | $100.00 | $85.00 | 15 |
The qty-20 break is derived - its base Price is inherited from the applicable price tier (qty 1). The number of PriceBreaks on BuyerPriceSchedule equals the number of distinct quantity values across all price breaks and discount breaks.
Constraints on Derived Breaks
A discount-break quantity is not derived as an additional price break if any of the following apply:
RestrictedQuantityistrue- buyers can only order at exact price break quantities, so intermediate breaks are meaningless. No derivation occurs at all; the discount is still applied to matching price break quantities.- Quantity is below
MinQuantity- the schedule prohibits ordering at that quantity. - Quantity is above
MaxQuantity- the schedule prohibits ordering at that quantity. - No applicable price break tier exists - the discount-break quantity falls below the lowest price break quantity (no base price can be inherited).
If the above constraints eliminate all discount coverage across every price break, PriceSchedule.Discount is set to null.
Discount persistence on line items and orders
When a line item is created or updated, OrderCloud calculates the discount and stores the result on the line item and order.
Line item fields
| Property | Type | Description |
|---|---|---|
DiscountID | string | ID of the applied discount. Read-only. |
BaseDiscount | decimal | Discount amount for the line item in currency units. Read-only. |
BaseDiscount uses this calculation:
LineSubtotal * (DiscountPercentage / 100)
Order field
| Property | Type | Description |
|---|---|---|
BaseDiscount | decimal | Sum of all LineItem.BaseDiscount values. Read-only. |