Skip to content
← All work

Order-to-shipment platform for a hemp/CBD distributor

B2B Wholesale Ordering Platform

Replaced a distributor's legacy wholesale site with an in-house Java platform: live inventory, multi-carrier shipping rates, quotes, payments and a sales dashboard.

My role: Full-stack Java developer on the client's in-house platform, one tested commit per Jira ticket

Discuss a similar project
  • Java 8
  • JSF / PrimeFaces
  • Hibernate
  • PostgreSQL
  • UPS / USPS

Overview

The company behind PriorityLab, a US environmental testing laboratory with labs in Fort Lauderdale and Indianapolis that analyses mold, radon, water, lead and asbestos samples and makes its own BREEZE testing equipment, runs its manufacturing and ordering on an in-house Java platform. Its multi-brand hemp/CBD wholesale distribution business still took orders through an aging third-party site, with no live inventory, manual shipping quotes and no visibility into sales activity. I ported and extended the in-house platform to cover the whole wholesale flow: product browsing, quoting, checkout and payment, shipping and sales reporting, for both sales reps and wholesale clients.

The challenge

The distributor's sales reps and wholesale clients ordered through an aging third-party website. It had no live inventory, so clients could order products that were out of stock; shipping had to be quoted by hand; and managers had no view of what the sales floor was doing.

The same company runs PriorityLab, an environmental testing laboratory, on an in-house Java platform for manufacturing and orders. The goal was to bring wholesale ordering onto that existing platform, so catalog, stock, quotes, shipping, payment and reporting all worked from the same data, without disrupting the other developers working on the same codebase.

How it works

  1. 1Rep or client browses
  2. 2Quote or cart
  3. 3Solving Maze packing
  4. 4UPS / USPS live rates
  5. 5Authorize.net payment
  6. 6Order + sales dashboard

Architecture

The platform is Java 8 with JSF (Mojarra) and PrimeFaces on Apache Tomcat, Hibernate ORM and PostgreSQL. Employee and client order screens share Facelets composite components, with a three-level menu (Actives, Type, Brand, Cart) and descriptor filters over the catalog.

Shipping starts from product, part and component dimensions. These go to the Solving Maze API, which decides how items pack into boxes, including combined packaging and outer-box items. The packed boxes are then priced against the UPS and USPS APIs for every enabled carrier, with markup and a pickup option. Quotes store the chosen ship-to profile, method and price, so a converted quote checks out with exactly the shipping the client agreed to.

Checkout charges through Authorize.net CIM customer profiles, supporting cards, bank accounts, payment plans and a no-payment option for staff. Availability for the whole catalog comes from a single grouped SQL query based on the limiting component's stock. The Sales Floor Feed joins orders and revenue with 3CX call detail records for calls and talk time, and quote PDFs are rendered from HTML with Flying Saucer and iText.

What I built

Multi-carrier shipping calculator

Product, part and component dimensions feed the Solving Maze API for box packing, then live UPS and USPS rates are pulled for every enabled carrier with markup, including combined packaging, outer-box items and pickup.

Checkout with integrated payments

A checkout dialog shows live shipping options and Authorize.net CIM payment methods — cards, bank accounts, payment plans, or no payment for staff — and charges at order placement.

Quotes with locked-in shipping

Reps save ship-to, method and price on a quote; when it converts to an order, checkout uses and pre-selects the quoted shipping. Quote PDFs and the public view show it too.

Live inventory and Sold Out

Available quantity is calculated from component stock (the limiting component divided by part quantity), shown in red when short; the client portal shows Sold Out and caps order quantities.

Dynamic catalog

A three-level menu (Actives → Type → Brand → Cart) replaced static tabs on employee and client order screens, with descriptor filters and list or grid views.

Sales Floor Feed dashboard

Per-rep revenue, orders, inbound and outbound calls and talk time from 3CX call records, activities and new accounts, with date-range search and Excel export.

Engineering decisions

  • Profile before optimising: server-side timing showed the slow order pages were caused by browser rendering of very large product lists, not the database.
  • Compute stock for the whole catalog in one grouped SQL query (about 5 ms) instead of per-product lookups.
  • Refresh only the changed row on quantity edits instead of re-rendering the whole table.
  • Add new entity fields as nullable through Hibernate schema updates so existing production rows migrate safely.

Results

  • Ordering moved off the legacy third-party site onto the in-house platform for reps and clients.
  • Live UPS and USPS rates with automated box packing, replacing manual shipping quotes.
  • Whole-catalog stock availability from one SQL query in about 5 ms, with Sold Out shown to clients.
  • Every feature delivered as a separate tested commit tied to a Jira ticket.

Stack

Backend
Java 8, JSF (Mojarra), Hibernate ORM, Apache Tomcat
UI
PrimeFaces (Morpheus), Facelets composite components, JSP
Data
PostgreSQL
Shipping
UPS API, USPS API, Solving Maze packaging optimiser
Payments & telephony
Authorize.net CIM, 3CX call detail records
Documents & tooling
Flying Saucer / iText (HTML → PDF), SVN, Jira, Maven

Related services

Need something like this?

I can build a version of this for your product, your data and your stack.

Start a project