Spaces:
Paused
Paused
| # Monthly Subscriptions Setup Guide | |
| This guide will help you set up monthly subscriptions for your 3DAI API backend. | |
| ## 1. Database Schema Updates | |
| You'll need to create the following tables in your Supabase database: | |
| ### User_Subscriptions Table | |
| ```sql | |
| CREATE TABLE "User_Subscriptions" ( | |
| id SERIAL PRIMARY KEY, | |
| user_id UUID NOT NULL REFERENCES auth.users(id), | |
| stripe_subscription_id VARCHAR(255) UNIQUE NOT NULL, | |
| plan VARCHAR(50) NOT NULL, | |
| status VARCHAR(50) NOT NULL, | |
| current_period_start TIMESTAMP WITH TIME ZONE, | |
| current_period_end TIMESTAMP WITH TIME ZONE, | |
| created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), | |
| canceled_at TIMESTAMP WITH TIME ZONE | |
| ); | |
| -- Add indexes for better performance | |
| CREATE INDEX idx_user_subscriptions_user_id ON "User_Subscriptions"(user_id); | |
| CREATE INDEX idx_user_subscriptions_status ON "User_Subscriptions"(status); | |
| CREATE INDEX idx_user_subscriptions_stripe_id ON "User_Subscriptions"(stripe_subscription_id); | |
| ``` | |
| ### Stripe_Customers Table | |
| ```sql | |
| CREATE TABLE "Stripe_Customers" ( | |
| id SERIAL PRIMARY KEY, | |
| user_id UUID NOT NULL REFERENCES auth.users(id), | |
| stripe_customer_id VARCHAR(255) UNIQUE NOT NULL, | |
| created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() | |
| ); | |
| -- Add index | |
| CREATE INDEX idx_stripe_customers_user_id ON "Stripe_Customers"(user_id); | |
| ``` | |
| ### Subscription_Payment_History Table | |
| ```sql | |
| CREATE TABLE "Subscription_Payment_History" ( | |
| id SERIAL PRIMARY KEY, | |
| user_id UUID NOT NULL REFERENCES auth.users(id), | |
| subscription_id VARCHAR(255) NOT NULL, | |
| invoice_id VARCHAR(255) UNIQUE NOT NULL, | |
| amount DECIMAL(10,2) NOT NULL, | |
| credits_added INTEGER NOT NULL, | |
| payment_date TIMESTAMP WITH TIME ZONE NOT NULL, | |
| status VARCHAR(50) NOT NULL, | |
| created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() | |
| ); | |
| -- Add indexes | |
| CREATE INDEX idx_subscription_payment_history_user_id ON "Subscription_Payment_History"(user_id); | |
| CREATE INDEX idx_subscription_payment_history_subscription_id ON "Subscription_Payment_History"(subscription_id); | |
| ``` | |
| ## 2. Stripe Configuration | |
| ### Create Products and Prices in Stripe | |
| You'll need to create products and prices in your Stripe dashboard or via API: | |
| ```bash | |
| # Using Stripe CLI (install from https://stripe.com/docs/stripe-cli) | |
| # Create Basic Plan Product | |
| stripe products create \ | |
| --name="Basic Plan" \ | |
| --description="50 credits per month" | |
| # Create Basic Plan Price (replace prod_xxx with your product ID) | |
| stripe prices create \ | |
| --unit-amount=999 \ | |
| --currency=gbp \ | |
| --recurring-interval=month \ | |
| --product=prod_xxx | |
| # Create Pro Plan Product | |
| stripe products create \ | |
| --name="Pro Plan" \ | |
| --description="150 credits per month" | |
| # Create Pro Plan Price | |
| stripe prices create \ | |
| --unit-amount=2499 \ | |
| --currency=gbp \ | |
| --recurring-interval=month \ | |
| --product=prod_xxx | |
| # Create Premium Plan Product | |
| stripe products create \ | |
| --name="Premium Plan" \ | |
| --description="300 credits per month" | |
| # Create Premium Plan Price | |
| stripe prices create \ | |
| --unit-amount=3999 \ | |
| --currency=gbp \ | |
| --recurring-interval=month \ | |
| --product=prod_xxx | |
| ``` | |
| ### Update Price IDs | |
| After creating the prices, update the `SUBSCRIPTION_PLANS` in `routers/payments.py` with your actual Stripe price IDs: | |
| ```python | |
| SUBSCRIPTION_PLANS = { | |
| "basic": { | |
| "credits_per_month": 50, | |
| "price_gbp": 9.99, | |
| "stripe_price_id": "price_1234567890", # Replace with actual price ID | |
| "name": "Basic Plan", | |
| "description": "50 credits per month" | |
| }, | |
| # ... update other plans | |
| } | |
| ``` | |
| ## 3. Environment Variables | |
| Add these new environment variables to your `.env` file: | |
| ```env | |
| # Existing variables... | |
| STRIPE_SECRET_KEY=sk_test_your_stripe_secret_key | |
| STRIPE_PUBLISHABLE_KEY=pk_test_your_stripe_publishable_key | |
| # New webhook secret (you'll get this when setting up the webhook) | |
| STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret | |
| ``` | |
| ## 4. Webhook Configuration | |
| ### Set up Stripe Webhook | |
| 1. Go to your Stripe Dashboard → Developers → Webhooks | |
| 2. Click "Add endpoint" | |
| 3. Set the endpoint URL to: `https://your-domain.com/payment/webhook` | |
| 4. Select these events: | |
| - `invoice.payment_succeeded` | |
| - `invoice.payment_failed` | |
| - `customer.subscription.deleted` | |
| - `customer.subscription.updated` | |
| 5. Copy the webhook secret and add it to your environment variables | |
| ## 5. API Endpoints | |
| Your subscription system now includes these new endpoints: | |
| ### Get Available Plans | |
| ``` | |
| GET /payment/subscription-plans | |
| ``` | |
| ### Create Subscription | |
| ``` | |
| POST /payment/create-subscription | |
| Content-Type: application/json | |
| Authorization: Bearer <token> | |
| { | |
| "plan": "basic" | |
| } | |
| ``` | |
| ### Get User's Subscription | |
| ``` | |
| GET /payment/subscription | |
| Authorization: Bearer <token> | |
| ``` | |
| ### Cancel Subscription | |
| ``` | |
| POST /payment/cancel-subscription | |
| Content-Type: application/json | |
| Authorization: Bearer <token> | |
| { | |
| "subscription_id": "sub_1234567890" | |
| } | |
| ``` | |
| ### Webhook Endpoint | |
| ``` | |
| POST /payment/webhook | |
| ``` | |
| ## 6. Frontend Integration Example | |
| Here's a basic example of how to integrate subscriptions in your frontend: | |
| ```javascript | |
| // Create subscription | |
| const createSubscription = async (plan) => { | |
| const response = await fetch('/payment/create-subscription', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${userToken}` | |
| }, | |
| body: JSON.stringify({ plan }) | |
| }); | |
| const { client_secret } = await response.json(); | |
| // Use Stripe.js to confirm payment | |
| const { error } = await stripe.confirmPayment({ | |
| elements, | |
| clientSecret: client_secret, | |
| confirmParams: { | |
| return_url: 'https://your-domain.com/subscription-success' | |
| } | |
| }); | |
| }; | |
| // Get user's subscription status | |
| const getSubscription = async () => { | |
| const response = await fetch('/payment/subscription', { | |
| headers: { | |
| 'Authorization': `Bearer ${userToken}` | |
| } | |
| }); | |
| const { subscription } = await response.json(); | |
| return subscription; | |
| }; | |
| ``` | |
| ## 7. Testing | |
| 1. Use Stripe test mode for development | |
| 2. Use test card numbers from Stripe documentation | |
| 3. Test webhook events using Stripe CLI: | |
| ```bash | |
| stripe listen --forward-to localhost:8000/payment/webhook | |
| ``` | |
| ## 8. Production Considerations | |
| 1. **Security**: Ensure webhook signature verification is enabled | |
| 2. **Monitoring**: Set up logging for subscription events | |
| 3. **Error Handling**: Implement retry logic for failed webhook processing | |
| 4. **Credits Management**: Consider implementing credit rollover policies | |
| 5. **Prorations**: Handle plan changes with appropriate prorations | |
| 6. **Tax Handling**: Implement tax calculation if required for your jurisdiction | |
| ## 9. Additional Features to Consider | |
| - **Plan Upgrades/Downgrades**: Allow users to change subscription plans | |
| - **Pause/Resume**: Allow temporary subscription pauses | |
| - **Annual Plans**: Add yearly subscription options with discounts | |
| - **Usage Limits**: Implement soft/hard limits based on subscription tier | |
| - **Email Notifications**: Send emails for subscription events | |
| - **Admin Dashboard**: Create admin interface for subscription management |