Skip to content

Build a B2B Storefront

⏱ 90 minutes advanced
📜Corecommerce

By the end of this tutorial, you will have a B2B storefront that:

  • Displays a product catalog with categories and variants
  • Applies customer-specific and volume-based pricing
  • Routes orders through an approval workflow before submission
  • Manages buyer organizations with multiple cost centers
  • Handles purchase orders and credit terms

This tutorial uses Commerce Configured. The patterns apply to B2B scenarios where buyers need negotiated pricing, purchasing controls, and organizational hierarchies.

Ensure your Commerce instance is running and you can access the admin panel at /episerver/cms. Verify that you have administrator-level permissions for catalog management and customer configuration.

Step 1: Configure the B2B organization structure

Section titled “Step 1: Configure the B2B organization structure”

B2B commerce requires an organizational hierarchy. Buyers belong to organizations, and each organization can have budgets, cost centers, and approval rules.

Navigate to Commerce > Customers and create your first buyer organization.

Create a buyer organization
csharp
using Insite.Core.Interfaces.Data;
using Insite.Model.Entities;

public void CreateBuyerOrganization(
    IUnitOfWork unitOfWork)
{
    var customer = new Customer
    {
        CompanyName = "Acme Manufacturing",
        CustomerType = "B2B",
        IsActive = true,
        DefaultWarehouse = "MAIN",
        CurrencyCode = "USD"
    };

    unitOfWork.GetRepository<Customer>().Insert(customer);
    unitOfWork.Save();
}

Create a catalog structure suited for B2B buyers. Industrial and wholesale catalogs typically organize by product function rather than brand.

  1. Navigate to Commerce > Catalog Management
  2. Create a catalog named “Industrial Supplies”
  3. Add top-level categories: “Fasteners”, “Safety Equipment”, “Tools”
  4. Under each category, create subcategories for specific product lines
Define a B2B product content type
csharp
public class IndustrialProduct
{
    public string Name { get; set; }
    public string Sku { get; set; }
    public string ManufacturerPartNumber { get; set; }
    public string UnitOfMeasure { get; set; } = "EA";
    public decimal MinimumOrderQuantity { get; set; } = 1;
    public decimal PackSize { get; set; } = 1;
    public bool RequiresQuote { get; set; }
    public string HazmatClassification { get; set; }
}

Step 3: Create product variants with B2B attributes

Section titled “Step 3: Create product variants with B2B attributes”

B2B variants need attributes beyond size and color. Add specifications like material grade, certifications, and compliance codes.

Create variants with industrial specs
csharp
public void CreateIndustrialVariant(
    IContentRepository repo,
    ContentReference productRef)
{
    var variant = repo.GetDefault<VariationContent>(productRef);
    variant.Name = "Hex Bolt M10x50 Grade 8.8 Zinc";
    variant.Code = "HB-M10-50-88-ZN";
    // B2B-specific properties
    variant["Material"] = "Carbon Steel";
    variant["Grade"] = "8.8";
    variant["Finish"] = "Zinc Plated";
    variant["CertificationStandard"] = "ISO 4014";
    variant["CountryOfOrigin"] = "DE";

    repo.Save(variant,
        SaveAction.Publish, AccessLevel.NoAccess);
}

Step 4: Configure customer-specific pricing

Section titled “Step 4: Configure customer-specific pricing”

B2B buyers expect negotiated prices. Set up pricing tiers that vary by customer group, volume, and contract terms.

Set up contract pricing
csharp
public void SetContractPricing(
    IPriceDetailService priceService,
    string variantCode)
{
    var prices = new List<IPriceDetailValue>
    {
        // List price for all customers
        new PriceDetailValue
        {
            CatalogKey = new CatalogKey(variantCode),
            MarketId = new MarketId("US"),
            CustomerPricing = CustomerPricing.AllCustomers,
            MinQuantity = 0,
            UnitPrice = new Money(4.50m, Currency.USD)
        },
        // Contract price for Acme Manufacturing
        new PriceDetailValue
        {
            CatalogKey = new CatalogKey(variantCode),
            MarketId = new MarketId("US"),
            CustomerPricing = new CustomerPricing(
                CustomerPricing.PriceType.PriceGroup,
                "AcmeContract2026"),
            MinQuantity = 0,
            UnitPrice = new Money(3.25m, Currency.USD)
        },
        // Volume discount at 500+ units
        new PriceDetailValue
        {
            CatalogKey = new CatalogKey(variantCode),
            MarketId = new MarketId("US"),
            CustomerPricing = CustomerPricing.AllCustomers,
            MinQuantity = 500,
            UnitPrice = new Money(2.90m, Currency.USD)
        }
    };

    priceService.Save(prices);
}

Assign budgets to cost centers so buyers can track spending by department or project.

  1. Navigate to Commerce > Customers > [Organization]
  2. Under Cost Centers, create entries like “Production Floor”, “Maintenance”, “R&D”
  3. Assign a monthly or annual budget to each cost center
  4. Link users to their authorized cost centers

When a buyer places an order, they select a cost center. The system validates that the order amount does not exceed the remaining budget.

Create a catalog browsing experience that shows B2B-relevant data: SKU, pack size, unit of measure, and availability.

B2B catalog listing component
csharp
@model CatalogViewModel

<div class="product-grid">
@foreach (var product in Model.Products)
{
    <div class="product-card">
        <img src="@product.ThumbnailUrl" alt="@product.Name" />
        <h3>@product.Name</h3>
        <p class="sku">SKU: @product.Sku</p>
        <p class="price">
            @product.CustomerPrice.ToString("C")
            <span class="uom">/ @product.UnitOfMeasure</span>
        </p>
        <p class="pack">Pack: @product.PackSize</p>
        <p class="availability">@product.AvailabilityStatus</p>
        <form method="post">
            <input type="number" name="qty"
                   min="@product.MinOrderQty"
                   step="@product.PackSize"
                   value="@product.MinOrderQty" />
            <button type="submit">Add to Cart</button>
        </form>
    </div>
}
</div>

B2B buyers often know exactly what they need. A quick order pad lets them enter SKUs and quantities directly.

Quick order pad
javascript
async function submitQuickOrder(lines) {
  // lines = [{ sku: 'HB-M10-50-88-ZN', qty: 200 }, ...]
  const response = await fetch('/api/cart/bulk-add', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ lines }),
  });

  const result = await response.json();

  // Show validation: invalid SKUs, below-minimum qty
  if (result.errors.length > 0) {
    displayErrors(result.errors);
  }

  // Show successfully added items
  updateCartCount(result.cartItemCount);
  return result;
}

Define approval rules so that orders above a threshold or from certain cost centers require manager sign-off before submission.

  1. Navigate to Commerce > Settings > Approval Rules
  2. Create a rule: “Orders over $5,000 require manager approval”
  3. Create a rule: “All orders from R&D cost center require VP approval”
  4. Assign approvers by role within each organization
Approval workflow configuration
csharp
public class OrderApprovalRule
{
    public string Name { get; set; }
    public decimal? AmountThreshold { get; set; }
    public string CostCenter { get; set; }
    public string ApproverRole { get; set; }
    public bool RequireAllApprovers { get; set; }
}

// Example rules
var rules = new List<OrderApprovalRule>
{
    new OrderApprovalRule
    {
        Name = "High Value Orders",
        AmountThreshold = 5000m,
        ApproverRole = "PurchasingManager"
    },
    new OrderApprovalRule
    {
        Name = "R&D Purchases",
        CostCenter = "RD-001",
        ApproverRole = "VPEngineering",
        RequireAllApprovers = true
    }
};

Create a view where approvers can review, approve, or reject pending orders.

Approval dashboard query
csharp
public async Task<List<PendingApproval>> GetPendingApprovals(
    string approverUserId)
{
    return await _orderRepository
        .GetOrders()
        .Where(o => o.Status == "PendingApproval")
        .Where(o => o.RequiredApprovers
            .Contains(approverUserId))
        .OrderByDescending(o => o.SubmittedDate)
        .Select(o => new PendingApproval
        {
            OrderNumber = o.OrderNumber,
            Submitter = o.PlacedBy,
            CostCenter = o.CostCenter,
            Total = o.OrderTotal,
            LineCount = o.LineItems.Count,
            SubmittedDate = o.SubmittedDate
        })
        .ToListAsync();
}

Step 10: Configure payment terms and purchase orders

Section titled “Step 10: Configure payment terms and purchase orders”

B2B transactions often use purchase orders and net terms instead of credit card payments. Configure payment methods that support PO numbers and invoicing.

  1. Navigate to Commerce > Settings > Payment Methods
  2. Add a “Purchase Order” payment method
  3. Configure net terms: Net 30, Net 60, or custom terms per customer
  4. Set credit limits per organization

Configure email notifications so buyers get order confirmations, approvers get approval requests, and fulfillment teams get picking instructions.

Order notification configuration
csharp
public class B2BNotificationConfig
{
    public static void Configure()
    {
        // Notify buyer when order is submitted
        OrderEvents.OnSubmitted += (order) =>
            SendEmail(order.PlacedByEmail,
                "order-submitted", order);

        // Notify approver when approval is needed
        OrderEvents.OnPendingApproval += (order) =>
            SendEmail(order.ApproverEmail,
                "approval-needed", order);

        // Notify buyer when order is approved
        OrderEvents.OnApproved += (order) =>
            SendEmail(order.PlacedByEmail,
                "order-approved", order);

        // Notify fulfillment when ready to ship
        OrderEvents.OnReleased += (order) =>
            SendEmail("fulfillment@company.com",
                "ready-to-fulfill", order);
    }
}

Walk through the entire buyer journey to verify everything works end to end.

ScenarioExpected result
Browse catalog as authenticated buyerCustomer-specific pricing displays
Add items via quick order padSKU validation, minimum quantity enforced
Select cost center at checkoutBudget validation passes
Submit order over $5,000Order enters “Pending Approval” status
Approve order as managerOrder moves to “Submitted”, buyer notified
Reject order with commentBuyer notified with rejection reason
Submit order under thresholdOrder bypasses approval, submits directly
Submit PO with net-30 termsOrder created with PO number, no payment capture

Run through the test scenarios above with at least two buyer accounts (one standard, one requiring approval) and verify that pricing, budgets, and workflows behave correctly. Check the admin dashboard to confirm orders appear with the right statuses and cost center assignments.