Whop × CatchBack

Integration Guide

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.

Stripe Checkout → Whop Checkout Stripe Connect → Whop Payouts ✓ Next.js 15 + Supabase stays ✓ No new dependencies ✓ PayPal & crypto stay

Start Here — Drop This Into Your Repo

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.”

You are integrating Whop into CatchBack, a Next.js 15 / TypeScript / Supabase trading card marketplace on Vercel. Replace Stripe Checkout (4 routes in app/api/) with Whop Checkout and Stripe Connect Express (7 routes in app/api/stripe-connect/) with Whop Transfers. Add PAYMENT_PROVIDER env var routing in app/lib/payment-provider.ts. Keep Stripe as fallback. Add whop_company_id and whop_payout_status columns to profiles, whop_transfer_id to catchback_transactions and cashout_transactions. Create /api/whop-connect/* routes alongside existing Stripe routes. Add webhook handler at /api/whop/webhook for payment.succeeded and transfer.completed events. See CLAUDE.md for full implementation details with exact file paths and code.

⚙ Rollout Strategy

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.
1

Build

Whop client (app/lib/whop.ts), webhook controller, DB migration, both flow paths. Stripe stays default. Deploy with zero behavior change.

2

Internal Test

Set PAYMENT_PROVIDER=whop on a Vercel preview deployment. Buy packs, purchase CatchCoins, test seller payouts with real money.

3

Small Cohort

Flip to "whop" on production. Monitor PostHog events, Resend emails, and payout completion for 5–10 sellers.

4

Full Rollout

Whop is default. Stripe code stays in repo as fallback. Remove Stripe code after 30 days of stable operation.

⚡ Money Flows

Three distinct payment flows, all routed through the same app/lib/payment-provider.ts check.

Pack Purchase (4 Checkout Routes)

Buyer Selects pack
→
API Route /api/create-checkout-session
→
Payment Whop Checkout
→
Fulfillment /pack-success

Replaces stripe.checkout.sessions.create() in 4 routes: create-checkout-session, create-catchcoins-checkout, base-pack/create-checkout, create-exercise-checkout

Marketplace Seller Payout

Card sold $1 fee retained
→
Admin triggers /api/whop-connect/payout
→
Transfer Whop transfers.create
→
Seller Whop payout account

Replaces stripe.transfers.create() in app/api/stripe-connect/payout/route.ts. $1 platform fee deducted before transfer.

CatchCoins Cashout

User converts CatchCoins → USD
→
DB row cashout_transactions
→
Admin payout Whop transfers.create
→
Seller Bank account

Same transfer API as marketplace payouts. convert-catchcoins-to-cash route creates the DB row; admin triggers the Whop transfer.

□ Your Code → Whop

How your existing Supabase schemas and API routes map to Whop. New columns added alongside existing Stripe columns.

Your SchemaCurrent ColumnWhop EntityNew 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

▣ What Changes

Side-by-side: the Stripe calls you have today vs. the Whop equivalents.

Stripe (Today)

  • stripe.checkout.sessions.create()
  • stripe.accounts.create()
  • stripe.accounts.retrieve()
  • stripe.accountLinks.create()
  • stripe.transfers.create()
  • stripe.accounts.createLoginLink()
  • 28 files, 18 API call sites

Whop (After)

  • whop.checkoutSessions.create()
  • whop.companies.create()
  • whop.companies.retrieve()
  • whop.accountLinks.create()
  • whop.transfers.create()
  • Same auth pattern, same success URLs
  • New /api/whop-connect/* routes

Stripe Init (app/lib/stripe.ts)

  • STRIPE_SECRET_KEY_LIVE
  • STRIPE_SECRET_KEY_TEST
  • FORCE_TEST_MODE flag
  • 28 files import this

Whop Init (app/lib/whop.ts)

  • WHOP_API_KEY
  • WHOP_COMPANY_ID
  • WHOP_WEBHOOK_SECRET
  • New routes import this

⚡ Webhook Mapping

CatchBack currently has no Stripe webhooks (uses redirect-based confirmation). Whop adds reliable webhook handling as an upgrade.

Current HandlingWhop EventWhat 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
ℹ
Reliability upgrade. Stripe confirmation was redirect-based (fragile if user closes tab). Whop webhooks at /api/whop/webhook ensure every payment is recorded even if the redirect fails.

▣ Architecture

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

● Seller Payout States

Maps directly to your existing profiles.stripe_connect_status column. New whop_payout_status column follows the same pattern.

StateStripe EquivalentMeaningCan 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

⏰ Timeline

One week to first live dollar. Stripe stays live the entire time.

Day 1–2
Build
  • app/lib/whop.ts + SDK setup
  • app/lib/payment-provider.ts
  • Supabase migration (4 columns + 1 table)
  • Whop checkout in 4 routes
  • /api/whop-connect/* routes
  • /api/whop/webhook
  • Deploy — Stripe still default
Day 3–4
Internal Test
  • Preview deploy with PAYMENT_PROVIDER=whop
  • Buy all pack tiers ($1–$1000)
  • Purchase CatchCoins (dynamic amount)
  • Onboard test seller, trigger payout
  • Verify analytics events fire
Day 5–6
Small Cohort
  • Flip to "whop" on production
  • 5–10 real sellers onboard
  • Verify payout timing + amounts
  • Confirm $1 fee accounting
  • Monitor PostHog + Resend
Day 7
Full Rollout
  • Whop is default provider
  • Stripe stays as fallback code
  • First live dollar on Whop
  • Remove Stripe after 30 days

✓ What Stays the Same

Most of your stack is unchanged. Whop replaces only the payment and payout provider layer.

✓ Next.js 15.5.7
✓ Vercel hosting
✓ Supabase Auth
✓ Supabase PostgreSQL
✓ TanStack React Query
✓ Tailwind CSS
✓ PostHog analytics
✓ TikTok Pixel
✓ Meta CAPI
✓ Resend email
✓ PayPal routes
✓ Coinbase / Coinflow
✓ CatchCoins system
✓ Card catalog tables
✓ Marketplace listings
✓ No new dependencies
~ profiles table (new cols)
~ transaction tables (new cols)
✓
Bottom line: Your entire card marketplace, CatchCoins economy, Supabase database, and frontend components stay untouched. Stripe stays in the codebase as a working fallback. The only new packages are @whop/sdk and @whop/checkout.