Building Marketplace Payments With Stripe: What the Docs Don't Tell You
Every marketplace eventually hits the same wall: moving money from one customer to your platform is the easy part. Moving it correctly between a customer, your platform, and a seller — while handling refunds, disputes, and payout timing without anyone ending up confused or shortchanged — is the part that actually consumes engineering time.
Stripe Connect is the right tool for most two-sided marketplaces, and the official documentation covers the happy path thoroughly. What it says very little about is the set of decisions that determine whether your support inbox is quiet or on fire six months after launch. This is what we've learned building marketplace payment flows, past the point where the docs stop being specific.
Standard, Express, or Custom — Choose Deliberately
This decision shapes the entire product, not just the payments layer, so it's worth resisting the urge to pick the option that looks fastest to build and moving on. Standard accounts hand most of the compliance burden and the entire dashboard experience to Stripe — fastest to ship, but you give up nearly all control over what the seller actually sees. Express accounts strike the balance most marketplaces need: a branded onboarding flow that feels like part of your product, while Stripe still owns the compliance weight behind it. Custom accounts hand you full control over the seller experience, at the cost of owning KYC, tax forms, and a long tail of edge cases yourself.
Our default recommendation for nearly every marketplace MVP is Express. Custom is a serious, ongoing commitment — the kind of decision that's rarely worth making before you have real transaction volume proving the product needs that level of control.
The Split Payment Itself Is the Easy Part
Taking a platform fee is genuinely simple — a couple of parameters on the charge:
application_fee_amount: platformFee,
transfer_data: { destination: connectedAccountId }Everything downstream of that call is where the real complexity lives, and it's the kind of complexity that doesn't show up until your first real dispute. What happens to your platform fee when a buyer disputes the charge months later? Who actually absorbs a refund — the platform, the seller, or some agreed split — and does your product even have a mechanism to enforce that split automatically? How do partial refunds get prorated against the fee you already took? What happens when a seller's account gets restricted by Stripe mid-transaction, with money already in flight? We write explicit answers to every one of these before a line of payment code gets written, because the alternative is improvising an answer during an actual dispute, with a confused customer on the other end of a support ticket.
Payout Timing Generates More Tickets Than You'd Expect
Sellers expect money to move instantly the moment a sale happens. Stripe payouts are not instant by default, and the gap between those two expectations is where a surprising share of marketplace support volume comes from. Design explicitly for standard payout schedules — rolling, daily, or weekly — and understand what each actually means for a seller's cash flow, because a weekly schedule that seemed reasonable in a planning meeting can feel brutal to a seller relying on that income. New accounts sit in a pending-balance risk review period that Stripe controls, not you, and instant payouts are a paid upsell option, not something to assume as the default experience. The single highest-leverage fix here isn't a policy change — it's UI. Most "where is my money" tickets disappear once the interface proactively tells a seller exactly when funds will land, instead of just confirming a transfer was "sent" and leaving them to wonder.
Refunds and Disputes Need a Written Policy Before Launch, Not During an Incident
We treat refund and dispute handling as a policy decision that has to exist in writing before the first real transaction, not something worked out ad hoc when the first dispute lands. That means deciding, explicitly: how a full refund is handled differently before payout versus after payout has already happened, how a partial refund affects the platform fee you've already collected, who's contractually liable for a chargeback — a decision that belongs in your Terms of Service, not improvised in a support thread — and what happens to a seller's balance when a dispute is ultimately lost. Without technical and contractual answers to all four of these before launch, your first real dispute becomes an engineering fire drill instead of a five-minute resolution.
Trust Webhooks, Not the API Response
Stripe is explicit about this in their own docs, and we've confirmed why the hard way: a successful API response is not the same thing as final state. A charge can succeed and then get reversed. A payout can fail after it's already been initiated. Treating the initial API response as "done" is how a marketplace ends up with a database that quietly disagrees with what actually happened in Stripe's system.
We build every marketplace payment system around webhook-driven state instead — idempotent handlers, since Stripe will retry and occasionally duplicate events by design, a real state machine per transaction rather than a handful of loosely related boolean flags, and a periodic reconciliation job that compares our database against Stripe's records and flags anything that's drifted out of sync.
Final Thoughts
Stripe Connect is genuinely excellent infrastructure, and the API surface itself is rarely where marketplace payment projects go wrong. The complexity lives in the business decisions around fees, refunds, disputes, and payout timing — decisions that have to be made explicit before you write code, not discovered in production during your first dispute. Get those decisions right early, and marketplace payments become a solved problem you rarely think about again, instead of a recurring fire.