Stripe Connect starter for Next.js

Skip 3 weekends of
Stripe Connect rediscovery.

We were building a marketplace and hit the Stripe Connect wall. Multi-vendor patterns undocumented. Edge cases everywhere — status sync races, double-charge bugs, cross-customer attach attacks. Stripe's docs cover none of it.

Spent 3 weekends rediscovering patterns nobody publishes. Then extracted everything into a Next.js 16 starter so you don't have to.

30-day money-back guarantee · Source via private GitHub repo · Auto-granted on purchase

What this skips

If any of these sound familiar, you've been here.

The 2-day rabbit hole figuring out idempotent Express account creation, only to realise Stripe's API doesn't dedupe — your code has to.

The Friday-evening incident when a buyer reopened the pay modal and got charged twice for the same order.

The Stripe Dashboard double-take when Connect status didn't sync after the seller returned from onboarding — webhook hadn't landed yet, and you didn't know to poll as a fallback.

The hour spent realising your setDefaultPaymentMethod didn't verify ownership — any authenticated user could attach any card to themselves.

The 200-line branching mess for Stripe's three "no-account" error variants — resource_missing, No such account, "not signed up for Connect."

The on-top fee math nobody walks through: customer pays subtotal + commission, vendor receives bare subtotal, Stripe processing fees come from where? (Platform balance by default — but the docs make you guess.)

See the destination-charge flow

What your buyers see at checkout. The breakdown is the proof — vendor receives the full listed price, platform earns its on-top fee, Stripe processing fees come from the platform balance.

Preview · what your buyers see

Buyer checkout

Demo product purchase

Order 9068df6e-0571-4234-be96-…

Subtotal $50.00
Platform fee (10.0%) $5.00
Total $55.00

Vendor receives $50.00 via destination charge. $5.00 lands in platform balance.

VISA •••• 4242 Default
Pay $55.00

↑ this is the demo running in the starter — not a live checkout

The breakdown is computed server-side from computeOnTopServiceFee in src/lib/stripe/connect.ts, then passed to Stripe as application_fee_amount + transfer_data.destination. Test card 4242 · webhook signature verified · order auto-flips to paid on payment_intent.succeeded.

Get the code → from €149

What you get

Every piece is extracted from a production marketplace shipping today.

Stripe Connect Express

Idempotent account creation, hosted onboarding link generation with proper return/refresh URLs, status sync from BOTH polling AND account.updated webhook. Stripe-hosted KYC flow, no fields to wire up.

Destination charges + on-top fee

Customer pays subtotal + commission. Vendor receives the full listed price via destination charge. Platform earns application_fee_amount. Stripe processing fees come out of platform balance — vendor never sees a deduction.

PaymentIntent reuse + double-charge defense

Handles the "user opens pay modal, navigates away, comes back" race condition that quietly creates duplicate charges in most boilerplates. Detects already-succeeded PIs that haven't synced to your DB yet. Cancels stale PIs when the buyer switches saved cards.

Saved payment methods CRUD

List / set default / detach, all guarded against the cross-customer attach attack (where an authenticated buyer tries to bind another customer's payment method as their default). SetupIntent for off-session card collection included.

Webhook signature verification

Raw-body signature check, typed event router for account.updated, payment_intent.succeeded, payment_intent.payment_failed. Returns 5xx on handler error so Stripe retries with backoff.

Typed Stripe error mapping

StripeAppError with stable codes — connect_platform_not_activated, connect_permission, connect_account_missing. Frontend switches on stable codes, never error-message strings.

Auth-adapter pattern

Drop-in interface that works with NextAuth, Clerk, Supabase Auth, or your own. Ships with a cookie-based demo so you can run the full flow before wiring real auth. Every Stripe path is auth-agnostic.

Drizzle schema, ready to migrate

Three tables — vendors, customers, orders — with all Stripe linkage fields, snapshotted pricing, and FK constraints. Works with Supabase, Neon, Railway, Vercel Postgres, or self-hosted.

Built on

Next.js 16 (App Router · Turbopack) · tRPC v11 · Drizzle ORM · Stripe Node SDK 17 · TypeScript strict · Tailwind v4

Pricing

One-time purchase. 30-day money-back guarantee. 12 months of patch updates included.

Single-App

For one production app.

€149

one-time, perpetual license

  • ✓ Full source code access (private GitHub repo, granted automatically)
  • ✓ All features above, including PaymentIntent reuse defense
  • ✓ Use in ONE production application
  • ✓ Modify freely, deploy to any environments
  • ✓ 12 months of patch updates
  • ✓ 48-hour email support SLA
  • ✓ 30-day money-back guarantee
Buy €149
BEST VALUE

Multi-App

For agencies + multi-product founders.

€349

one-time, perpetual license

  • ✓ Everything in Single-App
  • ✓ Use in unlimited production applications
  • ✓ Same legal entity covers all apps
  • ✓ 12 months of patch updates
  • ✓ 48-hour email support SLA
  • ✓ 30-day money-back guarantee
  • ✓ Save €447+ vs buying 4× Single-App
Buy €349

Prices are in EUR. VAT may apply for EU buyers (handled by Polar at checkout).
Not sure which tier? Email us.

FAQ

How is this different from ShipFast or other Stripe boilerplates?

Most boilerplates handle Stripe Standard (single-merchant payments). PayoutKit ships Stripe Connect — the multi-vendor marketplace pattern with destination charges, on-top platform fees, and KYC onboarding. If you're building a marketplace, this is the part the other boilerplates leave you to figure out.

What happens after I buy?

You get an email from Polar with a link to the GitHub repo. Add your GitHub username to the email so we can grant access within minutes. Clone, run pnpm install, set 4 env vars, run pnpm dev. The full demo runs locally in under 10 minutes.

Does it work with my auth provider?

Yes. The starter ships an AuthAdapter interface with a cookie-based demo implementation. Swap it for NextAuth, Clerk, Supabase Auth, or your own — the Stripe code paths are auth-agnostic. Most integrations take 30 minutes.

What about my database?

Drizzle ORM + node-postgres. Works with any standard Postgres: Supabase, Neon, Railway, Vercel Postgres, or self-hosted. Schema includes 3 tables (vendors, customers, orders) with snapshotted pricing and Stripe linkage fields.

What countries does Stripe Connect support?

Stripe Connect is available in 40+ countries. The starter has a STRIPE_CONNECT_COUNTRY env var (default US) — change it to your platform's country. See the Stripe Connect global availability page.

Do I need to know Stripe deeply to use this?

No. The code has heavy inline documentation explaining the WHY of every Stripe decision (destination charges vs direct charges, on-top fees vs deducted fees, polling vs webhook status sync). You'll learn Stripe Connect by reading the source. The Setup Pack add-on covers your specific implementation questions.

Can I get a refund?

Yes — 30-day money-back guarantee, no questions asked. Email support@payoutkit.dev within 30 days of purchase.

Will I get updates?

12 months of patch and minor-version updates included with every license. After 12 months, you keep using your version forever; renewal is optional.

Can I resell this or use it in client projects?

Use in client projects: yes, if it's the client's licensed application (one client = one Single-App license, OR one Multi-App license covers your agency's clients). Resell or republish the source code: no — see the commercial license.

Ready to skip the Stripe Connect learning curve?

Buy once. Ship a marketplace this weekend.

Buy from €149 →