Replace Stripe payments and Stripe Connect payouts with Whop. Both providers run side-by-side in production — no rip-and-replace. Your Next.js app, Supabase database, and card marketplace stay exactly as they are.
This file gives Cursor and Claude Code full context about your Whop migration. Every file path, schema change, and TypeScript code example — ready to implement.
Save as CLAUDE.md in your project root. Open Cursor. Say “implement the Whop migration.”
Whop runs alongside Stripe in production. No staging environment needed, no new dependencies. Routing is controlled by a single Vercel env var.
PAYMENT_PROVIDER env var defaults to "stripe". Set to "whop" to activate. All routing lives in app/lib/payment-provider.ts — one check, not scattered across 28 files.Whop client (app/lib/whop.ts), webhook controller, DB migration, both flow paths. Stripe stays default. Deploy with zero behavior change.
Set PAYMENT_PROVIDER=whop on a Vercel preview deployment. Buy packs, purchase CatchCoins, test seller payouts with real money.
Flip to "whop" on production. Monitor PostHog events, Resend emails, and payout completion for 5–10 sellers.
Whop is default. Stripe code stays in repo as fallback. Remove Stripe code after 30 days of stable operation.
Three distinct payment flows, all routed through the same app/lib/payment-provider.ts check.
How your existing Supabase schemas and API routes map to Whop. New columns added alongside existing Stripe columns.
| Your Schema | Current Column | Whop Entity | New Column |
|---|---|---|---|
profiles |
stripe_connect_account_id |
Whop Company (child) | whop_company_id TEXT |
profiles |
stripe_connect_status |
Company verification | whop_payout_status VARCHAR(20) |
catchback_transactions |
stripe_transfer_id |
Whop Transfer | whop_transfer_id TEXT |
cashout_transactions |
stripe_transfer_id |
Whop Transfer | whop_transfer_id TEXT |
marketplace_listings |
— | No change | — unchanged |
| (new table) | — | Webhook dedup | webhook_events NEW |
Side-by-side: the Stripe calls you have today vs. the Whop equivalents.
stripe.checkout.sessions.create()stripe.accounts.create()stripe.accounts.retrieve()stripe.accountLinks.create()stripe.transfers.create()stripe.accounts.createLoginLink()whop.checkoutSessions.create()whop.companies.create()whop.companies.retrieve()whop.accountLinks.create()whop.transfers.create()STRIPE_SECRET_KEY_LIVESTRIPE_SECRET_KEY_TESTFORCE_TEST_MODE flagWHOP_API_KEYWHOP_COMPANY_IDWHOP_WEBHOOK_SECRETCatchBack currently has no Stripe webhooks (uses redirect-based confirmation). Whop adds reliable webhook handling as an upgrade.
| Current Handling | Whop Event | What Happens |
|---|---|---|
success_url redirect + sessions.retrieve() |
payment.succeeded |
Confirm pack purchase, credit CatchCoins, trigger card assignment |
| Manual admin check | transfer.completed |
Confirm seller payout settled, send Resend notification email |
| Coinbase webhook (stays) | — | Unchanged — /api/coinbase/webhook stays live |
| Coinflow webhook (stays) | — | Unchanged — /api/coinflow-webhook stays live |
/api/whop/webhook ensure every payment is recorded even if the redirect fails.Where Whop fits. Orange is new, green stays unchanged. Both providers coexist behind the routing check.
Buyer (Browser)
|
Next.js 15 (Vercel)
app/api/* routes
|
app/lib/payment-provider.ts
PAYMENT_PROVIDER = stripe | whop
/ \
/ \
STRIPE (fallback) WHOP (new path)
app/lib/stripe.ts app/lib/whop.ts
| |
Stripe Checkout Whop Checkout
Stripe Connect Whop Transfers
stripe.transfers Whop Companies
| |
\ | /
\ /api/whop/webhook /
\ | /
Supabase (PostgreSQL)
profiles | catchback_transactions
cashout_transactions | marketplace_listings
pokemon_cards | sports_cards | onepiece_cards
|
Supabase Auth (JWT)
Google OAuth + Email
Other integrations (all unchanged):
PayPal | Coinbase | Coinflow | PostHog | Resend | TikTok | Meta CAPI
Maps directly to your existing profiles.stripe_connect_status column. New whop_payout_status column follows the same pattern.
| State | Stripe Equivalent | Meaning | Can Receive Payouts? |
|---|---|---|---|
| not_started | No Connect account | Seller hasn't started Whop onboarding | No |
| pending | stripe_connect_status = "pending" |
Whop company created, onboarding link generated | No |
| in_progress | stripe_connect_status = "in_progress" |
Seller is completing verification | No |
| completed | charges_enabled + details_submitted |
Fully verified, payout methods set up | Yes |
| failed | stripe_connect_status = "failed" |
Verification failed or account restricted | No |
One week to first live dollar. Stripe stays live the entire time.
app/lib/whop.ts + SDK setupapp/lib/payment-provider.ts/api/whop-connect/* routes/api/whop/webhookPAYMENT_PROVIDER=whop"whop" on productionMost of your stack is unchanged. Whop replaces only the payment and payout provider layer.
@whop/sdk and @whop/checkout.