Billing & Stripe Setup
Configure Stripe for subscription billing, storage plans, and payment processing.
Overview
BooksOnAutopilot.com uses Stripe for subscription billing. There are two independent subscription types per organization:
- Seat plan - Pro ($12/seat/mo or $10/seat/mo annual) for team access, reports, API, and multi-currency
- Storage add-on - Starter, Growth, or Scale tiers for file storage and email sending limits
Both subscriptions are managed separately in Stripe and can be upgraded or downgraded independently.
Stripe Setup
Create a Stripe account
Sign up at stripe.com and complete onboarding. For testing, use Stripe's test mode.
Create products and prices
In the Stripe Dashboard, create the following products with recurring prices:
Seat Plans:
| Product | Price (monthly) | Price (annual) |
|---|---|---|
| Pro | $12/seat/month | $120/seat/year ($10/mo effective) |
Storage Add-ons:
| Product | Price (monthly) | Price (annual) |
|---|---|---|
| Starter (25 GB) | $15/month | $156/year ($13/mo effective) |
| Growth (75 GB) | $45/month | $456/year ($38/mo effective) |
| Scale (300 GB) | $120/month | $1,200/year ($100/mo effective) |
Configure environment variables
Copy each price ID from the Stripe Dashboard and add them to your .env.local:
# Stripe API keys
STRIPE_SECRET_KEY="sk_test_..."
STRIPE_WEBHOOK_SECRET="whsec_..."
# Seat plan price IDs
STRIPE_PRO_PRICE_ID="price_..."
STRIPE_PRO_ANNUAL_PRICE_ID="price_..."
# Storage add-on price IDs (monthly)
STRIPE_STORAGE_STARTER_PRICE_ID="price_..."
STRIPE_STORAGE_GROWTH_PRICE_ID="price_..."
STRIPE_STORAGE_SCALE_PRICE_ID="price_..."
# Storage add-on price IDs (annual)
STRIPE_STORAGE_STARTER_ANNUAL_PRICE_ID="price_..."
STRIPE_STORAGE_GROWTH_ANNUAL_PRICE_ID="price_..."
STRIPE_STORAGE_SCALE_ANNUAL_PRICE_ID="price_..."Set up the webhook
Create a webhook endpoint in Stripe pointing to:
https://your-domain.com/api/stripe/webhookSubscribe to these events:
checkout.session.completedcustomer.subscription.updatedcustomer.subscription.deleted
Copy the webhook signing secret to STRIPE_WEBHOOK_SECRET.
How Upgrades Work
When a user upgrades or changes their plan:
- If they already have an active subscription, BooksOnAutopilot.com calls
stripe.subscriptions.update()with the new price ID - Stripe automatically prorates the charge for the remaining billing period
- The local database is updated immediately
- No duplicate subscriptions are created
For new subscriptions, a Stripe Checkout session is created and the user is redirected to complete payment.
Testing with Stripe CLI
For local development, use the Stripe CLI to forward webhook events:
# Install Stripe CLI
brew install stripe/stripe-cli/stripe
# Login to your Stripe account
stripe login
# Forward events to your local server
stripe listen --forward-to localhost:3000/api/stripe/webhookThe CLI will output a webhook signing secret starting with whsec_. Use this as your STRIPE_WEBHOOK_SECRET for local testing.
Test Card Numbers
| Card Number | Result |
|---|---|
4242 4242 4242 4242 | Successful payment |
4000 0000 0000 3220 | 3D Secure authentication required |
4000 0000 0000 9995 | Declined (insufficient funds) |
Use any future expiration date and any 3-digit CVC.
Customer Portal
Users can manage their billing (update payment method, cancel, view invoices) via the Stripe Customer Portal. To enable it:
- Go to Stripe Dashboard > Settings > Customer Portal
- Enable the features you want (invoice history, cancel subscription, etc.)
- The portal is accessed from Settings > Billing > "Manage Billing" button
Private Preview Without Stripe
Without Stripe configured, production organizations remain on the free plan. Paid subscriptions require the platform Stripe account.
Local development can explicitly enable preview access with PRIVATE_PREVIEW_UNLIMITED=true. Never enable this setting in the public production environment.