Skip to content
Web DevelopmentB2B trade / marketplace

Kontractz — B2B Trade Marketplace Platform

A custom B2B trade platform — trade leads, RFQs, vendor storefronts, deal rooms and memberships — built as an application rather than a website.

Client
Kontractz
Industry
B2B trade / marketplace
Services
Platform development · Web development · Database design · Payments integration

What this is based on: Full application source in the repository (Next.js, Prisma schema, 56 routes) plus the live site. Every feature listed below was read from the code, not from a brief.

Kontractz B2B trade marketplace architecture — buyers, sellers, deal rooms

Kontractz is a B2B trade marketplace connecting buyers and suppliers around trade leads, product listings and negotiated deals. It is not a brochure site with a contact form bolted on — it is a multi-role application with authenticated dashboards, a document-bearing deal workflow, real-time messaging and paid memberships.

Project type
Custom B2B marketplace platform
Sector
B2B trade / marketplace

The challenge

A trade marketplace has to serve two populations with opposite needs from the same data. Buyers want to describe a requirement once and reach qualified suppliers. Suppliers want visibility, and control over what they publish. Both then need somewhere for a negotiation to happen that is more structured than email and more auditable than a chat thread — with documents attached to the stage of the deal they belong to.

The objectives

  • One platform serving buyers, sellers, startups and investors without four separate products
  • Trade leads and RFQs that route to relevant suppliers rather than broadcasting
  • A structured deal workflow with documents attached to stages, not to an inbox
  • Paid membership tiers with real gating, billed automatically
  • An admin layer able to moderate every entity on the platform
  • Multi-language support from the start rather than retrofitted

Approach

Model the domain before building any interface. A marketplace lives or dies on whether its data model reflects how trade actually works — who owns a lead, what states an order moves through, what a deal room contains at each stage. Those decisions were made in the Prisma schema first, and the interfaces were built against them.

Implementation

Data model first

The schema defines the platform. Around thirty models and twenty enumerations covering:

DomainModels
IdentityUser, Account, Session, VerificationToken, UserRole
Supply sideVendor, Product, ProductInquiry
Demand sideLead with typed states, RFQ flow
TransactionsOrder, OrderEvent, OrderDoc, OrderMessage
NegotiationDealRoom, DealStageData, DealParticipant, DealAction, DealStageDoc, DealMessage
CommercialMembershipPlan, UserMembership, Payment
CapitalStartup, Investor
PlatformConversation, Message, Notification, UserDocument, Setting

The deal-room cluster is the part that makes it a trade platform rather than a directory. A deal has stages; each stage has its own data, its own documents and its own action history. That structure is what allows a negotiation to be audited afterwards, which is the thing email cannot do.

Typed enumerations rather than free-text status fields throughout — LeadStatus, OrderStatus, DealStage, VendorStatus and the rest. Status as a string is how marketplaces end up with six spellings of "pending" and reporting nobody trusts.

Application structure

Next.js App Router, with routes grouped by audience:

  • Public marketplace — products, vendors, trade leads, RFQ, post-requirements, investments, plus separate explainer routes for buyers and for sellers
  • Authentication — login, register, forgot-password, reset-password
  • Member dashboard — leads, products, orders, inquiries, messages, deal rooms, documents, membership, notifications, profile
  • Administration — members, vendors, products, orders, leads, inquiries, deal rooms, documents, investments, membership plans, messages, notifications, backup, and settings including email and Stripe configuration

Every locale-aware route sits under a locale segment, so internationalisation is structural rather than a translation layer bolted on afterwards.

Real-time and asynchronous work

Pusher carries live messaging and notifications, so a buyer sees a supplier's reply without refreshing. Email runs through Resend with Nodemailer as the transport fallback, and React Email for templating — transactional mail that renders consistently matters more on a platform where a missed notification is a missed deal.

File handling goes through UploadThing, which keeps document uploads off the application server.

Commercial layer

Stripe handles membership billing. Plans are data rather than code — MembershipPlan with UserMembership recording status — so tiers can change without a deployment. Payments are recorded as their own entity with typed status rather than being inferred from Stripe webhooks alone.

Administration

The admin surface covers every entity, not a subset. That is deliberate: a marketplace where the operator cannot moderate a listing, a lead or a deal without a developer is a marketplace that stops working the first time something needs intervening on.

Technology

  • Next.js (App Router)
  • TypeScript
  • Prisma
  • MySQL
  • NextAuth
  • Stripe
  • Pusher
  • UploadThing
  • Resend
  • React Email
  • next-intl
  • TanStack Query
  • Zustand
  • Radix UI
  • Tailwind CSS
  • Zod

Functionality

live

Live on kontractz.com

  • Public marketplace: product listings, vendor profiles, trade leads
  • Separate onboarding paths for buyers and for sellers
  • Post a trade lead / post requirements
  • RFQ entry point
  • Startups and investors listings
  • Account registration and login
  • Member dashboard
implemented

Implemented in the codebase

  • Deal rooms with per-stage data, documents, participants and action history
  • Order lifecycle with events, documents and per-order messaging
  • Product inquiries routed to vendors
  • Direct conversations and messaging, with Pusher for real-time delivery
  • Membership plans and subscriptions with Stripe billing
  • Document vault per user
  • Notification system with typed notification kinds
  • Full administration panel across every entity, including email and Stripe settings
  • Platform backup route in the admin area
  • Multi-language routing via next-intl

Decisions worth explaining

Typed enumerations for every status field

Free-text status is how a marketplace ends up with six spellings of 'pending' and reporting nobody believes. Enumerations make invalid states unrepresentable and keep the admin filters honest.

Deal rooms modelled as staged entities rather than a chat thread

A negotiation that lives in a chat log cannot be audited. Attaching documents and actions to the stage they belong to is what makes the history usable after the fact — which is the whole reason a business would use a platform instead of email.

Membership plans stored as data, not code

Pricing and tier structure on a marketplace change more often than the software does. Plans in the database mean a commercial change is an admin action rather than a deployment.

Internationalisation designed in from the start

Retrofitting locale routing onto an application with sixty routes is substantially more work than starting with it, and trade platforms are cross-border by definition.

What it produces

A production B2B marketplace running at kontractz.com, with the public marketplace, registration and member dashboard live, and the full deal-room, order, membership and administration layer implemented in the codebase. No traffic, transaction or revenue figures are claimed here — none were supplied or measured, and the platform's commercial performance is the client's data, not mine to publish.

What it teaches

  • On a marketplace, the schema is the product. Interfaces are comparatively cheap to change; a wrong data model is not.
  • Separating 'live' from 'implemented' is worth doing honestly — a platform of this size always has more built than is switched on.
  • Real-time messaging changes the support burden more than it changes the user experience, and that cost belongs in the plan.

What this project demonstrates

  • Multi-role application architecture — four audiences served from one data model.
  • Domain modelling as the first deliverable, not an implementation detail.
  • Payments, real-time messaging, file handling and transactional email integrated as a working system rather than as separate features.
  • An administration layer scoped to every entity, so the operator is never blocked on a developer.

Related services

Related guides

Worked examples

FAQ

Questions about this project

If yours isn't here, send it over — I reply within one working day.

A B2B trade marketplace. Buyers post trade leads and requirements, suppliers list products and maintain vendor profiles, and negotiations run through structured deal rooms rather than email.

Next.js with the App Router and TypeScript, Prisma against MySQL, NextAuth for authentication, Stripe for membership billing, Pusher for real-time messaging, UploadThing for file handling, Resend for transactional email, and next-intl for multi-language routing.

The deal-room model. Getting stages, documents, participants and actions into a structure that is auditable afterwards, without making the interface unusable, took more iteration than any other part of the platform.