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.