A set of plugins on nopCommerce 4.80 adds company accounts with team roles, contract and level pricing from NetSuite, PO-based B2B checkout, live stock checks and order export to NetSuite as quotes.
Starting point
The client distributes industrial equipment and already sold online through nopCommerce. The store was built for retail: one customer, one login, one price. Trade customers ordered by phone and email, and an older plugin copied products and stock from NetSuite on a schedule with separate credentials for each sync.
NetSuite holds the customers, contacts, price levels, contract prices, credit terms and orders. The portal had to follow NetSuite rather than become a second source of truth, and retail shoppers could not be affected.
What we built
Everything was built as nopCommerce plugins, so the B2B features can be maintained and upgraded separately from the core. The work is split into a domain plugin (accounts, pricing and order context, with its own database schema), a commerce plugin (storefront and admin), a NetSuite integration plugin and a payments plugin.
- Company accounts with several logins and Admin, Buyer and Viewer roles, managed by the customer from a trade dashboard
- A custom price calculation service: promotion price, then contract price, then price level, then base price, all mastered in NetSuite
- A switch between showing the trade price and the buy price
- B2B checkout with PO reference, ordering on behalf of another account user, and an audit log
- Company account requests, contact onboarding and bulk onboarding from an Excel upload
- Saved quotations with PDF and email, back-order handling with expected dates, and free-gift lines from NetSuite promotions
- A product sizing calculator that recommends products from the customer’s requirements
How the NetSuite integration works
- Products, stock, prices, promotions, customers, customer groups and ship-to addresses sync from NetSuite on a schedule
- New items from NetSuite go to a review queue instead of being created automatically; products are matched by SKU
- Every B2B order goes to NetSuite as a quote first, through an export queue with retries, so an order is never sent twice
- Stock is checked live against NetSuite when a product is added to the cart, at checkout and when the order is placed
- Customer records are created in NetSuite only when there is an order or an admin approves it, not on every registration
- A signed webhook (HMAC-SHA256 with replay protection) lets NetSuite push sales-order updates instead of the portal polling for them
How we delivered it
The project ran in phases over about ten months and more than 1,400 commits. Each phase shipped behind protected branches with reviewed pull requests.
- Automated tests for the domain, team management, NetSuite integration and product data exchange
- Every deploy to the test site runs an automated browser test that places an order
- Production releases are manual and approval-gated, run only in an overnight window, and take a backup, show a maintenance page and run a smoke check
- Performance work on listings and the cart: N+1 queries removed and a caching layer added for B2B data
Where it stands
The portal is in use and still being extended. The same plugins are now being moved into a second store run by the same group, in planned stages with their own test checkpoints.