Best Boilerplates for Marketplace Platforms 2026
Marketplaces Are One of the Hardest SaaS Categories
Two-sided marketplaces — platforms connecting buyers and sellers — have more moving parts than standard SaaS. You are not just building for one user type; you are building for two, with different needs, different dashboards, and a payment flow that splits revenue between your platform and each seller.
The complexity:
- Stripe Connect for split payments (platform fee + seller payout)
- Two onboarding flows (buyer vs seller, with seller identity verification)
- Listings management (CRUD for seller inventory)
- Reviews and reputation (trust infrastructure)
- Messaging between parties (in-platform communication)
- Dispute resolution (when things go wrong)
- 1099 tax reporting (for US marketplaces paying sellers)
No standard SaaS boilerplate handles all of this. You combine a boilerplate with custom marketplace infrastructure.
TL;DR
Best starting points for marketplace platforms in 2026:
- Stripe Connect + Next.js + any SaaS boilerplate — The payment infrastructure is the critical piece. Stripe Connect handles split payments and seller onboarding.
- Sharetribe Flex — Hosted marketplace platform for service and rental marketplaces. Not a boilerplate — a platform.
- OpenSaaS + custom marketplace — Free SaaS foundation; build marketplace layers on top.
- Payload CMS + Stripe Connect — Content-driven marketplaces (digital products, courses).
- T3 Stack + Stripe Connect — Developer-controlled, TypeScript-first marketplace foundation.
Key Takeaways
- Stripe Connect is required for any marketplace that splits payments — no alternative matches its compliance and onboarding UX
- Stripe Connect has two modes: Express (fast onboarding, Stripe handles payouts) and Custom (full control, more compliance work)
- Platform fee on Stripe Connect: take a percentage of each transaction via
application_fee_amount - Seller verification (KYC/KYB) is handled by Stripe — one of the biggest time-savers
- Digital product marketplaces (courses, templates) are simpler than service marketplaces (freelancers, rentals)
- Most marketplaces start with manual matching and add automated matching later
Stripe Connect: The Core Infrastructure
Stripe Connect is the only payment infrastructure worth considering for two-sided marketplaces in 2026.
Setting Up Stripe Connect
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
// Step 1: Create a connected account for a seller (Express mode):
export async function createSellerAccount(userId: string) {
const account = await stripe.accounts.create({
type: 'express',
country: 'US',
capabilities: {
transfers: { requested: true },
card_payments: { requested: true },
},
});
// Save the Stripe account ID to your database:
await db.user.update({
where: { id: userId },
data: { stripeAccountId: account.id },
});
return account.id;
}
// Step 2: Generate onboarding link for seller:
export async function getSellerOnboardingUrl(userId: string, returnUrl: string) {
const user = await db.user.findUnique({ where: { id: userId } });
if (!user?.stripeAccountId) throw new Error('No Stripe account');
const link = await stripe.accountLinks.create({
account: user.stripeAccountId,
refresh_url: `${returnUrl}?error=true`,
return_url: returnUrl,
type: 'account_onboarding',
});
return link.url;
}
// Step 3: Check if seller is fully onboarded:
export async function isSellerOnboarded(stripeAccountId: string): Promise<boolean> {
const account = await stripe.accounts.retrieve(stripeAccountId);
return account.charges_enabled && account.payouts_enabled;
}
Processing a Transaction with Platform Fee
// When a buyer purchases from a seller:
export async function createMarketplacePayment(
buyerId: string,
sellerId: string,
listingId: string,
amountCents: number // e.g., 5000 = $50.00
) {
const seller = await db.user.findUnique({ where: { id: sellerId } });
if (!seller?.stripeAccountId) throw new Error('Seller not connected');
const platformFeeCents = Math.floor(amountCents * 0.10); // 10% platform fee
const paymentIntent = await stripe.paymentIntents.create({
amount: amountCents,
currency: 'usd',
application_fee_amount: platformFeeCents,
transfer_data: {
destination: seller.stripeAccountId,
},
metadata: { buyerId, sellerId, listingId },
});
return paymentIntent.client_secret;
}
The buyer pays the full amount. Stripe routes amountCents - platformFeeCents to the seller and platformFeeCents to your platform. Stripe handles tax reporting (1099s for US sellers).
Listing Management
// Prisma schema for marketplace listings:
model Listing {
id String @id @default(cuid())
sellerId String
seller User @relation(fields: [sellerId], references: [id])
title String
description String
price Int // In cents
category String
images String[] // Array of CDN URLs
status ListingStatus @default(DRAFT)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
orders Order[]
reviews Review[]
}
enum ListingStatus {
DRAFT
ACTIVE
PAUSED
SOLD
}
model Order {
id String @id @default(cuid())
listingId String
buyerId String
sellerId String
amountCents Int
platformFee Int
status OrderStatus @default(PENDING)
stripePaymentId String?
createdAt DateTime @default(now())
}
model Review {
id String @id @default(cuid())
listingId String
buyerId String
rating Int // 1-5
comment String
createdAt DateTime @default(now())
}
Seller Dashboard vs Buyer Dashboard
// Seller dashboard API routes:
// GET /api/seller/listings - their listings with analytics
// GET /api/seller/orders - orders for their listings
// GET /api/seller/payouts - payout history from Stripe
// GET /api/seller/earnings - revenue summary
// Seller payout history from Stripe:
export async function getSellerPayouts(stripeAccountId: string) {
const payouts = await stripe.payouts.list(
{ limit: 20 },
{ stripeAccount: stripeAccountId }
);
return payouts.data;
}
// Buyer dashboard:
// GET /api/buyer/orders - their purchase history
// GET /api/buyer/reviews - reviews they have left
In-Platform Messaging
For service marketplaces where buyers and sellers need to communicate:
// Simple messaging schema:
model Conversation {
id String @id @default(cuid())
buyerId String
sellerId String
listingId String
createdAt DateTime @default(now())
messages Message[]
}
model Message {
id String @id @default(cuid())
conversationId String
conversation Conversation @relation(fields: [conversationId], references: [id])
senderId String
content String
createdAt DateTime @default(now())
readAt DateTime?
}
For real-time messaging, add Supabase Realtime subscriptions on the messages table filtered by conversation_id.
Platform Fee Structures
| Fee Model | How It Works | Best For |
|---|---|---|
| Percentage fee | 5-20% of each transaction | Most marketplaces |
| Listing fee | Charge sellers to list | Etsy-style, high-volume items |
| Subscription + percentage | Monthly fee + reduced % | High-volume sellers |
| Flat fee per transaction | $X per order | High-ticket items |
| Freemium | Free to list, % on sales | Building initial supply |
Stripe Connect handles all of these. The application_fee_amount parameter is the platform's cut per transaction.
Digital Product Marketplaces
Simpler than service marketplaces — no escrow, no disputes, instant delivery:
// Digital product delivery after payment:
export async function handleSuccessfulPayment(paymentIntentId: string) {
const payment = await stripe.paymentIntents.retrieve(paymentIntentId);
const { listingId, buyerId } = payment.metadata;
const listing = await db.listing.findUnique({
where: { id: listingId },
select: { downloadUrl: true, sellerId: true },
});
// Create download token (expires in 24h):
const token = await db.downloadToken.create({
data: {
listingId,
buyerId,
token: randomBytes(32).toString('hex'),
expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000),
},
});
// Send download link to buyer:
await sendEmail({
to: buyer.email,
subject: 'Your purchase is ready',
body: `Download your file: ${process.env.NEXT_PUBLIC_URL}/download/${token.token}`,
});
}
Recommended Stack by Marketplace Type
| Marketplace Type | Stack |
|---|---|
| Digital products | Payload CMS + Stripe Connect + Next.js |
| Service marketplace | T3 Stack + Stripe Connect + messaging |
| Rental marketplace | Sharetribe Flex (hosted) or custom |
| Freelancer platform | OpenSaaS + Stripe Connect + Escrow |
| Course marketplace | ShipFast + Stripe Connect + video (Mux) |
Methodology
Based on publicly available information from Stripe Connect documentation, marketplace builder communities, and public examples as of March 2026.
Building a marketplace? StarterPick helps you find the right SaaS boilerplate foundation before you layer on marketplace-specific features.