B2B commerce has always been the harder problem to solve. Consumer-facing stores follow a relatively consistent pattern: browse, add to cart, check out, receive confirmation. B2B buying journeys do not work that way. A purchasing manager at a manufacturing company expects to see prices negotiated months ago in a contract. An employee from that same company expects a spending limit enforced at the cart level. A procurement team expects to route large orders through an internal approval workflow before any payment is triggered.

    Most SaaS ecommerce platforms were designed for B2C and retrofitted for B2B. The result is a collection of workarounds: apps layered on top of apps, pricing logic split between the platform and an external ERP, and buyer role management handled through manual processes that do not scale. Medusa.js approaches this differently. Its modular architecture treats B2B commerce requirements as first-class concerns, giving development teams the primitives to build exactly the pricing engine, role hierarchy, and approval flow their business needs without patching a platform that was never designed for it.

    This article is a technical deep dive into how Medusa.js handles the two most complex dimensions of B2B commerce: pricing and buyer roles. It covers the native modules, the customization patterns, and the real-world implementation approaches that production B2B stores are using today.

    Why B2B Commerce Demands a Different Architecture

    The gap between B2C and B2B commerce is not simply about order volume or product complexity. It is about the entire commercial relationship that exists before a transaction is completed. B2B buyers operate within account structures. They have negotiated pricing that differs from list price. They have authority limits that determine whether they can finalize a purchase or must request approval. They expect to request quotes, receive counter-offers, and convert accepted quotes into orders.

    A traditional ecommerce platform handles none of this well without significant extension. When EKI, a 150-year-old Dutch foam and rubber manufacturer serving over 9,000 B2B customers across 42 countries, migrated from Magento to Medusa.js, one of the driving requirements was the ability to support customers with multiple buyers per organization, all with different purchasing permissions and access to custom pricing based on their organization's profile. Medusa's modular architecture handled this without forcing the implementation into the platform's existing data model. The full case study is available at medusajs.com/blog/eki.

    The Core Medusa.js Modules Behind B2B Commerce

    Module

    B2B Role

    Key Capability

    Pricing Module

    Contract and list price management

    Price lists, rule engine, tiered pricing

    Customer Module

    Buyer and account management

    Customer groups, role-based access, org links

    Sales Channel Module

    Product availability control

    B2B-only catalogs, publishable API keys

    Workflow Engine

    Approval and quote flows

    Multi-step workflows with rollback support

    Order Module

    Purchase order lifecycle

    Draft orders, order edits, quote-to-order conversion

    These modules are all open-source, installed by default in a Medusa.js application, and composable with each other and with your custom modules. The full B2B implementation guide and a ready-to-use B2B starter are documented at docs.medusajs.com/resources/recipes/b2b.

    Complex Pricing in Medusa.js: How It Actually Works

    The Pricing Module and Rule Engine

    Medusa.js's Pricing Module is built around a rule engine that evaluates the context of a request and returns the most applicable price for a given product variant. The module supports prices conditioned on multiple rule dimensions simultaneously, including customer group, sales channel, region, currency, and custom attributes you define. This means a single product can have dozens of price definitions attached to it, and Medusa's price calculation strategy automatically determines which price applies based on who is requesting it and from where.

    The advanced rule engine also supports tiered pricing, where the price for a product variant changes based on quantity thresholds. A B2B buyer purchasing 10 units of a product pays a different per-unit price than one purchasing 500 units. Medusa handles this within the same pricing framework without requiring a separate pricing plugin or custom middleware.

    Price Lists for Account-Level Pricing

    Price Lists are the mechanism Medusa.js uses to override standard prices for specific customer groups or under specific conditions. For B2B commerce, Price Lists are where you define the contracted rates that apply to individual accounts or account categories. A Price List can be associated with a customer group, given a validity window with start and end dates, and applied to some or all products in the catalog.

    The practical workflow is straightforward. You create a customer group for each pricing tier, such as Gold Partners, Distributors, or Direct Accounts. You then create a Price List for each group, upload the negotiated prices via CSV or through the Admin API, and associate the Price List with the corresponding customer group. Any request from a customer in that group automatically receives the contracted price rather than the public list price. Merchants manage this directly from the Medusa admin without developer involvement after initial setup.

    Tax-Inclusive and Region-Aware Pricing

    For B2B stores serving multiple countries, pricing must account for regional tax rules without exposing the complexity to the buyer. Medusa.js supports tax-inclusive pricing, where the listed price includes tax and Medusa automatically back-calculates the tax portion when generating invoices. This is particularly relevant for European B2B commerce, where VAT-inclusive pricing is standard, and for Indian B2B stores where GST rules differ by product category and buyer type.

    Region-specific pricing is configured through Medusa's region settings, where you define currencies, tax providers, and shipping options per region. Combined with Price Lists scoped to specific regions, Medusa can serve entirely different pricing structures to buyers in different geographies from a single backend instance.

    Building a Complex Pricing Engine on Medusa.js?

    Our B2B Commerce Team at Askan Ecomm Can Help
    Let's Talk

    Buyer Roles and Company Hierarchies in Medusa.js

    Out-of-the-Box Customer Groups

    Medusa.js's Customer Module includes built-in support for customer groups, which are the foundation of B2B role management. A customer group is a named segment that you assign customers to, and customer group membership determines which Price Lists apply, which sales channels are accessible, and what promotions are available. For straightforward B2B setups with a small number of account tiers, customer groups alone may be sufficient to model the role hierarchy.

    The Company and Employee Model

    Most production B2B stores require more structure than flat customer groups provide. When a buying organization has multiple employees who all purchase on behalf of the company, each with different authority levels, you need a Company and Employee data model that sits above the individual customer record.

    The official Medusa.js B2B starter on GitHub implements this model out of the box. The starter includes Company management, Employee invitation and onboarding, role-based permission controls, and spending limits enforced at the cart level. Here is the structural logic that the starter implements:

    • Company: Represents the buying organization. Linked to a customer group for pricing. Can contain multiple employees.

    • Company Admin: Has full access to the company's order history, can invite employees, set spending limits, and configure approval requirements.

    • Employee (Buyer): Can browse the catalog, build carts, and place orders within their assigned spending limit. Orders exceeding the limit are held for admin approval.

    • Spending Limits: Company admins assign per-employee purchase limits. The storefront enforces these limits at cart completion before an order is submitted.

    To deploy the B2B starter, clone the repository and follow the setup instructions. The backend and storefront install separately:

    javascript
    git clone https://github.com/medusajs/b2b-starter-medusa.git
    cd backend && yarn install && yarn medusa db:create && yarn medusa db:migrate
    yarn run seed && yarn medusa user -e admin@test.com -p supersecret -i admin
    

    Custom Company Module for Unique Hierarchies

    When the B2B starter's data model does not match your organization's structure, you build a custom module. A custom Company module follows the same pattern as any other Medusa module: define data models using Medusa's Data Model Language (DML), create a module service with the business logic, and link the Company and Employee data models to Medusa's native Customer entity using Module Links. This preserves all the benefits of Medusa's native customer authentication and order management while adding the organizational layer your business requires.

    EKI's implementation extended the Customer entity with an Organization ID field, which then served as the key for linking pricing, product recommendations, and order history to the buying organization rather than to individual customer accounts. This approach gave EKI's buyers a unified view of all orders placed by anyone in their organization, regardless of which employee had placed them.

    Quote Management and RFQ Flows

    Request-for-quote workflows are a staple of B2B procurement. A buyer adds products to a cart, requests a quote instead of checking out, and waits for the merchant to respond with a price proposal. The merchant can accept the requested quantities at a counter-price, modify line items, or reject the quote entirely. Once both parties agree, the quote converts to an order and payment is triggered.

    Medusa.js supports this entire flow through a combination of the Order Module and custom module extensions. The official guide at docs.medusajs.com/resources/examples/guides/quote-management walks through building a Quote Module with its own data model, status state machine (pending merchant, pending customer, accepted, rejected), and API routes for both buyer and merchant interactions.

    The B2B starter includes a ready-to-use implementation of this quote management flow, where customers and merchants can exchange messages on a quote, merchants can edit item prices and quantities, and accepted quotes convert to draft orders that proceed through the standard fulfillment pipeline. The B2B platform Medusa's B2B page shows how quote management integrates into a broader B2B commerce workflow.

    Cart Approval Workflows

    In organizations where not every employee has full purchasing authority, cart approval is a critical control mechanism. An employee builds a cart, submits it for approval, and the company admin receives a notification to review and approve or reject the cart before it becomes an order. This workflow eliminates the need for offline procurement processes and gives the buying organization visibility and control over spending without requiring manual intervention in every transaction.

    Medusa.js's Workflow engine is purpose-built for exactly this kind of multi-step, stateful process. An approval workflow defines the steps involved in moving a cart from submitted status to approved or rejected, with compensation logic that cleanly rolls back state if an intermediate step fails. The B2B starter's Company Approvals feature includes both company-level approval mandates, where the company admin configures whether all employee carts require approval, and merchant-level approvals, where the seller sets up compliance checks before fulfillment begins.

    Want to Implement Cart Approval Workflows in Your B2B Medusa.js Store?

    Talk to the Askan Ecomm Team
    Let's Talk

    Controlling Product Visibility with Sales Channels

    B2B stores frequently need to restrict certain products to authenticated buyers while keeping a public-facing catalog for general visitors. Medusa.js handles this through Sales Channels. You create a dedicated B2B sales channel and assign products to it that should only be visible to B2B customers. A Publishable API Key linked to the B2B sales channel is then used in the B2B storefront's API requests, and Medusa's backend automatically filters product responses to return only products available in that channel.

    This means your B2B and B2C storefronts can be entirely separate applications, each using a different Publishable API Key, while sharing the same Medusa.js backend. Product availability, pricing, and promotions are all scoped to the appropriate channel without any conditional logic in your storefront code. The Medusa Customer Module documentation at medusajs.com/customer-module covers how customer groups and sales channels combine to create fine-grained product and pricing access control.

    Integrating with ERP and PIM Systems

    Enterprise B2B stores rarely run on a single system. Product data comes from a PIM. Customer and organization data lives in a CRM or ERP. Inventory and fulfillment are managed by a warehouse management system. Medusa.js's API-first design makes it the commerce engine that sits at the center of this stack, consuming data from upstream systems and exposing commerce operations downstream through clean REST APIs.

    System Type

    Medusa.js Integration Approach

    ERP (SAP, NetSuite, Odoo)

    Event subscribers sync order status and fulfillment updates bidirectionally

    PIM (Contentful, Akeneo)

    Products imported to Medusa via Admin API or bulk CSV upload

    CRM (Salesforce, HubSpot)

    Customer group and account data synced via workflow subscribers

    Custom pricing engine

    Prices calculated externally and pushed to Medusa Price Lists via API

    Warehouse management

    Stock locations and reservations managed through Medusa Inventory Module

    EKI's implementation used Odoo as the ERP for fulfillment and customer organization data, Strapi as a PIM for product descriptions and images, and Medusa as the core commerce engine handling cart, checkout, and order management. The integration was event-driven: Medusa published events when orders were placed or updated, and subscribers pushed those events to Odoo for fulfillment processing. This decoupled architecture meant that changes to the ERP's internal logic did not require changes to the Medusa codebase, and vice versa.

    How Production B2B Stores Are Using Medusa.js

    Beyond EKI, Visionary Technologies in New Zealand used Medusa.js to build a B2B portal for their LED lighting products. Visionary required support for products with up to 300 variants, customer-specific pricing enforced at login, multiple employees per company, and a loyalty pricing engine that adjusted discount tiers based on cumulative spending. The implementation partner built a custom loyalty engine on top of Medusa's Pricing Strategies that automatically upgraded customers to better discount tiers as their annual spending crossed defined thresholds. The case study is documented at medusajs.com/blog/visionary.

    RigbyJS, a Medusa Expert Partner, has also published a dedicated Medusa B2B Starter with company employee management and role-based permissions, multi-cart management, quote flows, and company approval controls. This starter is built on Medusa 2.0 and provides a production-ready foundation for wholesale operations without requiring you to build the B2B data model from scratch.

    Should You Use the B2B Starter or Build from Scratch?

    The official Medusa B2B starter is a strong starting point for the majority of B2B commerce requirements. If your business needs company management, employee roles, spending limits, quote flows, cart approvals, and customer-group pricing, the starter delivers all of those features in a well-structured, production-tested codebase. You can deploy it, configure it for your product catalog and pricing tiers, and be live in weeks rather than months.

    The custom-module approach is the right choice when your B2B model has requirements that the starter does not accommodate cleanly. If your organization hierarchy has more than two levels, if your pricing logic requires inputs from an external system at request time, or if your approval workflow involves more than two parties, you will spend less time building cleanly from the recipe than adapting the starter to fit a structure it was not designed for.

    For a broader view of how Medusa.js handles the comparison against other headless platforms in a B2B context, the Medusa.js vs Shopify comparison guide on Askan Ecomm covers the fundamental differences in data ownership and customization depth that make headless the more appropriate choice for enterprise B2B requirements.

    Planning a B2B Medusa.js Implementation?

    Get Expert Guidance from the Askan Ecomm Development Team
    Let's Talk

    B2B commerce rewards platforms that bend to the business rather than forcing the business to bend to the platform. Medusa.js's Pricing Module, Customer Module, Workflow engine, and open extensibility model give development teams the right tools to build exactly the pricing hierarchy, buyer role structure, and approval flow their commercial relationships require. The official B2B recipe, the open-source starter, and real-world case studies from EKI and Visionary confirm that this is not theoretical capability. It is working in production B2B environments at scale today.

    The Askan Technologies team has published detailed thinking on API-first backend architecture that is directly relevant to the ERP integration patterns covered in this article. You can read that at askantech.com/medusa-js-ecommerce-development-company, which covers how Medusa.js fits within a broader enterprise commerce stack from an implementation partner's perspective.

    R

    Written by

    Raj Thilak

    CQO

    Ready to Transform
    Your Business?

    Build your next landing page fast & easy

    Available now

    Free consultation included. We'll review your requirements and provide a detailed proposal.