Case Study

UVP Veltopak's packaging storefront: A self-service wholesale store on nopCommerce 4.70

UVP Veltopak is a South African packaging manufacturer based in Cape Town. It supplies printed board, corrugated packaging, napkins, bags, and straws to food and beverage businesses across South Africa and sub-Saharan Africa. Unlike typical online shoppers, its trade customers buy at negotiated prices, use credit accounts, and often require quotes for custom packaging.
UVP Veltopak's packaging storefront: A self-service wholesale store on nopCommerce 4.70
UVP Veltopak's packaging storefront: A self-service wholesale store on nopCommerce 4.70 that earned R 172,869 in profit in its first 5 months
Statistics #1
Built one wholesale store (nopCommerce 4.70) that sells both bespoke and generic packaging to logged-in trade buyers.
Statistics #2
Connected the store to the accounting system (Sage Evolution), keeping six data types in sync on a nightly run.
Statistics #3
A single trade account placed four paid orders worth over R 74,000 in about 14 minutes, across roughly 170 units.

A brief background on UVP Veltopak

UVP Veltopak is a South African packaging manufacturer, established in 1995 and based in Epping, Cape Town. A subsidiary of Gerber Goldschmidt SA, it makes printed board, corrugated packs, napkins, bags, and straws for food and beverage businesses across South Africa and sub-Saharan Africa. These buyers do not shop like consumers. They buy at a negotiated rate, pay on credit, and often order branded print that needs a quote first. Standard ecommerce software is built for shoppers, not for a manufacturer selling this way.

Challenges

UVP needed one store where trade buyers could serve themselves, with the accounting system still in charge of customers, stock, and prices. Standard nopCommerce follows a retail model with a public price and a checkout-first cart, which does not fit a wholesale catalog mixing bespoke branded SKUs with generic pack. After reviewing the platform and the commercial rules, the team identified the challenges below.

A Catalog for Trade Buyers, Not Shoppers: The store had to sell the way wholesalers do: the buyer's own price, a pack size, and live stock, with no shelf price for bespoke work. Standard ecommerce shows a price on every product (nopCommerce), and left as is, any visitor would see the trade rate.

The Right Customer Account for Every Buyer: Every user had to attach to a real trade account carrying a credit limit, balance, price group, and delivery branches (Sage Evolution). A generic sign-up form would push an order to the wrong account, and the factory would invoice the wrong customer.

A Quote and a Sale in the Same Basket: Bespoke packaging often starts as a quote, but the platform (nopCommerce) is built to check out. Without a clear split, an enquiry would post as a sale, while the basket still had to keep prices exclusive of VAT and the pack quantities intact.

Account, Group, and Special Pricing Across the Catalog: List prices are often zero or call for price, with the real rate held in the price groups and special prices of the accounting system (Sage Evolution). Recreating those rules in the store would drift from the ERP, and across thousands of SKUs, the price had to resolve per account.

Two Product Worlds on One Store: MY SPACE holds bespoke, customer-branded print such as solid board, corrugated, napkins, and bags. OTHER COOL STUFF holds generic and unprinted pack. One store had to keep these ranges apart so a brand buyer was not sent into raw board and reels.

Pack Sizes, Stock, and Credit the ERP Already Owns: Trade units such as 100 per pack, live stock, credit limits, and delivery addresses live in the accounting system (Sage Evolution). If the store ignored them, a buyer could order the wrong unit or be promised stock the factory does not have.

Our Solution

The team built on the existing platform (nopCommerce 4.70) with a set of B2B and ERP modules, and added custom logic where the quote rules needed it. The store runs on .NET 8 with a SQL database on Comalytics hosting, using a custom theme with instant search and a mega menu.

Login-Gated Store and Two Product Worlds: Anonymous visitors land on a branded sign-in and apply-to-shop screen. Once logged in, the store splits into MY SPACE for bespoke printed packaging and OTHER COOL STUFF for generic pack. Search, the menu, and category grids stay shared, and prices and account terms appear only for a buyer linked to an ERP account.

Apply to shop online: account number and account name required

Image 1.2: Apply to shop online: account number and account name required

Registration That Joins an Existing Trade Account: Registration asks for the Sage account number and account name along with personal and company details, so the web user joins an existing trade account. Admin can see each account's credit limit, balance, user count, and delivery branches, with payment on account handled by the B2B account module (Payments.B2BAccount) and prices entered exclusive of VAT.

Admin ERP accounts with credit limit and ship-to branches

Image 1.3: Admin ERP accounts with credit limit and ship-to branches

A Price Resolved for the Buyer Who Is Logged In: Product pages show the price for the buyer who is logged in rather than one public value. A mapped buyer sees their own rate from their price group or special price code (Sage Evolution), while anonymous visitors see Call for pricing. SKU, availability, and pack size stay visible either way, so a buyer can see thousands of units of a scoop and a pack of 100 without seeing the contract rate.

Product detail: stock, SKU, account-resolved pricing, and pack UOM (500/Pack)

Image 1.4: Product detail: stock, SKU, account-resolved pricing, and pack UOM (500/Pack)

Pricing Rules Fetched From the Accounting System: Administrators manage the price codes the accounting system (Sage Evolution) uses for accounts, including customer-specific codes and a wholesale tier. Scheduled jobs refresh group and special prices so the store never becomes a second price book.

Admin ERP group price codes kept in sync with Sage Evolution

Image 1.5: Admin ERP group price codes kept in sync with Sage Evolution

Quote and Checkout, Then the Right Document: The basket keeps a six-step trade checkout and offers Quote and Checkout, and lets buyers save a basket to favourites. Order records tell the ERP what the order is: a B2B sales order, a B2B quote, a B2C sales order, or a B2C quote. Confirmed B2B sales orders get a Sage sales-order number, and a failed post can be retried from admin.

Shopping cart: Quote and Checkout on the same basket, prices excluding VAT

Image 1.6: Shopping cart: Quote and Checkout on the same basket, prices excluding VAT

Overnight Sync Keeps the Store Honest: A sync module (ErpSqlIntegration) holds the queries the accounting system (Sage Evolution) must share, account, ship-to, product, group price, special price, and stock, and a scheduler (ErpDataScheduler) runs them on a timetable. Incremental runs keep the load light for accounts and stock; a full refresh keeps the price book complete. Jobs run overnight so the morning catalog matches the factory's records.

Admin ERP data scheduler sync tasks

Image 1.7: Admin ERP data scheduler sync tasks

Together these let one store run as a wholesale packaging counter, with the accounting system (Sage Evolution) still the single source of truth for customers, prices, and documents.

Results:

  • Delivered one trade storefront (nopCommerce 4.70) handling both bespoke and generic packaging on one site.
  • Connected the store to the accounting system (Sage Evolution), keeping customers, products, stock, and prices aligned overnight.
  • Replaced public list pricing with each buyer's own rate, SKU, stock, and pack size, so trade rates are never exposed.
  • Let a buyer run a quote and a sale from the same basket, posting each as the right document in the ERP.
  • Enabled one trade account to place four paid orders worth over R 74,000 in about 14 minutes, across roughly 170 units.
  • Enabled account-based selling that captured R 195,091 in orders, with R 172,869 in profit, in its first 3 months.

Book a Meeting