Billing and Stripe
Plan IDs
- coach_free
- coach_starter
- coach_pro
- coach_pro_plus
- club_starter
- club_pro
- club_enterprise
Environment Variables
Required:
- STRIPE_SECRET_KEY
- STRIPE_WEBHOOK_SECRET
Coach prices:
- STRIPE_PRICE_COACH_PRO_EARLY_ACCESS_MONTHLY
- STRIPE_PRICE_COACH_STARTER_MONTHLY
- STRIPE_PRICE_COACH_PRO_MONTHLY
- STRIPE_PRICE_COACH_PRO_PLUS_MONTHLY
Club prices:
- STRIPE_PRICE_CLUB_STARTER_MONTHLY
- STRIPE_PRICE_CLUB_PRO_MONTHLY
- STRIPE_PRICE_CLUB_ENTERPRISE_MONTHLY
Legacy club price names still supported as fallbacks:
- STRIPE_PRICE_BASIC_MONTHLY
- STRIPE_PRICE_PRO_MONTHLY
- STRIPE_PRICE_CLUB_MONTHLY
Stripe Setup
1. Create products and recurring monthly prices.
2. Copy `price_...` IDs into env vars.
3. Configure webhook endpoint:
- `https://protime.tennis/billing/webhook`
4. Subscribe to events:
- checkout.session.completed
- customer.subscription.created
- customer.subscription.updated
- customer.subscription.deleted
- invoice.paid
- invoice.payment_failed
Upgrade Flow
1. App calls `POST /billing/checkout-session` with `planId`.
2. Backend creates Stripe Checkout Session.
3. User completes payment.
4. Webhook updates tenant `plan_id`, billing status, subscription refs.
Common Errors
- `stripe is not configured`: missing `STRIPE_SECRET_KEY`
- `stripe price not configured for this plan`: missing matching env var
- `No such price`: wrong mode (test/live mismatch)
- `Your account cannot currently make live charges`: Stripe live account not fully activated
Launch Discounts
Recommended:
- Keep list price as recurring price
- Use promotion code/coupon for launch discount duration
- Keep plan IDs stable