Whop × FoodFluence

Payment Integration Guide

Migrate collab payments from Stripe to Whop. Both providers run side-by-side in production — no rip-and-replace, no new infrastructure. Payouts via Dots stay untouched.

Stripe pay-ins → Whop Dots payouts stay Flask + App Engine stays Firebase / Firestore stays No new dependencies

Start Here — Drop This Into Your Repo

This file gives Cursor and Claude full context about your Whop migration. Every file path, schema change, and code example — ready to implement.

Save as CLAUDE.md in your project root. Open Cursor. Say “implement the Whop migration.”

Integrate Whop payments into the FoodFluence Flask backend, replacing Stripe for one-time collab charges. Key files: services/payments/stripe_payments.py (add Whop equivalent), services/payments/stripe_webhook_handler.py (add Whop equivalent), app.py (add /whop-webhook route), environment.py (add WHOP_API_KEY, WHOP_COMPANY_ID, WHOP_WEBHOOK_SECRET). Run Whop side-by-side with Stripe using PAYMENT_PROVIDER env var + per-client paymentProvider field in Firestore. Payouts (Dots) stay unchanged. Subscriptions are out of scope. See CLAUDE.md for full implementation details.

⚙ Rollout Strategy

Whop runs alongside Stripe in production. No staging environment needed, no new dependencies. Routing is controlled by an env var with per-client override using your existing Firestore documents.

ℹ
PAYMENT_PROVIDER env var defaults to "stripe". Per-client override: set paymentProvider: "whop" on the client’s Firestore document. All routing lives in services/payments/payment_router.py — one check, not scattered across files.
1

Build

Whop payment service, webhook controller, Firestore field additions. Stripe stays default. Deploy with zero behavior change.

2

Internal Test

Set paymentProvider: "whop" on FoodFluence’s own client document. Test with real money internally.

3

Small Cohort

Enable Whop for 5–10 trusted clients. Verify webhook parity, payment confirmation timing, and Firestore consistency.

4

Full Rollout

Flip PAYMENT_PROVIDER=whop in App Engine config. Stripe path stays in code as fallback until you’re confident.

⚡ Payment Flows

Two core flows being migrated: saving a payment method (card) and charging for collaborations.

Save Payment Method

Brand Client
→
Backend Flask API
→
Checkout Whop Setup
→
Webhook setup_intent.succeeded
→
Store Firestore

Replaces stripe.SetupIntent.create in services/payments/stripe_payments.py with Whop checkout configuration in setup mode

Charge for Collab

Trigger Collab Approved
→
Backend whop_payments.py
→
API POST /payments
→
Webhook payment.succeeded
→
Update Collab Record

Replaces stripe.PaymentIntent.create(off_session=True) in services/payments/stripe_payments.py. Key change: Whop charges are async — confirmation comes via webhook, not in the API response.

□ Your Code → Whop

How your Firestore collections and payment modules map to Whop. New fields are added alongside existing Stripe fields.

Your CollectionFileWhop EntityNew Fields
clients services/firebase/firestore_service.py Member whopMemberId, whopPaymentMethodId, paymentProvider
clientDashboardAdmin services/firebase/firestore_service.py Member whopMemberId
collabs services/payments/stripe_payments.py Payment whopPaymentId, paymentProvider
influencerCampaigns services/firebase/firestore_service.py Payment Method whopPaymentMethodId

▣ What Changes

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

Stripe (Today)

  • stripe.SetupIntent.create()
  • stripe.PaymentMethod.list()
  • stripe.PaymentMethod.attach()
  • stripe.Customer.create()
  • stripe.Customer.modify()
  • stripe.PaymentIntent.create(off_session=True)
  • stripe.Webhook.construct_event()

Whop (After)

  • checkout_configurations.create(mode="setup")
  • payment_methods.list(member_id=...)
  • Automatic on checkout completion
  • Implicit on first checkout
  • N/A (member managed by Whop)
  • payments.create(payment_method_id=...)
  • standardwebhooks.Webhook.verify()

Stripe Routes (Today)

  • POST /create-setup-intent
  • POST /save-payment-method
  • POST /get-payment-methods
  • POST /charge-for-collab
  • POST /bill-for-additional-collab
  • POST /stripe-webhook

Updated Routes

  • Same routes — branching via is_whop()
  • Same routes — branching via is_whop()
  • Same routes — branching via is_whop()
  • Same routes — branching via is_whop()
  • Same routes — branching via is_whop()
  • POST /whop-webhook (NEW, alongside Stripe)

⚡ Webhook Mapping

Your existing Stripe event handlers map to these Whop events. Both webhook endpoints run simultaneously.

Stripe EventWhop EventWhat Happens
payment_intent.succeeded payment.succeeded Update collab with whopPaymentId and chargedAt
payment_intent.payment_failed payment.failed Log failure, alert ops team
setup_intent.succeeded setup_intent.succeeded Store whopMemberId + whopPaymentMethodId on client
customer.subscription.created — Not migrated (subscriptions out of scope)
invoice.payment_succeeded — Not migrated (subscriptions out of scope)
ℹ
Both endpoints live simultaneously. /stripe-webhook continues handling subscription events. /whop-webhook handles Whop payment and setup events. Never remove the Stripe route.

▣ Architecture

Where Whop fits in the FoodFluence stack. Orange is new, green stays unchanged. Both providers coexist.

  Brand (Frontend)
       |
       v
  Flask API  (app.py)
       |
       v
  payment_router.py  ─── is_whop(client_doc)?
       |                        |
       |                        |
    no (default)              yes
       |                        |
       v                        v
  stripe_payments.py     whop_payments.py
       |                        |
       v                        v
  Stripe API              Whop API
       |                        |
       v                        v
  /stripe-webhook        /whop-webhook
       |                        |
       v                        v
  stripe_webhook_         whop_webhook_
  handler.py              handler.py
       |                        |
       +────────┬───────────────+
                v
         Firestore  (clients, collabs, campaigns)
                |
         Dots Payouts  (unchanged)

⏰ Timeline

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

Day 1–2
Build
  • Whop payment service + webhook handler
  • Provider router + env var config
  • Firestore field additions
  • Deploy — Stripe still default
Day 3–4
Internal Test
  • Enable Whop on your own client
  • Real money, real webhooks
  • Verify Firestore field consistency
Day 5–6
Small Cohort
  • 5–10 trusted clients
  • Webhook parity confirmed
  • Payment timing validated
Day 7
Full Rollout
  • Flip env var to “whop”
  • Stripe path stays as fallback
  • First live dollar

✓ What Stays the Same

Most of your stack is unchanged. Whop replaces only the Stripe pay-in layer for collab charges.

✓ Flask + Gunicorn
✓ Google App Engine
✓ Firebase Auth
✓ Cloud Firestore
✓ Dots Payouts
✓ Twilio SMS
✓ Mailersend Email
✓ Shopify Integration
✓ Instagram Services
✓ Rewardful Affiliates
✓ OpenAI / Pinecone
✓ GCP Secret Manager
✓ No new dependencies
~ Stripe (stays for subscriptions)
✓
Bottom line: Your entire stack stays intact. Stripe stays as the default provider and handles subscriptions. Dots continues handling payouts. Whop is added as a parallel payment path for collab charges only. No new databases, no new queues, no new infrastructure.