Phase 1 Step 2: Stripe Subscription Integration Design
Overview
Implement Stripe subscription management for CODITECT Cloud Platform with three pricing tiers.
Subscription Plans
Free Tier
- Price: $0/month
- Features:
- 1 user seat
- 5 projects
- Community support
- Basic license management
- Stripe Product ID:
prod_free(created manually in Stripe Dashboard) - No payment required - Auto-assigned on registration
Pro Tier
- Price: $29/month per seat
- Features:
- Up to 10 user seats
- Unlimited projects
- Priority email support
- Advanced license analytics
- API access
- Stripe Product ID:
prod_pro - Stripe Price ID:
price_pro_monthly
Enterprise Tier
- Price: $99/month per seat
- Features:
- Unlimited user seats
- Unlimited projects
- Dedicated account manager
- SLA guarantees
- Custom integrations
- Phone support
- Stripe Product ID:
prod_enterprise - Stripe Price ID:
price_enterprise_monthly
Database Schema Updates
Organization Model Updates
# tenants/models.py
class Organization(models.Model):
# ... existing fields ...
# Subscription fields
stripe_customer_id = models.CharField(max_length=255, null=True, blank=True, unique=True)
stripe_subscription_id = models.CharField(max_length=255, null=True, blank=True)
stripe_price_id = models.CharField(max_length=255, null=True, blank=True)
# Billing status
subscription_status = models.CharField(
max_length=50,
choices=[
('FREE', 'Free'),
('ACTIVE', 'Active'),
('PAST_DUE', 'Past Due'),
('CANCELED', 'Canceled'),
('TRIALING', 'Trialing'),
],
default='FREE'
)
# Billing period
current_period_start = models.DateTimeField(null=True, blank=True)
current_period_end = models.DateTimeField(null=True, blank=True)
trial_end = models.DateTimeField(null=True, blank=True)
# Usage limits
seats_purchased = models.IntegerField(default=1)
seats_used = models.IntegerField(default=0)
API Endpoints
1. Get Available Plans
GET /api/v1/subscriptions/plans/
Response 200:
{
"plans": [
{
"id": "free",
"name": "Free",
"price": 0,
"interval": "month",
"features": ["1 seat", "5 projects", "Community support"],
"stripe_price_id": null
},
{
"id": "pro",
"name": "Pro",
"price": 29,
"interval": "month",
"currency": "usd",
"features": ["10 seats", "Unlimited projects", "Priority support", "API access"],
"stripe_price_id": "price_pro_monthly"
},
{
"id": "enterprise",
"name": "Enterprise",
"price": 99,
"interval": "month",
"currency": "usd",
"features": ["Unlimited seats", "Dedicated support", "SLA", "Custom integrations"],
"stripe_price_id": "price_enterprise_monthly"
}
]
}
2. Create Checkout Session
POST /api/v1/subscriptions/checkout/
Request:
{
"price_id": "price_pro_monthly",
"seats": 5,
"success_url": "https://app.coditect.ai/success",
"cancel_url": "https://app.coditect.ai/pricing"
}
Response 200:
{
"checkout_url": "https://checkout.stripe.com/c/pay/cs_test_...",
"session_id": "cs_test_..."
}
3. Webhook Handler
POST /api/v1/subscriptions/webhook/
Stripe webhook events:
- checkout.session.completed
- customer.subscription.created
- customer.subscription.updated
- customer.subscription.deleted
- invoice.payment_succeeded
- invoice.payment_failed
4. Get Current Subscription
GET /api/v1/subscriptions/current/
Response 200:
{
"plan": "pro",
"status": "active",
"seats_purchased": 5,
"seats_used": 3,
"current_period_end": "2025-01-01T00:00:00Z",
"cancel_at_period_end": false
}
5. Update Subscription
POST /api/v1/subscriptions/update/
Request:
{
"seats": 10
}
Response 200:
{
"message": "Subscription updated",
"new_seats": 10,
"prorated_amount": 150.00
}
6. Cancel Subscription
POST /api/v1/subscriptions/cancel/
Request:
{
"immediately": false # false = cancel at period end, true = cancel now
}
Response 200:
{
"message": "Subscription will be canceled at period end",
"canceled_at": "2025-01-01T00:00:00Z"
}
Implementation Steps
Step 2.1: Database Migration
- Add stripe_customer_id, stripe_subscription_id to Organization
- Add subscription_status, billing period fields
- Create migration file
Step 2.2: Stripe Client Setup
- Configure Stripe SDK with API keys
- Create StripeService helper class
- Implement error handling
Step 2.3: Subscription Models & Serializers
- Create SubscriptionPlanSerializer
- Create CheckoutSessionSerializer
- Create SubscriptionStatusSerializer
Step 2.4: API Views
- SubscriptionPlansView (list available plans)
- CheckoutSessionCreateView (create Stripe checkout)
- SubscriptionWebhookView (handle Stripe events)
- CurrentSubscriptionView (get org subscription)
- UpdateSubscriptionView (change seats)
- CancelSubscriptionView (cancel subscription)
Step 2.5: Webhook Integration
- Set up Stripe webhook endpoint
- Implement webhook signature verification
- Handle subscription lifecycle events
- Update organization billing status
Step 2.6: Testing
- Unit tests for StripeService
- Integration tests for checkout flow
- Webhook event tests
- Subscription status tests
Security Considerations
- Webhook Verification: Verify Stripe webhook signatures
- Customer Validation: Ensure stripe_customer_id belongs to authenticated org
- Idempotency: Handle duplicate webhook events
- Rate Limiting: Limit checkout session creation
- PCI Compliance: Never store card details (handled by Stripe)
Environment Variables
# .env.local
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Stripe Product IDs (created in Stripe Dashboard)
STRIPE_PRODUCT_FREE=prod_free
STRIPE_PRODUCT_PRO=prod_pro
STRIPE_PRODUCT_ENTERPRISE=prod_enterprise
# Stripe Price IDs (created in Stripe Dashboard)
STRIPE_PRICE_PRO=price_pro_monthly
STRIPE_PRICE_ENTERPRISE=price_enterprise_monthly
Stripe Dashboard Setup
- Create Products:
- Pro ($29/month/seat)
- Enterprise ($99/month/seat)
- Create Prices for each product
- Enable webhook endpoint:
https://api.coditect.ai/api/v1/subscriptions/webhook/ - Copy webhook signing secret
Next Steps After Step 2
- Step 3: License generation after successful payment
- Step 4: License API key delivery
- Step 5: SendGrid email notifications
Timeline
- Database Migration: 2 hours
- Stripe Service Implementation: 4 hours
- API Endpoints: 6 hours
- Webhook Handler: 4 hours
- Testing: 4 hours
- Total: 2-3 days