Merchanta
Wholesale purchasing for the buying side and the selling side at once.
- Role
- Frontend architecture · UI
- Year
- 2026
- Stack
- React · TS · TanStack
- Status
- Self-directed showcase
Price is a range, not a number
In wholesale the same SKU has several prices at once — a tier ladder, a contract rate, a minimum order quantity, and whatever a supplier will counter for a large enough release. A single price label cannot carry that, so the product page shows the whole ladder and marks the tier the buyer is actually in.
The quantity field is the pivot: it drives the tier highlight, the extended total, and whether the primary action is add-to-order or request-a-quote.
One basket, several purchase orders
A wholesale basket is not one order. It is grouped by supplier, each group carrying its own terms, freight and minimums, and it resolves into a separate purchase order per supplier on approval. The checkout is built around that grouping instead of hiding it, and a line that misses a supplier minimum says so where the line is, with the adjustment that fixes it.
A quote round you can still read months later
An RFQ is a conversation with money in it, and the part that usually gets lost is why a price changed. Each round puts list, requested and countered price on one row, keeps the message thread beside it, and states plainly what accepting would create.
A quote round is a row: list, requested and countered price side by side, so a negotiation can still be read months later.
The supplier sees the same price list
The vendor portal is not a second product. It reads the same catalogue, the same contracts and the same quote rounds from the other side, which is what keeps a counter-offer and a price list from drifting apart.
An order is a set of shipments
A purchase order rarely arrives at once. The order page is built around partial fulfilment: each shipment carries its own status and tracking, received quantities are reconciled against ordered quantities line by line, and a discrepancy is a state the page can show rather than an exception someone has to email about.
A proof link renders only once its destination exists.