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.
Trust Infrastructure: Reviews, Reputation, and Fraud Prevention
Two-sided marketplaces live and die on trust between buyers and sellers. The technical infrastructure for trust — reviews, reputation scores, identity verification — is often treated as a later-stage concern and built too late, causing early retention problems.
Reviews should be collected within 48–72 hours of transaction completion while the experience is fresh. A delayed review request (7 days after delivery) gets 3–5x lower response rates than an immediate one. The review schema above captures the basic data (rating, comment, reviewer ID). The trust infrastructure around it matters more: only buyers who completed a transaction can review (verified purchase requirement), review content is moderated (at minimum, filtered for prohibited content), and both buyers and sellers can see each other's review history before transacting.
Reputation aggregation should be denormalized for performance. A sellerStats table or a cached aggregate on the User record (total sales, average rating, response rate, completion rate) prevents expensive aggregate queries on the reviews and orders tables on every listing page load. Update these aggregates asynchronously when new reviews or orders are created.
Fraud prevention is the hardest trust problem. Stripe Connect handles identity verification (KYC) for sellers as part of the onboarding process — you don't need to verify sellers yourself. But buyer fraud (chargebacks after delivery, claiming non-delivery for digital products) and seller fraud (not delivering, misrepresenting the product) require platform-level policies, not just technical controls.
For digital product marketplaces, the practical fraud prevention stack: require verified email for purchases (reduces anonymous fraud), use Stripe Radar for fraud scoring on payment intents (blocks known fraud patterns), implement a 3–7 day payout delay for new sellers (time to detect fraudulent accounts before they withdraw funds), and log delivery evidence for digital goods (timestamp when the download link was generated and accessed). These four measures handle 90%+ of marketplace fraud at early stage without requiring a dedicated fraud team.
Geographic Expansion and Multi-Currency Support
Stripe Connect handles currency conversion and international payouts, but there are implementation decisions that affect how well your marketplace works globally.
By default, Stripe charges buyers in your platform's currency and converts to the seller's local currency. A US marketplace charging in USD will show European buyers a USD amount — fine for developer tools and digital products, worse for consumer marketplaces where local currency is expected. Stripe supports presentment currency (the currency the customer sees) separately from settlement currency (the currency you deposit to your bank). Implementing presentment currencies requires detecting the user's location (from IP or browser locale), setting currency on the PaymentIntent to the localized currency, and handling the rate difference in your platform fee calculation.
Seller payout currencies depend on the seller's Stripe connected account country. A UK seller automatically gets paid in GBP; a Brazilian seller in BRL. Stripe handles the conversion. The complication: your platform fee is a percentage of the transaction amount, and that percentage is calculated before currency conversion. This is fine for standard marketplace transactions. For subscription-based marketplace products (monthly access to seller content), the subscription amount should be set in the presentment currency, not converted after the fact.
Multi-currency pricing — where sellers set different prices for different markets — requires a prices table with currency variants per listing. This is common for SaaS marketplaces (different price for USD vs EUR markets). The implementation: Listing has a basePrice plus a ListingPrice join table with currency and amount columns. At checkout, select the price matching the buyer's presentment currency.
Scaling the Supply Side: Seller Acquisition and Retention
The technical build matters, but the hardest marketplace problem is acquiring and retaining high-quality sellers. Technical decisions affect this more than most founders realize.
Seller onboarding friction directly correlates with supply-side conversion rate. Every additional step in the Stripe Connect onboarding (the KYC verification flow) reduces the percentage of potential sellers who complete it. Stripe Express accounts minimize friction — sellers provide basic information and Stripe handles the rest. Custom accounts give you more control but require you to implement the verification flow yourself, which increases both development time and seller dropout rate. Default to Stripe Express unless you have specific reasons to need Custom accounts.
The seller dashboard experience affects retention. Sellers who can see their earnings in real time, understand why payouts are delayed (the T+2 standard payout delay), and manage their inventory without contacting support stay active longer. The payout history endpoint in the code above provides earnings visibility. Add a "when will I get paid?" calculator that shows the next payout date and estimated amount based on pending orders and the settlement delay.
Seller discovery (how buyers find sellers) is a technical decision with business impact. Search ranking for sellers (should new sellers be ranked lower until they have reviews? how much weight to give response rate vs review score?) affects whether new sellers get their first transactions. A marketplace that systematically starves new sellers of visibility has a supply acquisition problem — sellers churn before they earn anything. Default ranking for new sellers should include a "new seller boost" that decays over 30 days, giving new supply a chance to establish a review history before competing solely on aggregate score.
Read the best SaaS boilerplates guide to find a strong foundation before building marketplace layers on top.
See the Stripe vs LemonSqueezy vs Polar comparison — for marketplace platforms, Stripe Connect is required, but understanding the broader payment landscape helps with ancillary product decisions.
Read the best multi-tenant SaaS boilerplates guide — marketplace platforms are a specialized form of multi-tenancy where the tenant is the seller.