Skip to content
Zyntrivia
Case Study · Built by Zyntrivia · MARKETPLACE

A two-sided marketplace, including the boring parts nobody demos.

A multi-category service marketplace with the full provider lifecycle implemented — onboarding, verification, split payments via Stripe Connect, refunds, and two honest dashboards.

Next.js 14Stripe ConnectPostgreSQLPrisma

The problem

Marketplace MVPs are easy to fake and hard to ship. The demo — a grid of listings and a checkout button — takes a weekend. The actual product is everything after: onboarding third-party providers, verifying them, splitting payments, handling refunds when the provider has already been paid, and giving both sides a dashboard that tells them the truth. That's where marketplace builds die, and it's the part most agencies quietly leave for "phase two."

What we built

A multi-category service marketplace with the full provider lifecycle implemented.

  • Provider onboarding. Self-serve signup → profile and service catalog → verification → live. Stripe Connect onboarding embedded in the flow, so a provider can be taking payments the same day.
  • Multi-category taxonomy. Categories, sub-categories, and per-category service attributes — so a new vertical is a config change, not a migration.
  • Booking and payment. Customer books, pays; funds are held, split at completion, and paid out to the provider net of platform fee. Refunds and disputes handled at the Connect level.
  • Two dashboards. Providers see bookings, earnings, and payouts. Admins see providers, transactions, disputes, and platform revenue.
  • Search and filtering across category, location, availability, and price.

Architecture

Architecture Overview
ClientNext.js 14 App Router
Booking lifecycleWebhook-driven state machine
PaymentsStripe Connect · Express accounts
DataPostgreSQL · Prisma

Next.js 14 App Router. Stripe Connect (Express accounts) for the money. Postgres/Prisma. Webhook-driven state machine for the booking lifecycle — every payment state transition is driven by a verified Stripe webhook, never by an optimistic client callback.

Engineering decisions

Why webhook-driven state, not client callbacks? Because a customer closing the tab after paying is a normal event, and a marketplace that loses that booking is broken. Webhooks are the only source of truth the network can't drop.

Why Stripe Connect over building payouts? Money transmission, KYC, and 1099/tax reporting are not places to be original. Connect absorbs the compliance surface entirely.

Idempotency everywhere. Every payment-adjacent handler is keyed and replay-safe, because Stripe will deliver the same webhook twice and eventually does.

What it does, measured

  • Provider goes from signup to accepting payments in Benchmark: time the flow
  • Booking lifecycle survives tab-close, double-submit, and duplicate webhook delivery — all three tested
  • New service category added via config in Benchmark: time it, no schema change

Adaptable for: home services, professional services, rentals, freelance and creator marketplaces, B2B supplier networks.

Have a system like this in mind?