A production-ready boilerplate for building subscription-based web applications using FastAPI, with Stripe for payments, Supabase for database, and Clerk for authentication.
-
🔐 User Management with Clerk
- OAuth (Google, etc.)
- Email/Password
- User Profile Management
- Webhook Integration
-
💳 Stripe Integration
- Subscription Management
- Customer Management
- Webhook Integration
- Payment Link Support
-
🗄️ Database Integration with Supabase
- User Data Storage
- Subscription Tracking
- Automated Timestamps
- Efficient Indexing
-
🚀 Modern Stack
- FastAPI for high performance
- Async/await support
- Type hints throughout
- Structured logging
- Python 3.8+
- ngrok for webhook testing
- Accounts on:
git clone <repository-url>
cd <repository-name># Create a virtual environment
python -m venv venv
# Activate it
# On Windows:
venv\Scripts\activate
# On macOS/Linux:
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt- Create a new project on Supabase
- Go to Project Settings > Database to find your connection details
- In the SQL Editor, run the following schema:
-- Create users table
CREATE TABLE users (
id TEXT PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
phone TEXT,
username TEXT UNIQUE,
full_name TEXT,
first_name TEXT,
last_name TEXT,
is_subscribed BOOL NOT NULL DEFAULT FALSE,
stripe_customer_id TEXT UNIQUE,
stripe_plan_id TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc', NOW()),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc', NOW())
);
-- Create indexes for frequent queries
CREATE INDEX users_email_idx ON users(email);
CREATE INDEX users_username_idx ON users(username);
-- Add a trigger to automatically update the updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = TIMEZONE('utc', NOW());
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_users_updated_at
BEFORE UPDATE
ON users
FOR EACH ROW
EXECUTE PROCEDURE update_updated_at_column();- Get your Supabase URL and anon key from Project Settings > API
- Create an account on Stripe
- Go to Developers > API keys
- Get your test Secret key
- Create a payment link:
- Go to Payment Links in Stripe Dashboard
- Create a new payment link
- Configure your product/price
- Example: https://buy.stripe.com/test_00gbMje8a9VW6FqbII?prefilled_email=test@test.com
- Save your payment link URL
- Create a new application on Clerk
- Configure your OAuth providers (Google, etc.)
- Get your API keys from the dashboard
- Configure your webhook endpoints (we'll add the URL later)
Create a .env file in your project root:
# Stripe Configuration
STRIPE_SECRET_KEY=sk_test_your_key_here
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret_here
# Supabase Configuration
SUPABASE_URL=your_supabase_url_here
SUPABASE_KEY=your_supabase_anon_key_here# Start the FastAPI server
uvicorn main:app --reload --port 8000- Install ngrok if you haven't already:
# Using Homebrew on macOS
brew install ngrok
# Or download from ngrok.com- Start ngrok tunnel:
ngrok http 8000- Copy your ngrok URL (e.g., https://your-tunnel.ngrok.io)
- Go to Stripe Dashboard > Developers > Webhooks
- Add endpoint:
https://your-tunnel.ngrok.io/webhook/stripe - Select events to listen for:
- customer.created
- customer.updated
- customer.subscription.created
- customer.subscription.updated
- customer.subscription.deleted
- checkout.session.completed
- Save and get your webhook signing secret
- Update your
.envfile with the webhook secret
- Go to Clerk Dashboard > Webhooks
- Add endpoint:
https://your-tunnel.ngrok.io/webhook/user-profile - Select events:
- user.created
- user.updated
- user.deleted
- Save the configuration
- Start your FastAPI server:
uvicorn main:app --reload --port 8000- Start ngrok:
ngrok http 8000-
Test user creation:
- Sign up a new user through your Clerk integration
- Check the logs for webhook reception
- Verify user creation in Supabase
-
Test subscription:
- Use your Stripe payment link
- Complete a test purchase
- Verify the subscription status update in your database
app/
├── services/
│ ├── stripe_subscription_service.py
│ └── user_service.py
├── database/
│ └── base_repository.py
└── utils/
└── logger.py
main.py
.env
requirements.txt
- Automatic user creation when users sign up through Clerk
- Profile updates sync to database
- Email change handling
- Phone number management
- Customer creation in Stripe
- Subscription status tracking
- Plan changes
- Subscription cancellation
- Automatic timestamp management
- Efficient indexing
- Unique constraint enforcement
- Relationship management
Contributions are welcome! Please open an issue or submit a pull request.
MIT License