Stripe Connect: Building a Marketplace With Split Payments
Marketplaces need to split payments between the platform and sellers. Stripe Connect handles the complex parts: onboarding sellers, splitting funds, handling payouts, and staying compliant.
Connect Account Types
Express — Stripe-hosted onboarding, Stripe handles KYC. Best for most marketplaces.
Standard — Sellers have full Stripe accounts. Platform gets limited control.
Custom — Full control, full liability. Complex, only for large platforms.
Onboarding a Seller
// Create a Connect account
const account = await stripe.accounts.create({
type: 'express',
country: 'US',
email: seller.email,
capabilities: {
card_payments: { requested: true },
transfers: { requested: true },
},
});
// Save account ID to your database
await db.seller.update({
where: { id: seller.id },
data: { stripeAccountId: account.id },
});
// Create onboarding link
const accountLink = await stripe.accountLinks.create({
account: account.id,
refresh_url: `${BASE_URL}/sellers/onboarding/refresh`,
return_url: `${BASE_URL}/sellers/onboarding/complete`,
type: 'account_onboarding',
});
// Redirect seller to accountLink.url
Checking Onboarding Status
async function isSellerReady(stripeAccountId: string): Promise<boolean> {
const account = await stripe.accounts.retrieve(stripeAccountId);
return account.details_submitted && account.charges_enabled;
}
Taking a Payment With Platform Fee
// Checkout Session with application fee
const session = await stripe.checkout.sessions.create({
mode: 'payment',
payment_method_types: ['card'],
line_items: [{
price_data: {
currency: 'usd',
product_data: { name: product.name },
unit_amount: product.priceInCents,
},
quantity: 1,
}],
payment_intent_data: {
application_fee_amount: Math.floor(product.priceInCents * 0.10), // 10% fee
transfer_data: {
destination: seller.stripeAccountId, // Seller gets the rest
},
},
success_url: `${BASE_URL}/success`,
cancel_url: `${BASE_URL}/cancel`,
});
Manual Transfers
// Transfer funds to seller after your own processing
const transfer = await stripe.transfers.create({
amount: sellerAmountInCents,
currency: 'usd',
destination: seller.stripeAccountId,
transfer_group: `ORDER_${orderId}`,
});
Webhook Events to Handle
switch (event.type) {
case 'account.updated':
// Check if seller completed onboarding
const account = event.data.object;
if (account.charges_enabled) await markSellerActive(account.id);
break;
case 'payment_intent.succeeded':
await fulfillOrder(event.data.object.metadata.orderId);
break;
case 'transfer.created':
await logSellerPayout(event.data.object);
break;
}
Dashboard Link for Sellers
// Let sellers view their Stripe dashboard
const loginLink = await stripe.accounts.createLoginLink(seller.stripeAccountId);
// Redirect to loginLink.url — expires in a few minutes
Building payment infrastructure? The AI SaaS Starter Kit includes full Stripe Connect integration with seller onboarding flow, split payment checkout, and payout tracking. $99 at whoffagents.com.
Top comments (0)