Overview:
Working with baskets in business-to-business (B2B) scenarios involves additional considerations compared to standard consumer shopping. In B2B contexts, you typically know the customer identity upfront, work with company-specific pricing, and may need to handle special agreements or project-based pricing.
Note: B2B baskets in Norce Commerce do not require existing customers and companies. You can create a B2B purchase as long as there is a company entity in the checkout model. However, you will also always need a person (contact) as well.
For known buyers, this is represented in the basket by both aCustomerIdandCompanyIdthat must be set. With this, you get company-specific pricing, agreements, and business rules.
References:
- Basket Schema
- B2B Examples in Postman
- Working with Baskets - General basket concepts
To create a B2B basket for personalized business rules, you must have:
- A valid customer ID (
CustomerId) - A valid company ID (
CompanyId) - Configured B2B price lists and agreements
- Company-customer relationships established in Norce Commerce
When creating a B2B basket, pass the customer and company information in the initial basket object:
{
"CustomerId": 12345,
"CompanyId": 67890,
"PaymentMethodId": 14,
"DeliveryMethodId": 1,
"Comment": "Project order for Q1 2024"
}Common Practice:
Wait and create the basket only when the first item is added, passing both customer/company IDs and the initial item simultaneously:
{
"CustomerId": 12345,
"CompanyId": 67890,
"PaymentMethodId": 14,
"DeliveryMethodId": 1,
"Items": [ {
"PartNo": "PRD001",
"Quantity": 5.000,
} ]
}When customer-specific prices are configured, Norce Commerce automatically selects the best available price from connected price lists:
{
"PartNo": "PRD001",
"Quantity": 1.000,
"PriceListId": null
}Note: Leave
PriceListIdnull to allow automatic price selection from the customer's available price lists.
There are two common scenarios:
- Create a new context of price lists, instead of the default.
- Pick and choose price lists for each item in the basket
Prerequisites
Enable the client setting: "When PriceListSeed is used in Norce API, disregard public price lists". This lets you change the best price context as you wish. By passing in a price list seed without, for example, a campaign or event, the standard price list you can let Norce validate the best price based only on your choosing.
PriceListSeed As long as you use PriceListSeed in all your product and listproduct contexts, you will get the current best price between only the provided price lists.
Add to basket You don't need to do anything different when you call InsertBasketItem; pass in PriceListId = null.
In this scenario, you want to pick and choose the specific agreement (price list) as you add an item to the cart. For this, you need to:
- Fetch the specific price by using PriceListSeed when fetching the product with only the specific id for the agreement.
- Set PriceListLocked = true when you add it to the cart. This will override any best price calculations later.
{
"PartNo": "PRD001",
"Quantity": 1.000,
"PriceListId": 15320,
"PriceListLocked": true,
"Comment": "Using special project agreement"
}Use Case Example: Project agreements that may be more expensive than public pricing but include additional benefits like extended warranties or service packages.
Important: Use
PriceListLockedwhen you need to maintain different pricing contexts within the same basket.
Use the ListCompanyPriceLists method to get all price lists connected to a company:
GET customer/1.1/ListCompanyPricelists?companyId=67890You can also fetch all price lists for the client by calling ListPricelists:
GET product/1.1/ListPricelistsThese allow you to present pricing options to the user and let them choose which agreement(s) to use for their purchase for any of the options above.
Common practice is to update information on the basket before creating the order, which relates to the procurement process at the end customer. Some basket fields are built-in and can be used, but the powerful extendability of the info types lets you add as much information as you need. This can be:
- Purchase order number
- Invoice mark
- Delivery mark or other comments
- Additional fields, like expected delivery date, sales representative, department identifiers and more
Note: Some information might be added programmatically, while other information may be input from the end customer
Use the UpdateBasket method to add this information when needed:
{
"Id": 6600304,
"CustomerId": 12345,
"CompanyId": 67890,
"OrderReference": "PO-2024-001",
"Comment": "New computer for Johan",
"InvoiceReference": "Cost center 1001",
"Info": [
{
"TypeId": 1,
"Value": "20251101",
"Code": "bit_deliverydate"
},
{
"TypeId": 2,
"Value": "Stefan S",
"Code": "bit_salesrep"
},
,
{
"TypeId": 2,
"Value": "Finance",
"Code": "bit_department"
}
]
}Additional information can also be set at the item level using info types, for example:
- Information about the item, entered by the end customer
- Delivery instructions to merchant
{
"Id": 33263,
"LineNo": 1,
"PartNo": "PRD001",
"Quantity": 1,
"Comment": "Put in Johans cubicle directly",
"Info": [
{
"TypeId": 10,
"Value": "Yes",
"Code": "bit_pack_together"
},
{
"TypeId": 11,
"Value": "microdot",
"Code": "bit_taggedfortheft"
}
]
}B2B baskets may require approval based on:
- Order Value: High-value orders need management approval
- Customer Credit: Credit limit validations
- Product Categories: Restricted items require special approval
Norce provides some built-in support, like account roles, flags, or info types to create a customer/company model that can keep the information needed for front-end business logic.
For example:
- Use account roles to manage "Approver", "Purchaser", "Buyer" etc.
- Use company flags and flag groups to tag specific companies for different types of processes.
- Use info types on customers or companies for more detailed configurations, like storing JSON objects with information about the approval steps for a company, or updating current order values from an ERP integration.
Code example stub
Implement additional validation for B2B scenarios:
public bool ValidateB2BBasket(Basket basket)
{
// Check company credit limit
if (basket.Summary.Total.AmountIncVat > GetCreditLimit(basket.CompanyId))
return false;
// Validate customer permissions
if (!HasPurchasePermission(basket.CustomerId, basket.CompanyId))
return false;
return basket.IsBuyable;
}And track the approval process on the basket using info types:
{
"Id": 6600304,
"CustomerId": 12345,
"CompanyId": 67890,
"OrderReference": "PO-2024-001",
"Comment": "New computer for Johan",
"InvoiceReference": "Cost center 1001",
"Info": [
{
"TypeId": 1,
"Value": "Anders S",
"Code": "bit_approved_by"
}
]
}For punch-out scenarios where users shop on your site but return to their procurement system:
- Create basket with punch-out context
- Allow shopping and basket building
- Instead of checkout, return basket data to external procurement system
Convert quotes to orders by:
- Creating basket with manual pricing
- Setting
IsPriceManual: truefor quote prices - Setting a "Valid to" info type field
- Converting to order when quote is accepted (validation of "Valid to" field)
- Cache Price Lists: Store company price lists to reduce API calls
- Validate Permissions: Check customer-company relationships early
- Optimize Context: Set price list context once per session when possible
- Late Login: Often simplest to create a new basket and pass in the old one with customerId and companyId set.
- Working with Baskets - General basket concepts
- Working with the Checkout Process - Completing B2B orders
- Shopping Integration - ERP integration patterns