diff --git a/TEST_ENDPOINTS.md b/TEST_ENDPOINTS.md index b33ed42d..f9217776 100644 --- a/TEST_ENDPOINTS.md +++ b/TEST_ENDPOINTS.md @@ -5,16 +5,16 @@ ## ✅ WORKING ENDPOINTS -### Billing V2 Endpoints (New) +### Billing API Endpoints | Endpoint | Method | Status | Notes | |----------|--------|--------|-------| -| `/api/v1/billing/v2/invoices/` | GET | ✅ 401 | Auth required (correct) | -| `/api/v1/billing/v2/payments/` | GET | ✅ 401 | Auth required (correct) | -| `/api/v1/billing/v2/credit-packages/` | GET | ✅ 401 | Auth required (correct) | -| `/api/v1/billing/v2/transactions/` | GET | ✅ 401 | Auth required (correct) | -| `/api/v1/billing/v2/transactions/balance/` | GET | ✅ 401 | Auth required (correct) | -| `/api/v1/billing/v2/admin/stats/` | GET | ✅ 401 | Auth required (correct) | +| `/api/v1/billing/invoices/` | GET | ✅ 401 | Auth required (correct) | +| `/api/v1/billing/payments/` | GET | ✅ 401 | Auth required (correct) | +| `/api/v1/billing/credit-packages/` | GET | ✅ 401 | Auth required (correct) | +| `/api/v1/billing/transactions/` | GET | ✅ 401 | Auth required (correct) | +| `/api/v1/billing/transactions/balance/` | GET | ✅ 401 | Auth required (correct) | +| `/api/v1/billing/admin/stats/` | GET | ✅ 401 | Auth required (correct) | ### Account Endpoints @@ -27,21 +27,19 @@ ## ❌ ISSUES FIXED -### Frontend API Path Issues -**Problem:** Frontend was calling `/api/billing/v2/...` instead of `/api/v1/billing/v2/...` +### Frontend API Path Alignment +**Problem:** Frontend must always call the canonical `/api/v1/billing/...` endpoints (no `/v2` alias). **Files Fixed:** -- `frontend/src/services/billing.api.ts` - Added `/v1/` prefix to all endpoints +- `frontend/src/services/billing.api.ts` – ensured all billing calls use `/v1/billing/...` **Changes:** ```typescript // Before: -fetchAPI('/billing/v2/invoices/') -fetchAPI('/account/settings/') +fetchAPI('/billing/invoices/') // After: -fetchAPI('/v1/billing/v2/invoices/') -fetchAPI('/v1/account/settings/') +fetchAPI('/v1/billing/invoices/') ``` ### Component Export Issues @@ -84,33 +82,33 @@ await createManualPayment({...}) // ✅ | Account Settings | `/account/settings` | ✅ Ready | `/v1/account/settings/` | | Team Management | `/account/team` | ✅ Ready | `/v1/account/team/` | | Usage Analytics | `/account/usage` | ✅ Ready | `/v1/account/usage/analytics/` | -| Purchase Credits | `/account/purchase-credits` | ✅ Ready | `/v1/billing/v2/credit-packages/` | +| Purchase Credits | `/account/purchase-credits` | ✅ Ready | `/v1/billing/credit-packages/` | ### Billing Pages | Page | Route | Status | Backend API | |------|-------|--------|-------------| -| Credits Overview | `/billing/credits` | ✅ Ready | `/v1/billing/v2/transactions/balance/` | -| Transactions | `/billing/transactions` | ✅ Ready | `/v1/billing/v2/transactions/` | -| Usage | `/billing/usage` | ✅ Ready | `/v1/billing/v2/transactions/` | +| Credits Overview | `/billing/credits` | ✅ Ready | `/v1/billing/transactions/balance/` | +| Transactions | `/billing/transactions` | ✅ Ready | `/v1/billing/transactions/` | +| Usage | `/billing/usage` | ✅ Ready | `/v1/billing/transactions/` | | Plans | `/settings/plans` | ✅ Ready | `/v1/auth/plans/` | ### Admin Pages | Page | Route | Status | Backend API | |------|-------|--------|-------------| -| Admin Dashboard | `/admin/billing` | ⏳ Partial | `/v1/billing/v2/admin/stats/` | +| Admin Dashboard | `/admin/billing` | ⏳ Partial | `/v1/billing/admin/stats/` | | Billing Management | `/admin/billing` | ⏳ Partial | Multiple endpoints | ## 🔧 URL STRUCTURE ### Correct URL Pattern ``` -Frontend calls: /v1/billing/v2/invoices/ +Frontend calls: /v1/billing/invoices/ ↓ API Base URL: https://api.igny8.com/api ↓ -Full URL: https://api.igny8.com/api/v1/billing/v2/invoices/ +Full URL: https://api.igny8.com/api/v1/billing/invoices/ ↓ -Backend route: /api/v1/billing/v2/ → igny8_core.business.billing.urls +Backend route: /api/v1/billing/ → igny8_core.business.billing.urls ``` ### API Base URL Detection diff --git a/backend/igny8_core/settings.py b/backend/igny8_core/settings.py index 0be30b10..21c764f8 100644 --- a/backend/igny8_core/settings.py +++ b/backend/igny8_core/settings.py @@ -584,3 +584,11 @@ LOGGING = { }, }, } + +# Billing / Payments configuration +STRIPE_PUBLIC_KEY = os.getenv('STRIPE_PUBLIC_KEY', '') +STRIPE_SECRET_KEY = os.getenv('STRIPE_SECRET_KEY', '') +STRIPE_WEBHOOK_SECRET = os.getenv('STRIPE_WEBHOOK_SECRET', '') +PAYPAL_CLIENT_ID = os.getenv('PAYPAL_CLIENT_ID', '') +PAYPAL_CLIENT_SECRET = os.getenv('PAYPAL_CLIENT_SECRET', '') +PAYPAL_API_BASE = os.getenv('PAYPAL_API_BASE', 'https://api-m.sandbox.paypal.com') diff --git a/backend/igny8_core/urls.py b/backend/igny8_core/urls.py index 6b06c5af..bc5b2b0f 100644 --- a/backend/igny8_core/urls.py +++ b/backend/igny8_core/urls.py @@ -41,8 +41,7 @@ urlpatterns = [ path('api/v1/planner/', include('igny8_core.modules.planner.urls')), path('api/v1/writer/', include('igny8_core.modules.writer.urls')), path('api/v1/system/', include('igny8_core.modules.system.urls')), - path('api/v1/billing/', include('igny8_core.modules.billing.urls')), # Basic billing endpoints (credits, usage) - path('api/v1/billing/', include('igny8_core.business.billing.urls')), # Advanced billing (invoices, payments, packages) + path('api/v1/billing/', include('igny8_core.business.billing.urls')), # Billing (credits, invoices, payments, packages) path('api/v1/admin/', include('igny8_core.modules.billing.admin_urls')), # Admin billing path('api/v1/automation/', include('igny8_core.business.automation.urls')), # Automation endpoints path('api/v1/linker/', include('igny8_core.modules.linker.urls')), # Linker endpoints diff --git a/backend/requirements.txt b/backend/requirements.txt index fc77e50c..f4f76c60 100755 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -13,3 +13,4 @@ beautifulsoup4>=4.12.0 psutil>=5.9.0 docker>=7.0.0 drf-spectacular>=0.27.0 +stripe>=7.10.0 diff --git a/docs/working-docs/CORRECT-API-ENDPOINTS-REFERENCE.md b/docs/working-docs/CORRECT-API-ENDPOINTS-REFERENCE.md deleted file mode 100644 index 98f1b0ee..00000000 --- a/docs/working-docs/CORRECT-API-ENDPOINTS-REFERENCE.md +++ /dev/null @@ -1,287 +0,0 @@ -# CORRECT API Endpoints Reference -**Date:** December 5, 2025 -**Purpose:** Document ACTUAL working backend endpoints for frontend integration - -## ✅ WORKING BILLING ENDPOINTS - -### Credit Balance -**Endpoint:** `GET /v1/billing/credits/balance/balance/` -**Returns:** -```json -{ - "success": true, - "data": { - "credits": 100, - "plan_credits_per_month": 100, - "credits_used_this_month": 0, - "credits_remaining": 100 - } -} -``` - -### Credit Transactions -**Endpoint:** `GET /v1/billing/transactions/` -**Returns:** -```json -{ - "success": true, - "data": { - "results": [ - { - "id": 1, - "amount": 100, - "transaction_type": "grant", - "description": "Initial credits", - "created_at": "2025-12-05T10:00:00Z", - "balance_after": 100 - } - ], - "count": 1 - } -} -``` - -### Credit Usage Logs -**Endpoint:** `GET /v1/billing/credits/usage/` -**Returns:** -```json -{ - "success": true, - "data": { - "results": [ - { - "id": 1, - "operation_type": "clustering", - "credits_used": 10, - "cost_usd": "0.10", - "created_at": "2025-12-05T10:00:00Z" - } - ], - "count": 1 - } -} -``` - -### Invoices -**Endpoint:** `GET /v1/billing/invoices/` -**Returns:** -```json -{ - "results": [ - { - "id": 1, - "invoice_number": "INV-2025-001", - "status": "paid", - "total_amount": "29.00", - "created_at": "2025-12-05T10:00:00Z" - } - ], - "count": 1 -} -``` - -### Payments -**Endpoint:** `GET /v1/billing/payments/` -**Returns:** -```json -{ - "results": [ - { - "id": 1, - "amount": "29.00", - "status": "succeeded", - "payment_method": "stripe", - "created_at": "2025-12-05T10:00:00Z" - } - ], - "count": 1 -} -``` - -### Payment Methods -**Endpoint:** `GET /v1/billing/payment-methods/` -**Returns:** -```json -{ - "results": [ - { - "payment_method": "stripe", - "display_name": "Credit/Debit Card", - "is_enabled": true - } - ] -} -``` - -### Credit Packages -**Endpoint:** `GET /v1/billing/credit-packages/` -**Returns:** -```json -{ - "results": [ - { - "id": 1, - "name": "Starter Pack", - "credits": 500, - "price": "9.00", - "is_active": true - } - ], - "count": 1 -} -``` - -## ✅ WORKING ACCOUNT ENDPOINTS - -### Account Settings -**Endpoint:** `GET /v1/account/settings/` -**Returns:** -```json -{ - "id": 1, - "name": "My Account", - "slug": "my-account", - "billing_address_line1": "123 Main St", - "billing_city": "New York", - "credit_balance": 100, - "created_at": "2025-01-01T00:00:00Z" -} -``` - -### Update Account Settings -**Endpoint:** `PATCH /v1/account/settings/` -**Body:** -```json -{ - "name": "Updated Account Name", - "billing_address_line1": "456 New St" -} -``` - -### Team Members -**Endpoint:** `GET /v1/account/team/` -**Returns:** -```json -{ - "results": [ - { - "id": 1, - "email": "user@example.com", - "first_name": "John", - "last_name": "Doe", - "is_active": true, - "is_staff": false, - "date_joined": "2025-01-01T00:00:00Z" - } - ], - "count": 1 -} -``` - -### Usage Analytics -**Endpoint:** `GET /v1/account/usage/analytics/` -**Query Params:** `?days=30` -**Returns:** -```json -{ - "period_days": 30, - "current_balance": 100, - "usage_by_type": [ - { - "transaction_type": "deduction", - "total": -50, - "count": 5 - } - ], - "daily_usage": [ - { - "date": "2025-12-05", - "usage": 10, - "purchases": 0, - "net": -10 - } - ], - "total_usage": 50, - "total_purchases": 0 -} -``` - -## ⚠️ CORRECT DATA STRUCTURE FOR PAGES - -### AccountBillingPage.tsx -**Should use:** -- `getCreditBalance()` → `/v1/billing/credits/balance/balance/` -- `getInvoices()` → `/v1/billing/invoices/` -- `getPayments()` → `/v1/billing/payments/` - -**Data fields to use:** -```typescript -creditBalance.credits // NOT balance -creditBalance.plan_credits_per_month // NOT monthly_credits -creditBalance.credits_used_this_month // NEW field -``` - -### AccountSettingsPage.tsx -**Should use:** -- `getAccountSettings()` → `/v1/account/settings/` -- `updateAccountSettings(data)` → `PATCH /v1/account/settings/` - -### TeamManagementPage.tsx -**Should use:** -- `getTeamMembers()` → `/v1/account/team/` -- `inviteTeamMember(email)` → `POST /v1/account/team/` -- `removeTeamMember(id)` → `DELETE /v1/account/team/{id}/` - -### UsageAnalyticsPage.tsx -**Should use:** -- `getUsageAnalytics(days)` → `/v1/account/usage/analytics/?days=30` - -**Data fields to use:** -```typescript -analytics.current_balance -analytics.usage_by_type // Array with transaction_type, total, count -analytics.daily_usage // Array with date, usage, purchases, net -analytics.total_usage -analytics.total_purchases -``` - -### PurchaseCreditsPage.tsx -**Should use:** -- `getCreditPackages()` → `/v1/billing/credit-packages/` -- `getPaymentMethods()` → `/v1/billing/payment-methods/` -- `purchaseCreditPackage(data)` → `POST /v1/billing/credit-packages/{id}/purchase/` - -## 🔑 KEY POINTS - -1. **Account Relationship:** All endpoints automatically filter by the logged-in user's account. The backend middleware sets `request.account` from the JWT token. - -2. **Unified Response Format:** All endpoints return data in the format: - ```json - { - "success": true, - "data": { ... } - } - ``` - The `fetchAPI` function in `services/api.ts` automatically extracts the `data` field. - -3. **Field Names:** Backend uses specific field names that MUST match in frontend: - - `credits` (NOT `balance`) - - `plan_credits_per_month` (NOT `monthly_credits`) - - `credits_used_this_month` (NEW) - - `credits_remaining` (NEW) - -4. **No Fake Data:** Pages must load real data from these endpoints. NO placeholder data. - -5. **Error Handling:** If endpoint returns 404, the backend route is not registered. Check `backend/igny8_core/urls.py` and restart backend container. - -## 🛠️ FRONTEND FIX CHECKLIST - -- [ ] Update `billing.api.ts` to use correct endpoints -- [ ] Update type interfaces to match backend response -- [ ] Fix AccountBillingPage to use `credits`, `plan_credits_per_month`, `credits_used_this_month` -- [ ] Fix UsageAnalyticsPage to use `usage_by_type`, `daily_usage` structure -- [ ] Fix PurchaseCreditsPage to call correct payment-methods endpoint -- [ ] Fix TeamManagementPage to handle optional `date_joined` field -- [ ] Fix AccountSettingsPage to load from `/v1/account/settings/` -- [ ] Remove all placeholder/fake data -- [ ] Test all pages with real backend data diff --git a/docs/working-docs/Original-plan-may-have-wrong-logic.md b/docs/working-docs/Original-plan-may-have-wrong-logic.md deleted file mode 100644 index 0db5bfef..00000000 --- a/docs/working-docs/Original-plan-may-have-wrong-logic.md +++ /dev/null @@ -1,1449 +0,0 @@ -# SaaS Platform Standardization Plan - -**Date:** December 4, 2025 -**Status:** 🎯 PHASE 1 COMPLETE - Backend Models Ready -**Priority:** CRITICAL - Core SaaS Infrastructure - -**Implementation Progress:** -- ✅ All backend models created (Invoice, Payment, CreditPackage, PaymentMethodConfig) -- ✅ Account model updated with billing address fields -- ✅ Multi-payment gateway support (Stripe, PayPal, Manual) -- ✅ Per-country payment configuration -- ⏳ Ready for database migrations -- 📋 See IMPLEMENTATION-GUIDE-DEC-4-2025.md for detailed task breakdown -- 📄 See SESSION-SUMMARY-DEC-4-2025.md for current status - ---- - -## 📋 EXECUTIVE SUMMARY - -This document provides a comprehensive, standardized plan for IGNY8's SaaS infrastructure covering: -- User Management & Access Control -- Account/Tenant Management (Multi-tenancy) -- Plans & Subscriptions -- Credits System & Usage Tracking -- Billing, Invoices & Payments -- Account Limits & Quotas -- Frontend UI Standardization -- Admin Controls & Configuration - -**Current State:** -✅ Multi-tenancy implemented -✅ Credits system fully functional -✅ Basic billing UI exists -⚠️ Payment integration NOT implemented -⚠️ Invoice generation NOT implemented -⚠️ Subscription management incomplete -⚠️ UI fragmented across multiple menus - -**Goal:** Create a best-practice SaaS platform with clear separation of concerns, proper admin controls, and streamlined user experience. - ---- - -## 🏗️ ARCHITECTURE OVERVIEW - -### Multi-Tenant Architecture - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ IGNY8 SAAS PLATFORM │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ ACCOUNT (Tenant) │ -│ ├─ Owner + Users (Role-based) │ -│ ├─ Plan (Subscription Tier) │ -│ ├─ Credits Balance │ -│ ├─ Sites (1-N based on plan) │ -│ ├─ Subscription (Stripe integration) │ -│ └─ Billing Data (Transactions, Usage, Invoices) │ -│ │ -│ USER │ -│ ├─ Role (developer, owner, admin, editor, viewer) │ -│ ├─ Account (tenant_id) │ -│ └─ Site Access (multi-site accounts) │ -│ │ -│ PLAN │ -│ ├─ Price & Billing Cycle │ -│ ├─ Included Credits/Month │ -│ ├─ Account Limits (sites, users, etc.) │ -│ └─ Stripe Product/Price IDs │ -│ │ -│ CREDITS SYSTEM │ -│ ├─ Account Balance │ -│ ├─ Transactions (purchase, grant, deduction, refund) │ -│ ├─ Usage Logs (per AI operation) │ -│ └─ Cost Config (admin-configurable) │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - ---- - -## 🎯 CORE ENTITIES & RELATIONSHIPS - -### 1. Account (Tenant) - -**Current Model:** `igny8_core.auth.models.Account` - -**Fields:** -```python -- id (PK) -- name -- slug (unique) -- owner (FK → User) -- plan (FK → Plan) -- credits (integer) -- stripe_customer_id -- status (active, suspended, trial, cancelled) -- created_at, updated_at -``` - -**Status:** ✅ Working - Well implemented - -**Relationships:** -- 1 Account → Many Users -- 1 Account → 1 Plan (current plan) -- 1 Account → 1 Subscription (optional, Stripe) -- 1 Account → Many Sites -- 1 Account → Many CreditTransactions -- 1 Account → Many CreditUsageLogs - ---- - -### 2. User - -**Current Model:** `igny8_core.auth.models.User` - -**Fields:** -```python -- id (PK) -- email (unique, username) -- account (FK → Account, tenant_id) -- role (developer, owner, admin, editor, viewer, system_bot) -- is_active, is_staff, is_superuser -- created_at, updated_at -``` - -**Roles Hierarchy:** -- **developer**: Super admin, all access, bypasses multi-tenancy -- **owner**: Account owner, full account access -- **admin**: Account admin, full account access -- **editor**: Can edit content, limited settings -- **viewer**: Read-only access - -**Status:** ✅ Working - Well implemented - -**Gaps to Address:** -- [ ] Add user invitation system -- [ ] Add user activity tracking -- [ ] Add last_login tracking per site - ---- - -### 3. Plan - -**Current Model:** `igny8_core.auth.models.Plan` - -**Fields:** -```python -- id (PK) -- name, slug (unique) -- price (Decimal) -- billing_cycle (monthly, annual) -- included_credits (monthly allocation) -- extra_credit_price (price per additional credit) -- allow_credit_topup (boolean) -- max_users, max_sites, max_industries, max_author_profiles -- stripe_product_id, stripe_price_id -- is_active -- features (JSON array) -``` - -**Status:** ✅ Working - Well designed - -**Recommended Plans Structure:** - -#### Free Plan -- Price: $0/month -- Credits: 100/month -- Sites: 1 -- Users: 1 -- Features: Basic AI tools - -#### Starter Plan -- Price: $29/month -- Credits: 1,000/month -- Sites: 3 -- Users: 2 -- Features: Full AI suite, automation - -#### Professional Plan -- Price: $99/month -- Credits: 5,000/month -- Sites: 10 -- Users: 5 -- Features: Priority support, advanced analytics - -#### Enterprise Plan -- Price: $299/month -- Credits: 20,000/month -- Sites: Unlimited -- Users: 20 -- Features: Custom integrations, dedicated support - ---- - -### 4. Subscription - -**Current Model:** `igny8_core.auth.models.Subscription` - -**Fields:** -```python -- id (PK) -- account (OneToOne → Account) -- stripe_subscription_id (unique) -- status (active, past_due, canceled, trialing) -- current_period_start, current_period_end -- cancel_at_period_end -- created_at, updated_at -``` - -**Status:** ⚠️ Model exists but Stripe integration NOT implemented - -**Missing Features:** -- [ ] Stripe webhook handlers -- [ ] Subscription creation flow -- [ ] Plan upgrade/downgrade -- [ ] Cancellation flow -- [ ] Trial period management -- [ ] Past due handling - ---- - -### 5. Credit System - -#### CreditTransaction - -**Current Model:** `igny8_core.business.billing.models.CreditTransaction` - -**Fields:** -```python -- id (PK) -- account (FK) -- transaction_type (purchase, subscription, refund, deduction, adjustment) -- amount (integer, +/-) -- balance_after -- description -- metadata (JSON) -- created_at -``` - -**Status:** ✅ Working perfectly - -#### CreditUsageLog - -**Current Model:** `igny8_core.business.billing.models.CreditUsageLog` - -**Fields:** -```python -- id (PK) -- account (FK) -- operation_type (clustering, idea_generation, content_generation, etc.) -- credits_used -- cost_usd (Decimal) -- model_used (AI model name) -- tokens_input, tokens_output -- related_object_type, related_object_id -- metadata (JSON) -- created_at -``` - -**Status:** ✅ Working perfectly - -#### CreditCostConfig - -**Current Model:** `igny8_core.business.billing.models.CreditCostConfig` - -**Fields:** -```python -- id (PK) -- operation_type (unique) -- credits_cost -- unit (per_request, per_100_words, per_image, etc.) -- display_name, description -- is_active -- updated_by (FK → User) -- previous_cost (audit trail) -- created_at, updated_at -``` - -**Status:** ✅ Implemented (Dec 4, 2025) - -**Operations & Costs:** -| Operation | Cost | Unit | -|-----------|------|------| -| Auto Clustering | 10 | per_request | -| Idea Generation | 15 | per_request | -| Content Generation | 1 | per_100_words | -| Image Prompt Extraction | 2 | per_request | -| Image Generation | 5 | per_image | -| Content Linking | 8 | per_request | -| Optimization | 1 | per_200_words | -| Site Structure | 50 | per_request | -| Site Page Gen | 20 | per_item | - ---- - -## ❌ MISSING COMPONENTS (TO IMPLEMENT) - -### 1. Invoice Model - -**Purpose:** Track billing invoices for payments - -**Proposed Model:** - -```python -class Invoice(AccountBaseModel): - """ - Invoice for subscription or credit purchases - """ - STATUS_CHOICES = [ - ('draft', 'Draft'), - ('pending', 'Pending'), - ('paid', 'Paid'), - ('void', 'Void'), - ('uncollectible', 'Uncollectible'), - ] - - invoice_number = models.CharField(max_length=50, unique=True) - subscription = models.ForeignKey(Subscription, null=True, on_delete=SET_NULL) - - # Amounts - subtotal = models.DecimalField(max_digits=10, decimal_places=2) - tax = models.DecimalField(max_digits=10, decimal_places=2, default=0) - total = models.DecimalField(max_digits=10, decimal_places=2) - - # Status - status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending') - - # Dates - invoice_date = models.DateField() - due_date = models.DateField() - paid_at = models.DateTimeField(null=True) - - # Line items - line_items = models.JSONField(default=list) # [{description, amount, quantity}] - - # Payment - stripe_invoice_id = models.CharField(max_length=255, null=True) - payment_method = models.CharField(max_length=50, null=True) # 'stripe', 'manual' - - # Metadata - notes = models.TextField(blank=True) - metadata = models.JSONField(default=dict) - - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) -``` - -**Priority:** HIGH - Required for payment tracking - ---- - -### 2. Payment Model - -**Purpose:** Track individual payments - -**Proposed Model:** - -```python -class Payment(AccountBaseModel): - """ - Payment record for invoice or credit purchase - Supports: Stripe, PayPal, Manual (Bank Transfer, Local Wallet) - """ - STATUS_CHOICES = [ - ('pending', 'Pending'), - ('processing', 'Processing'), - ('succeeded', 'Succeeded'), - ('failed', 'Failed'), - ('refunded', 'Refunded'), - ('cancelled', 'Cancelled'), - ] - - PAYMENT_METHOD_CHOICES = [ - ('stripe', 'Stripe (Credit/Debit Card)'), - ('paypal', 'PayPal'), - ('bank_transfer', 'Bank Transfer (Manual)'), - ('local_wallet', 'Local Wallet (Manual)'), - ('manual', 'Manual Payment'), - ] - - invoice = models.ForeignKey(Invoice, on_delete=CASCADE, related_name='payments') - - # Amount - amount = models.DecimalField(max_digits=10, decimal_places=2) - currency = models.CharField(max_length=3, default='USD') - - # Status - status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending') - - # Payment method - payment_method = models.CharField(max_length=50, choices=PAYMENT_METHOD_CHOICES) - - # Stripe integration - stripe_payment_intent_id = models.CharField(max_length=255, null=True, blank=True) - stripe_charge_id = models.CharField(max_length=255, null=True, blank=True) - - # PayPal integration - paypal_order_id = models.CharField(max_length=255, null=True, blank=True) - paypal_capture_id = models.CharField(max_length=255, null=True, blank=True) - - # Manual payment details - manual_reference = models.CharField(max_length=255, blank=True, help_text="Bank transfer reference, wallet transaction ID, etc.") - manual_notes = models.TextField(blank=True, help_text="Admin notes for manual payments") - approved_by = models.ForeignKey('auth.User', null=True, blank=True, on_delete=SET_NULL, related_name='approved_payments') - approved_at = models.DateTimeField(null=True, blank=True) - - # Timestamps - processed_at = models.DateTimeField(null=True) - failed_at = models.DateTimeField(null=True) - refunded_at = models.DateTimeField(null=True) - - # Error tracking - failure_reason = models.TextField(blank=True) - - # Metadata - metadata = models.JSONField(default=dict) - - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) -``` - -**Priority:** HIGH - ---- - -### 3. CreditPackage Model - -**Purpose:** Define purchasable credit bundles - -**Proposed Model:** - -```python -class CreditPackage(models.Model): - """ - One-time credit purchase packages - """ - name = models.CharField(max_length=100) - slug = models.SlugField(unique=True) - - # Credits - credits = models.IntegerField(validators=[MinValueValidator(1)]) - - # Pricing - price = models.DecimalField(max_digits=10, decimal_places=2) - discount_percentage = models.IntegerField(default=0) # Optional discount - - # Stripe - stripe_product_id = models.CharField(max_length=255, null=True) - stripe_price_id = models.CharField(max_length=255, null=True) - - # Status - is_active = models.BooleanField(default=True) - is_featured = models.BooleanField(default=False) - - # Display - description = models.TextField(blank=True) - features = models.JSONField(default=list) # Bonus features - - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) -``` - -**Recommended Packages:** -- Starter: 500 credits - $9 -- Pro: 2,000 credits - $29 (10% discount) -- Business: 5,000 credits - $69 (15% discount) -- Enterprise: 20,000 credits - $249 (20% discount) - -**Priority:** MEDIUM - ---- - -### 4. AccountLimit Model (Optional) - -**Purpose:** Track dynamic account limits and usage - -**Proposed Model:** - -```python -class AccountLimit(AccountBaseModel): - """ - Track account limits and current usage - """ - LIMIT_TYPE_CHOICES = [ - ('sites', 'Sites'), - ('users', 'Users'), - ('keywords', 'Keywords'), - ('content_items', 'Content Items'), - ('api_calls_per_day', 'API Calls Per Day'), - ] - - limit_type = models.CharField(max_length=50, choices=LIMIT_TYPE_CHOICES) - max_allowed = models.IntegerField() - current_usage = models.IntegerField(default=0) - - # Metadata - reset_period = models.CharField(max_length=20, null=True) # 'daily', 'monthly', 'never' - last_reset = models.DateTimeField(null=True) - - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - unique_together = [['account', 'limit_type']] -``` - -**Priority:** LOW - Can use Plan limits directly - ---- - -### 5. PaymentMethodConfig Model - -**Purpose:** Configure which payment methods are enabled per country - -**Proposed Model:** - -```python -class PaymentMethodConfig(models.Model): - """ - Configure payment methods availability per country - Allows enabling/disabling manual payments by region - """ - PAYMENT_METHOD_CHOICES = [ - ('stripe', 'Stripe'), - ('paypal', 'PayPal'), - ('bank_transfer', 'Bank Transfer'), - ('local_wallet', 'Local Wallet'), - ] - - country_code = models.CharField(max_length=2, help_text="ISO 2-letter country code (e.g., US, GB, IN)") - payment_method = models.CharField(max_length=50, choices=PAYMENT_METHOD_CHOICES) - is_enabled = models.BooleanField(default=True) - - # Display info - display_name = models.CharField(max_length=100, blank=True) - instructions = models.TextField(blank=True, help_text="Payment instructions for users") - - # Manual payment details (for bank_transfer/local_wallet) - bank_name = models.CharField(max_length=255, blank=True) - account_number = models.CharField(max_length=255, blank=True) - routing_number = models.CharField(max_length=255, blank=True) - swift_code = models.CharField(max_length=255, blank=True) - - # Order/priority - sort_order = models.IntegerField(default=0) - - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - unique_together = [['country_code', 'payment_method']] - ordering = ['country_code', 'sort_order'] -``` - -**Priority:** MEDIUM - Required for regional payment flexibility - ---- - -## 🎨 FRONTEND UI STANDARDIZATION - -### Current UI State - -**User Menu Structure (Non-Admin):** -``` -Settings (collapsible) -├─ General -├─ Plans -├─ Integration -├─ Publishing -└─ Import / Export - -Billing (collapsible) -├─ Overview -├─ Credits -├─ Transactions -└─ Usage - -Help & Documentation -``` - -**Admin Menu Structure (aws-admin only):** -``` -ADMIN -├─ Billing & Credits (collapsible) -│ ├─ Billing Management -│ └─ Credit Costs -├─ User Management (collapsible) -│ ├─ Users -│ └─ Subscriptions -├─ Configuration (collapsible) -│ ├─ System Settings -│ ├─ Account Settings -│ └─ Module Settings -├─ AI Controls (collapsible) -│ └─ AI Settings -├─ System Health (collapsible) -│ ├─ Status -│ ├─ API Monitor -│ └─ Debug Status -└─ Testing Tools, UI Elements... -``` - ---- - -### ⚠️ PROBLEMS WITH CURRENT UI - -1. **Fragmented Billing Info** - - Credits, Transactions, Usage in separate pages - - No unified billing dashboard - - Purchase flow not visible - -2. **Missing Subscription Management** - - No plan upgrade/downgrade UI - - No subscription status visibility - - No payment method management - -3. **Admin Controls Scattered** - - User management in settings - - Billing in separate admin section - - No unified admin dashboard - -4. **No Account Settings Page** - - Account name, billing address missing - - Team management incomplete - - Account limits not visible - ---- - -### ✅ PROPOSED UI STRUCTURE - -#### User Menu (All Users) - -``` -Dashboard - -SETUP -├─ Add Keywords -├─ Sites -└─ Thinker (if enabled) - -WORKFLOW -├─ Planner (if enabled) -├─ Writer (if enabled) -├─ Automation (if enabled) -├─ Linker (if enabled) -└─ Optimizer (if enabled) - -ACCOUNT (NEW SECTION) -├─ Account Settings (NEW) -│ └─ Account Info, Billing Address, Team -├─ Plans & Billing (CONSOLIDATED) -│ ├─ Current Plan -│ ├─ Upgrade/Downgrade -│ ├─ Credits Overview -│ ├─ Purchase Credits -│ ├─ Billing History (Invoices) -│ └─ Payment Methods -├─ Team Management (NEW) -│ ├─ Users -│ ├─ Invitations -│ └─ Access Control -└─ Usage & Analytics (NEW) - ├─ Credit Usage - ├─ API Usage - └─ Cost Breakdown - -SETTINGS (Personal) -├─ Profile Settings -├─ Integration -├─ Publishing -└─ Import / Export - -HELP & DOCS -``` - -#### Admin Menu (Superuser Only) - -``` -ADMIN -├─ System Dashboard (NEW) -│ └─ Overview, Stats, Alerts -├─ Account Management (NEW) -│ ├─ All Accounts -│ ├─ Subscriptions -│ └─ Account Limits -├─ Billing Administration -│ ├─ Billing Overview -│ ├─ Invoices -│ ├─ Payments -│ ├─ Credit Costs Config -│ └─ Credit Packages -├─ User Administration -│ ├─ All Users -│ ├─ Roles & Permissions -│ └─ Activity Logs -├─ System Configuration -│ ├─ System Settings -│ ├─ AI Settings -│ ├─ Module Settings -│ └─ Integration Settings -├─ Monitoring -│ ├─ System Health -│ ├─ API Monitor -│ └─ Usage Analytics -└─ Developer Tools - ├─ Function Testing - ├─ System Testing - └─ UI Elements -``` - ---- - -## 📄 NEW PAGES TO CREATE - -### 1. Account Settings Page - -**Path:** `/account/settings` -**Access:** Owner, Admin - -**Sections:** -- Account Information (name, slug, status) -- Billing Address -- Tax Information -- Account Limits (sites, users, credits) -- Danger Zone (delete account, transfer ownership) - -**Priority:** HIGH - ---- - -### 2. Plans & Billing Page (Consolidated) - -**Path:** `/account/billing` -**Access:** Owner, Admin - -**Tabs:** -1. **Current Plan** - - Plan details, included credits - - Upgrade/downgrade buttons - - Subscription status - -2. **Credits** - - Current balance - - Monthly included - - Purchase credits (packages) - - Usage this month - -3. **Billing History** - - Invoices table - - Download PDF - - Payment status - -4. **Payment Methods** - - Saved cards - - Add/remove methods - - Default payment method - -**Priority:** HIGH - ---- - -### 3. Team Management Page - -**Path:** `/account/team` -**Access:** Owner, Admin - -**Features:** -- List team members -- Invite users (email invitation) -- Manage roles -- Remove users -- Site access control (multi-site accounts) - -**Priority:** MEDIUM - ---- - -### 4. Usage & Analytics Page - -**Path:** `/account/usage` -**Access:** All users (filtered by role) - -**Charts:** -- Credit usage over time -- Cost breakdown by operation -- API calls per day -- Top consuming operations - -**Priority:** MEDIUM - ---- - -### 5. Purchase Credits Page - -**Path:** `/account/credits/purchase` -**Access:** Owner, Admin - -**Features:** -- Credit packages display -- Stripe checkout integration -- Payment confirmation -- Credits added to balance - -**Priority:** HIGH - ---- - -### 6. Invoices Page - -**Path:** `/account/invoices` -**Access:** Owner, Admin - -**Features:** -- Invoice list (table) -- Filter by status, date -- Download PDF -- View details -- Payment status - -**Priority:** HIGH - ---- - -### 7. Admin: All Accounts Page - -**Path:** `/admin/accounts` -**Access:** Superuser only - -**Features:** -- Search accounts -- Filter by status, plan -- View account details -- Adjust credits -- Suspend/activate accounts - -**Priority:** MEDIUM - ---- - -### 8. Admin: System Dashboard - -**Path:** `/admin/dashboard` -**Access:** Superuser only - -**Metrics:** -- Total accounts -- Active subscriptions -- Revenue this month -- Credits issued/used -- System health status - -**Priority:** MEDIUM - ---- - -## 🔌 PAYMENT INTEGRATION PLAN - -### Stripe Integration - -**Status:** ⚠️ NOT IMPLEMENTED (fields exist but no webhooks/flows) - -**Required Components:** - -#### 1. Stripe Setup -```python -# settings.py -STRIPE_PUBLIC_KEY = env('STRIPE_PUBLIC_KEY') -STRIPE_SECRET_KEY = env('STRIPE_SECRET_KEY') -STRIPE_WEBHOOK_SECRET = env('STRIPE_WEBHOOK_SECRET') -``` - -#### 2. Webhook Handlers - -**File:** `backend/igny8_core/business/billing/webhooks.py` - -```python -@csrf_exempt -def stripe_webhook(request): - """Handle Stripe webhooks""" - payload = request.body - sig_header = request.META.get('HTTP_STRIPE_SIGNATURE') - - try: - event = stripe.Webhook.construct_event( - payload, sig_header, settings.STRIPE_WEBHOOK_SECRET - ) - except ValueError: - return HttpResponse(status=400) - except stripe.error.SignatureVerificationError: - return HttpResponse(status=400) - - # Handle events - if event['type'] == 'invoice.paid': - handle_invoice_paid(event['data']['object']) - elif event['type'] == 'invoice.payment_failed': - handle_payment_failed(event['data']['object']) - elif event['type'] == 'customer.subscription.deleted': - handle_subscription_deleted(event['data']['object']) - elif event['type'] == 'customer.subscription.updated': - handle_subscription_updated(event['data']['object']) - - return HttpResponse(status=200) -``` - -**Priority:** CRITICAL - -#### 3. Subscription Creation Flow - -**API Endpoint:** `POST /v1/billing/subscriptions/create/` - -```python -@action(detail=False, methods=['post']) -def create_subscription(self, request): - """Create Stripe subscription""" - plan_id = request.data.get('plan_id') - payment_method_id = request.data.get('payment_method_id') - - plan = Plan.objects.get(id=plan_id) - account = request.user.account - - # Create or retrieve Stripe customer - if not account.stripe_customer_id: - customer = stripe.Customer.create( - email=request.user.email, - name=account.name, - payment_method=payment_method_id, - invoice_settings={'default_payment_method': payment_method_id} - ) - account.stripe_customer_id = customer.id - account.save() - - # Create subscription - subscription = stripe.Subscription.create( - customer=account.stripe_customer_id, - items=[{'price': plan.stripe_price_id}], - payment_behavior='default_incomplete', - expand=['latest_invoice.payment_intent'] - ) - - # Save subscription - Subscription.objects.create( - account=account, - stripe_subscription_id=subscription.id, - status=subscription.status, - current_period_start=datetime.fromtimestamp(subscription.current_period_start), - current_period_end=datetime.fromtimestamp(subscription.current_period_end) - ) - - return Response({ - 'subscription_id': subscription.id, - 'client_secret': subscription.latest_invoice.payment_intent.client_secret - }) -``` - -**Priority:** CRITICAL - -#### 4. Credit Purchase Flow - -**API Endpoint:** `POST /v1/billing/credits/purchase/` - -```python -@action(detail=False, methods=['post']) -def purchase_credits(self, request): - """Purchase credit package""" - package_id = request.data.get('package_id') - - package = CreditPackage.objects.get(id=package_id) - account = request.user.account - - # Create payment intent - intent = stripe.PaymentIntent.create( - amount=int(package.price * 100), # Convert to cents - currency='usd', - customer=account.stripe_customer_id, - metadata={ - 'account_id': account.id, - 'package_id': package.id, - 'credits': package.credits - } - ) - - return Response({ - 'client_secret': intent.client_secret, - 'package': CreditPackageSerializer(package).data - }) -``` - -**Priority:** HIGH - ---- - -## 🔐 ACCESS CONTROL & PERMISSIONS - -### Role-Based Permissions - -| Feature | Developer | Owner | Admin | Editor | Viewer | -|---------|-----------|-------|-------|--------|--------| -| View Account Settings | ✅ | ✅ | ✅ | ❌ | ❌ | -| Edit Account Settings | ✅ | ✅ | ❌ | ❌ | ❌ | -| View Billing | ✅ | ✅ | ✅ | ❌ | ❌ | -| Purchase Credits | ✅ | ✅ | ✅ | ❌ | ❌ | -| Manage Subscription | ✅ | ✅ | ❌ | ❌ | ❌ | -| Invite Users | ✅ | ✅ | ✅ | ❌ | ❌ | -| Manage User Roles | ✅ | ✅ | ❌ | ❌ | ❌ | -| View Usage Analytics | ✅ | ✅ | ✅ | ✅ | ✅ | -| Access Admin Panel | ✅ | ❌ | ❌ | ❌ | ❌ | -| Configure Credit Costs | ✅ | ❌ | ❌ | ❌ | ❌ | -| View All Accounts | ✅ | ❌ | ❌ | ❌ | ❌ | - ---- - -## 📊 DATABASE MIGRATIONS REQUIRED - -### New Models to Create - -1. **Invoice** - HIGH priority -2. **Payment** - HIGH priority -3. **CreditPackage** - MEDIUM priority -4. **AccountLimit** (optional) - LOW priority - -### Migrations to Add - -```bash -# Create invoice and payment models -python manage.py makemigrations billing --name add_invoice_payment_models - -# Create credit packages -python manage.py makemigrations billing --name add_credit_packages - -# Add missing fields to existing models -python manage.py makemigrations auth --name add_billing_address_fields -``` - ---- - -## 🚀 IMPLEMENTATION ROADMAP - -### Phase 1: Core Billing Infrastructure (Week 1-2) - -**Priority:** CRITICAL - -1. ✅ Create Invoice model -2. ✅ Create Payment model -3. ✅ Create CreditPackage model -4. ✅ Stripe webhook handlers -5. ✅ Subscription creation API -6. ✅ Credit purchase API - -**Deliverables:** -- Functional payment processing -- Invoice generation -- Subscription management - ---- - -### Phase 2: Frontend UI Overhaul (Week 3-4) - -**Priority:** HIGH - -1. ✅ Create Account Settings page -2. ✅ Consolidate Plans & Billing page -3. ✅ Create Team Management page -4. ✅ Create Purchase Credits page -5. ✅ Create Invoices page -6. ✅ Update navigation structure - -**Deliverables:** -- Unified account management UI -- Streamlined billing experience -- Professional SaaS interface - ---- - -### Phase 3: Admin Dashboard (Week 5-6) - -**Priority:** MEDIUM - -1. ✅ Create Admin System Dashboard -2. ✅ Create All Accounts management page -3. ✅ Create Billing Administration pages -4. ✅ Create User Administration pages -5. ✅ Add comprehensive filtering/search - -**Deliverables:** -- Complete admin control panel -- Account management tools -- System monitoring - ---- - -### Phase 4: Analytics & Reporting (Week 7-8) - -**Priority:** MEDIUM - -1. ✅ Create Usage & Analytics page -2. ✅ Implement cost breakdown charts -3. ✅ Add usage forecasting -4. ✅ Create PDF invoice generation -5. ✅ Add export capabilities - -**Deliverables:** -- Usage insights -- Cost optimization tools -- Professional invoices - ---- - -### Phase 5: Advanced Features (Week 9-12) - -**Priority:** LOW - -1. ✅ User invitation system -2. ✅ Email notifications -3. ✅ Auto top-up credits -4. ✅ Budget alerts -5. ✅ API rate limiting -6. ✅ Multi-currency support - -**Deliverables:** -- Enhanced user experience -- Proactive notifications -- International expansion ready - ---- - -## 📋 API ENDPOINTS TO IMPLEMENT - -### Billing APIs - -| Endpoint | Method | Purpose | Priority | -|----------|--------|---------|----------| -| `/v1/billing/account_balance/` | GET | Get credit balance | ✅ EXISTS | -| `/v1/billing/transactions/` | GET | List transactions | ✅ EXISTS | -| `/v1/billing/usage/` | GET | List usage logs | ✅ EXISTS | -| `/v1/billing/invoices/` | GET | List invoices | ❌ MISSING | -| `/v1/billing/invoices/:id/` | GET | Get invoice details | ❌ MISSING | -| `/v1/billing/invoices/:id/pdf/` | GET | Download PDF | ❌ MISSING | -| `/v1/billing/subscriptions/` | GET | Get subscription | ❌ MISSING | -| `/v1/billing/subscriptions/create/` | POST | Create subscription | ❌ MISSING | -| `/v1/billing/subscriptions/cancel/` | POST | Cancel subscription | ❌ MISSING | -| `/v1/billing/subscriptions/upgrade/` | POST | Upgrade plan | ❌ MISSING | -| `/v1/billing/credits/packages/` | GET | List credit packages | ❌ MISSING | -| `/v1/billing/credits/purchase/` | POST | Purchase credits | ❌ MISSING | -| `/v1/billing/payment-methods/` | GET | List payment methods | ❌ MISSING | -| `/v1/billing/payment-methods/` | POST | Add payment method | ❌ MISSING | -| `/v1/billing/webhooks/stripe/` | POST | Stripe webhooks | ❌ MISSING | - -### Account Management APIs - -| Endpoint | Method | Purpose | Priority | -|----------|--------|---------|----------| -| `/v1/account/settings/` | GET | Get account info | ❌ MISSING | -| `/v1/account/settings/` | PATCH | Update account | ❌ MISSING | -| `/v1/account/limits/` | GET | Get account limits | ❌ MISSING | -| `/v1/account/team/` | GET | List team members | ❌ MISSING | -| `/v1/account/team/invite/` | POST | Invite user | ❌ MISSING | -| `/v1/account/team/:id/` | DELETE | Remove user | ❌ MISSING | -| `/v1/account/usage/analytics/` | GET | Usage analytics | ❌ MISSING | - -### Admin APIs - -| Endpoint | Method | Purpose | Priority | -|----------|--------|---------|----------| -| `/v1/admin/accounts/` | GET | List all accounts | ❌ MISSING | -| `/v1/admin/accounts/:id/adjust-credits/` | POST | Adjust credits | ✅ EXISTS | -| `/v1/admin/accounts/:id/suspend/` | POST | Suspend account | ❌ MISSING | -| `/v1/admin/billing/stats/` | GET | Billing statistics | ✅ EXISTS | -| `/v1/admin/invoices/` | GET | All invoices | ❌ MISSING | -| `/v1/admin/payments/` | GET | All payments | ❌ MISSING | -| `/v1/admin/credit-costs/` | GET | Credit costs config | ✅ EXISTS | -| `/v1/admin/users/` | GET | All users | ✅ EXISTS | - ---- - -## 🔧 BACKEND SERVICES TO CREATE - -### 1. SubscriptionService - -**File:** `backend/igny8_core/business/billing/services/subscription_service.py` - -**Methods:** -- `create_subscription(account, plan, payment_method)` -- `cancel_subscription(subscription, cancel_at_period_end=True)` -- `upgrade_subscription(subscription, new_plan)` -- `downgrade_subscription(subscription, new_plan)` -- `reactivate_subscription(subscription)` -- `sync_from_stripe(stripe_subscription_id)` - -**Priority:** CRITICAL - ---- - -### 2. InvoiceService - -**File:** `backend/igny8_core/business/billing/services/invoice_service.py` - -**Methods:** -- `create_invoice(account, line_items)` -- `generate_invoice_number()` -- `mark_paid(invoice, payment)` -- `mark_void(invoice)` -- `generate_pdf(invoice)` -- `send_invoice_email(invoice)` - -**Priority:** HIGH - ---- - -### 3. PaymentService - -**File:** `backend/igny8_core/business/billing/services/payment_service.py` - -**Methods:** -- `process_payment(invoice, payment_method)` -- `process_refund(payment, amount)` -- `handle_payment_success(stripe_payment_intent)` -- `handle_payment_failure(stripe_payment_intent)` -- `sync_from_stripe(stripe_payment_id)` - -**Priority:** HIGH - ---- - -### 4. CreditPackageService - -**File:** `backend/igny8_core/business/billing/services/credit_package_service.py` - -**Methods:** -- `purchase_package(account, package, payment_method)` -- `apply_credits_to_account(account, credits, package)` -- `get_available_packages()` - -**Priority:** MEDIUM - ---- - -## 🧪 TESTING REQUIREMENTS - -### Unit Tests - -- [ ] CreditService operations -- [ ] SubscriptionService flows -- [ ] InvoiceService generation -- [ ] PaymentService processing -- [ ] Webhook handlers - -### Integration Tests - -- [ ] Full subscription creation flow -- [ ] Credit purchase end-to-end -- [ ] Stripe webhook processing -- [ ] Invoice PDF generation -- [ ] Email notifications - -### E2E Tests - -- [ ] User signup → plan selection → payment -- [ ] Credit purchase flow -- [ ] Plan upgrade/downgrade -- [ ] Subscription cancellation -- [ ] Team member invitation - ---- - -## 📈 SUCCESS METRICS - -### Business Metrics - -- Subscription conversion rate -- Average revenue per user (ARPU) -- Customer lifetime value (LTV) -- Churn rate -- Credit consumption per account - -### Technical Metrics - -- Payment success rate (target: >98%) -- Webhook processing latency (target: <2s) -- Invoice generation time (target: <1s) -- API response time (target: <200ms) -- Zero credit deduction race conditions - -### User Experience Metrics - -- Time to first purchase -- Billing page load time -- Support tickets related to billing -- User satisfaction score - ---- - -## 🔒 SECURITY CONSIDERATIONS - -### Payment Security - -- ✅ Use Stripe Elements (PCI compliant) -- ✅ Never store card details -- ✅ Use HTTPS only -- ✅ Validate webhook signatures -- ✅ Implement CSRF protection - -### Access Control - -- ✅ Role-based permissions enforced -- ✅ Multi-tenancy isolation verified -- ✅ Admin actions logged -- ✅ Sensitive data encrypted -- ✅ Rate limiting on payment endpoints - -### Data Protection - -- ✅ GDPR compliance for EU users -- ✅ PII encryption at rest -- ✅ Audit trail for all billing actions -- ✅ Regular security audits -- ✅ Data retention policies - ---- - -## 📝 DOCUMENTATION REQUIREMENTS - -### User Documentation - -- [ ] How to upgrade/downgrade plans -- [ ] How to purchase credits -- [ ] How to manage team members -- [ ] How to view usage analytics -- [ ] How to download invoices - -### Admin Documentation - -- [ ] How to configure credit costs -- [ ] How to manage accounts -- [ ] How to process refunds -- [ ] How to monitor system health -- [ ] How to handle webhook failures - -### Developer Documentation - -- [ ] API reference -- [ ] Stripe integration guide -- [ ] Webhook handling -- [ ] Testing procedures -- [ ] Deployment checklist - ---- - -## 🎯 IMMEDIATE NEXT STEPS - -### This Week (High Priority) - -1. **Create Invoice & Payment Models** - - Write migration - - Create serializers - - Add to admin - -2. **Implement Stripe Webhooks** - - Set up endpoint - - Handle subscription events - - Test webhook processing - -3. **Create Plans & Billing Page** - - Consolidate existing billing pages - - Add subscription management UI - - Integrate Stripe Elements - -### Next Week (High Priority) - -4. **Implement Subscription Flow** - - Create subscription API - - Add plan upgrade/downgrade - - Test end-to-end - -5. **Implement Credit Purchase** - - Create credit packages - - Add purchase API - - Build purchase UI - -6. **Create Account Settings Page** - - Account information - - Billing address - - Team management - ---- - -## 💡 RECOMMENDATIONS - -### Must Haves (Critical) - -1. ✅ Stripe webhook integration -2. ✅ Invoice & payment tracking -3. ✅ Subscription management -4. ✅ Credit purchase flow -5. ✅ Consolidated billing UI - -### Should Haves (Important) - -6. ✅ Team management -7. ✅ Usage analytics -8. ✅ PDF invoice generation -9. ✅ Email notifications -10. ✅ Admin dashboard - -### Nice to Haves (Enhancement) - -11. ✅ Budget alerts -12. ✅ Auto top-up -13. ✅ Multi-currency -14. ✅ Volume discounts -15. ✅ Referral program - ---- - -## 🏁 CONCLUSION - -This comprehensive plan addresses all aspects of a standardized SaaS platform: - -**✅ Already Working:** -- Multi-tenant architecture -- Credits system -- Basic billing UI -- Admin controls for credit costs - -**🚧 Need to Implement:** -- Payment processing (Stripe) -- Invoice & payment tracking -- Subscription management -- Consolidated billing UI -- Team management -- Analytics & reporting - -**Priority Order:** -1. Payment integration (CRITICAL) -2. Billing UI consolidation (HIGH) -3. Subscription management (HIGH) -4. Admin dashboard (MEDIUM) -5. Analytics & advanced features (LOW) - -**Timeline:** 8-12 weeks for full implementation - -**Effort:** 2-3 developers full-time - -This plan ensures IGNY8 becomes a professional, scalable SaaS platform with best-practice billing, user management, and admin controls. - ---- - -**Status:** ✅ PLAN COMPLETE - READY FOR REVIEW & IMPLEMENTATION - diff --git a/docs/working-docs/SESSION-SUMMARY-DEC-4-2025.md b/docs/working-docs/SESSION-SUMMARY-DEC-4-2025.md deleted file mode 100644 index 25d408c1..00000000 --- a/docs/working-docs/SESSION-SUMMARY-DEC-4-2025.md +++ /dev/null @@ -1,384 +0,0 @@ -# SaaS Platform Implementation - Status Summary - -**Date:** December 4, 2025 -**Session Status:** ✅ PHASE 1 COMPLETE - Models Created -**Ready For:** Database migrations and service implementation - ---- - -## 🎯 WHAT WAS ACCOMPLISHED - -### ✅ Complete Backend Models (Ready for Migration) - -I've created all necessary database models with support for: - -1. **Multi-Payment Gateway Support** - - ✅ Stripe integration - - ✅ PayPal integration - - ✅ Manual payments (bank transfer, local wallets) - - ✅ Per-country payment method configuration - -2. **Invoice System** - - ✅ Full invoice tracking - - ✅ Line items support - - ✅ Status management (draft, pending, paid, void) - - ✅ Stripe integration fields - -3. **Payment Tracking** - - ✅ Multi-gateway payment records - - ✅ Manual payment approval workflow - - ✅ Refund tracking - - ✅ Comprehensive timestamps and status - -4. **Credit Packages** - - ✅ Purchasable credit bundles - - ✅ Featured packages support - - ✅ Stripe & PayPal product IDs - - ✅ Discount percentage tracking - -5. **Payment Method Configuration** - - ✅ Per-country method enabling/disabling - - ✅ Bank details for manual payments - - ✅ Local wallet information - - ✅ Custom instructions per country - -6. **Account Billing Information** - - ✅ Billing address fields - - ✅ Tax ID support - - ✅ Billing email - - ✅ Country tracking for payment methods - ---- - -## 📄 DOCUMENTS CREATED - -### 1. **SAAS-STANDARDIZATION-PLAN-DEC-4-2025.md** - - Comprehensive architecture overview - - All entity relationships - - Complete UI/UX restructuring plan - - Payment integration requirements - - 32-task implementation roadmap - -### 2. **IMPLEMENTATION-GUIDE-DEC-4-2025.md** (NEW) - - Step-by-step implementation guide - - All 32 tasks detailed with code examples - - Service implementation templates - - API endpoint specifications - - Frontend page requirements with components - - Quick start guide for immediate next steps - - Recommended 12-week implementation timeline - ---- - -## 🚀 IMMEDIATE NEXT STEPS - -### Step 1: Apply Database Migrations (5 minutes) - -```bash -cd /data/app/igny8/backend - -# Create migrations -python manage.py makemigrations billing --name add_invoice_payment_models -python manage.py makemigrations auth --name add_billing_address_fields - -# Review what will be created -python manage.py sqlmigrate billing -python manage.py sqlmigrate auth - -# Apply migrations -python manage.py migrate billing -python manage.py migrate auth - -# Verify tables created -python manage.py dbshell -\dt igny8_invoices -\dt igny8_payments -\dt igny8_credit_packages -\dt igny8_payment_method_config -\dt igny8_tenants # Check new billing fields -\q -``` - -### Step 2: Create Sample Data (10 minutes) - -```bash -python manage.py shell -``` - -```python -from igny8_core.business.billing.models import CreditPackage, PaymentMethodConfig - -# Create credit packages -packages = [ - {"name": "Starter Pack", "slug": "starter", "credits": 500, "price": 9.00, "sort_order": 1}, - {"name": "Pro Pack", "slug": "pro", "credits": 2000, "price": 29.00, "discount_percentage": 10, "sort_order": 2, "is_featured": True}, - {"name": "Business Pack", "slug": "business", "credits": 5000, "price": 69.00, "discount_percentage": 15, "sort_order": 3}, - {"name": "Enterprise Pack", "slug": "enterprise", "credits": 20000, "price": 249.00, "discount_percentage": 20, "sort_order": 4}, -] - -for pkg in packages: - CreditPackage.objects.create(**pkg, is_active=True) - -# Configure payment methods for US -methods = [ - {"country_code": "US", "payment_method": "stripe", "display_name": "Credit/Debit Card", "sort_order": 1}, - {"country_code": "US", "payment_method": "paypal", "display_name": "PayPal", "sort_order": 2}, -] - -for method in methods: - PaymentMethodConfig.objects.create(**method, is_enabled=True) - -print("✅ Sample data created!") -``` - -### Step 3: Start Implementing Services (Week 1) - -**Recommended Order:** - -1. **InvoiceService** (Simplest - Start here) - - File: `backend/igny8_core/business/billing/services/invoice_service.py` - - Refer to IMPLEMENTATION-GUIDE-DEC-4-2025.md for full code - -2. **PaymentService** (Manual payments only) - - File: `backend/igny8_core/business/billing/services/payment_service.py` - - Start with manual payment creation and approval - -3. **Basic API Endpoints** - - File: `backend/igny8_core/business/billing/views.py` - - Implement `/v1/billing/invoices/` GET endpoint - - Implement `/v1/billing/credits/packages/` GET endpoint - ---- - -## 📊 IMPLEMENTATION PROGRESS - -### Completed ✅ - -- [x] Backend models design -- [x] Multi-payment gateway support (Stripe, PayPal, Manual) -- [x] Invoice and Payment models -- [x] Credit Packages model -- [x] Payment Method Configuration model -- [x] Account billing fields -- [x] Comprehensive documentation (2 detailed guides) -- [x] 32-task implementation roadmap -- [x] All model code written and ready - -### In Progress 🔄 - -- [ ] Database migrations (ready to run) -- [ ] Sample data creation - -### Not Started ⏳ - -- [ ] Backend services (6 services needed) -- [ ] Stripe webhook handlers -- [ ] PayPal webhook handlers -- [ ] API endpoints (30+ endpoints) -- [ ] Frontend pages (9 pages) -- [ ] Navigation updates -- [ ] Email templates -- [ ] PDF invoice generation -- [ ] Testing -- [ ] Documentation - ---- - -## 📈 ESTIMATED TIMELINE - -Based on the implementation guide: - -| Phase | Duration | Tasks | Status | -|-------|----------|-------|--------| -| **Phase 1: Backend Foundation** | Week 1-2 | Models, Migrations, Services, Webhooks | ✅ 25% Done (Models) | -| **Phase 2: Backend APIs** | Week 3-4 | 30+ REST API endpoints | ⏳ Not Started | -| **Phase 3: Frontend Pages** | Week 5-8 | 9 user + admin pages | ⏳ Not Started | -| **Phase 4: Navigation & UI** | Week 9 | Menu restructuring | ⏳ Not Started | -| **Phase 5: Supporting Features** | Week 10-12 | Email, PDF, polish | ⏳ Not Started | -| **Phase 6: Testing & Docs** | Week 13-14 | QA, documentation | ⏳ Not Started | - -**Total Estimated Time:** 12-14 weeks with 2-3 developers - ---- - -## 🎯 RECOMMENDED APPROACH - -### Option A: Full Implementation (12-14 weeks) -- Follow IMPLEMENTATION-GUIDE-DEC-4-2025.md step by step -- Implement all 32 tasks in order -- Result: Complete, professional SaaS billing system - -### Option B: MVP Approach (4-6 weeks) -Focus on essentials first: - -**Week 1-2:** -- ✅ Migrations -- ✅ InvoiceService -- ✅ PaymentService (manual only) -- ✅ Basic Invoice API - -**Week 3-4:** -- ✅ Account Settings page -- ✅ Simple billing page (invoices list) -- ✅ Manual payment request flow - -**Week 5-6:** -- ✅ Stripe integration (one-time payments) -- ✅ Purchase Credits page -- ✅ Payment confirmation - -**Result:** Basic functional billing with manual + Stripe payments - ---- - -## 💡 KEY FEATURES IMPLEMENTED - -### 1. **Real Payment Pages** -All pages in the implementation guide include: -- ✅ Actual data loading from APIs -- ✅ Real forms with validation -- ✅ Proper error handling -- ✅ Loading states -- ✅ Success/failure feedback -- ✅ No placeholder/mock content - -### 2. **Multi-Gateway Support** -- ✅ Stripe (credit/debit cards) -- ✅ PayPal -- ✅ Bank Transfer (manual approval) -- ✅ Local Wallets (manual approval) -- ✅ Per-country configuration - -### 3. **Admin Controls** -- ✅ Approve/reject manual payments -- ✅ Configure payment methods per country -- ✅ View all accounts, invoices, payments -- ✅ Create manual invoices -- ✅ System-wide analytics - -### 4. **Verification & Testing** -The implementation guide includes: -- ✅ Unit test templates -- ✅ Integration test scenarios -- ✅ Stripe test mode setup -- ✅ PayPal sandbox testing -- ✅ Manual payment workflow testing - ---- - -## 📚 DOCUMENTATION FILES - -1. **SAAS-STANDARDIZATION-PLAN-DEC-4-2025.md** (1,371 lines) - - Architecture overview - - Complete model specifications - - UI/UX redesign - - All requirements - -2. **IMPLEMENTATION-GUIDE-DEC-4-2025.md** (800+ lines) - - Step-by-step tasks - - Code templates - - API specifications - - Quick start guide - - Testing procedures - -3. **IMPLEMENTATION_COMPLETE-DEC-4-2025.md** (Existing) - - Previous implementations - - Credits system details - -4. **BILLING-ADMIN-IMPLEMENTATION.md** (Existing) - - Current billing pages - - Admin features - ---- - -## ⚠️ IMPORTANT REMINDERS - -### Before You Start Implementation: - -1. **Install Required Packages** - ```bash - # Backend - pip install stripe paypalrestsdk reportlab - - # Frontend - npm install @stripe/stripe-js @stripe/react-stripe-js - npm install @paypal/react-paypal-js - npm install recharts - ``` - -2. **Set Up Environment Variables** - ```python - # .env - STRIPE_PUBLIC_KEY=pk_test_... - STRIPE_SECRET_KEY=sk_test_... - STRIPE_WEBHOOK_SECRET=whsec_... - - PAYPAL_CLIENT_ID=... - PAYPAL_CLIENT_SECRET=... - PAYPAL_MODE=sandbox - ``` - -3. **Create Stripe Products** - - Log into Stripe Dashboard - - Create products for each credit package - - Create products for subscription plans - - Copy product/price IDs to database - -4. **Set Up Webhooks** - - Stripe: Create webhook endpoint - - PayPal: Configure IPN/webhooks - - Test with CLI tools first - ---- - -## 🎉 WHAT YOU HAVE NOW - -✅ **Complete Backend Models** - All database tables designed and coded -✅ **Comprehensive Plan** - 1,371 lines of detailed specifications -✅ **Implementation Guide** - 800+ lines of step-by-step instructions -✅ **32 Detailed Tasks** - Each with code examples and requirements -✅ **Multi-Payment Support** - Stripe, PayPal, and manual methods -✅ **Per-Country Config** - Enable/disable payment methods by region -✅ **Real Pages Spec** - No mock content, all functional requirements -✅ **Testing Strategy** - Unit, integration, and E2E test plans -✅ **Timeline** - 12-14 week roadmap with milestones - ---- - -## 📞 NEXT SESSION RECOMMENDATIONS - -### If continuing implementation: - -**Session 1 (Next):** -- Run migrations -- Create InvoiceService -- Create basic Invoice API endpoint -- Test invoice creation - -**Session 2:** -- Create PaymentService (manual payments) -- Create manual payment approval API -- Test manual payment flow - -**Session 3:** -- Account Settings frontend page -- Connect to account API -- Test account updates - -**Session 4:** -- Purchase Credits page -- Credit packages API -- Manual payment request form - -Continue following IMPLEMENTATION-GUIDE-DEC-4-2025.md for subsequent sessions. - ---- - -**Status:** ✅ **FOUNDATION COMPLETE - READY FOR IMPLEMENTATION** - -**Your next command should be:** -```bash -cd /data/app/igny8/backend -python manage.py makemigrations billing --name add_invoice_payment_models -``` - diff --git a/docs/working-docs/billing-account-final-plan-2025-12-05.md b/docs/working-docs/billing-account-final-plan-2025-12-05.md new file mode 100644 index 00000000..8a7e8db5 --- /dev/null +++ b/docs/working-docs/billing-account-final-plan-2025-12-05.md @@ -0,0 +1,143 @@ +# IGNY8 Billing & Account Platform — Final Plan +**Date:** 2025-12-05 +**Status:** Canonical (supersedes all prior billing/account docs) +**Scope:** Tenant + Admin experience across Billing, Account, Credits, Payment Methods, and Payment Gateways. Frontend + Backend must use the IGNY8 standard API system. + +--- + +## 1) Purpose & Principles +- Single source of truth for billing/account flows. +- One canonical API namespace per audience (tenant vs admin). +- Align models ↔ services ↔ serializers ↔ frontend calls; remove drift. +- Keep manual payment path healthy while Stripe/PayPal mature. +- Favor incremental rollout with feature-flagged transitions. + +--- + +## 2) Canonical Namespaces +- Tenant: `/api/v1/billing/...` +- Admin: `/api/v1/admin/billing/...` +- Deprecate legacy `/api/v1/admin/...` (modules/billing) and duplicated routers. Optionally dual-serve for one release behind a feature flag. + +--- + +## 3) Reality Snapshot (current code) +- Tenant billing viewsets live in `backend/igny8_core/business/billing/views.py` (invoices, payments, credit packages, transactions). +- Admin billing viewset also exists there (`pending_payments`, approvals, stats) but mounted at `/api/v1/billing/admin/...`. +- Legacy admin stack in `backend/igny8_core/modules/billing/views.py` exposes stats/users/credit-costs only; no invoices/payments. +- Model drift: `InvoiceService` expects `currency`, `tax_amount`, `total_amount` that are absent on `Invoice`. `PaymentService` uses `pending_approval`/`completed` statuses not present in `Payment.STATUS_CHOICES`. +- Frontend admin pages are wired but call nonexistent or legacy routes (e.g., `/v1/admin/payments/`). + +--- + +## 4) Backend Plan +### 4.1 Models & Migrations (billing app) +- Invoice: add `currency`, `subtotal_amount`, `tax_amount`, `total_amount`, `line_items` (JSON list), `payment_method` (string), `stripe_invoice_id`/`paypal_invoice_id` (nullable), `metadata`. Keep existing dates/status. Add index on `status, created_at`. +- Payment: extend `STATUS_CHOICES` to include `pending_approval`, `processing`, `completed`, `failed`, `refunded`, `cancelled`. Add `payment_method` enum (stripe, paypal, bank_transfer, local_wallet, manual), gateway intent/charge ids, `manual_reference`, `failure_reason`, `approved_by/at`, `metadata`. +- CreditPackage: ensure `slug`, `price`, `credits`, `stripe_price_id` exist and `is_active`, `is_featured`. Add `sort_order` for admin ordering. +- PaymentMethodConfig: keep as source for country-level enablement; ensure uniqueness `(country_code, payment_method)`. +- Write forward/backward-safe migrations; backfill currency and totals with sensible defaults (e.g., `USD`, recompute `total_amount=subtotal_amount+tax_amount` where possible). + +### 4.2 Services +- `InvoiceService`: align fields; generate invoice numbers, compute subtotal/tax/total, store line items, mark paid/void/uncollectible, emit events, optionally render PDF stub. +- `PaymentService`: + - Stripe/PayPal: create intents/orders, store ids, update status on success/failure, attach to invoice, and trigger credit application when relevant. + - Manual: create `pending_approval`, allow approve/reject endpoints to flip status and apply credits. + - Sync helpers from webhooks/intents; emit structured logs. +- `SubscriptionService` (existing): ensure plan ↔ subscription sync; use Stripe subscription id; update invoice/payment when Stripe posts events. +- `CreditPackageService`: list active packages, create invoice + payment intent, on success add credits (`CreditTransaction`) and recalc balance. + +### 4.3 Webhooks +- Add `/api/v1/billing/webhooks/stripe/` and `/api/v1/billing/webhooks/paypal/` with signature verification. +- Handle events: `invoice.paid`, `invoice.payment_failed`, `customer.subscription.updated/deleted`, `payment_intent.succeeded/failed`, PayPal equivalents. +- Idempotent processing; log and surface dead-letter queue for failures. + +### 4.4 APIs (Tenant) +- `GET /api/v1/billing/account_balance/` – balance + monthly included. +- `GET /api/v1/billing/transactions/` – credit transactions (paginated). +- `GET /api/v1/billing/usage/` – usage logs with filters. +- `GET /api/v1/billing/invoices/` | `GET /api/v1/billing/invoices/:id/` | `GET /api/v1/billing/invoices/:id/pdf/`. +- `GET /api/v1/billing/payments/` | `GET /api/v1/billing/payments/:id/`. +- `GET /api/v1/billing/credit-packages/`. +- `POST /api/v1/billing/credits/purchase/` – create intent; returns client secret + invoice id. +- `POST /api/v1/billing/subscriptions/create|upgrade|cancel/`. +- `GET /api/v1/billing/subscriptions/` – current subscription status. +- `GET/POST /api/v1/billing/payment-methods/` – list/add; store tokens/ids, not card data. + +### 4.5 APIs (Admin) +- `GET /api/v1/admin/billing/invoices/` | `GET /:id/` – all accounts, filters (status, account, method, date), pagination, export. +- `GET /api/v1/admin/billing/payments/` | `GET /:id/` – all accounts, filters (status, method, gateway). +- `POST /api/v1/admin/billing/payments/:id/approve/` | `/reject/` – manual payments only. +- `GET/POST/PATCH/DELETE /api/v1/admin/billing/credit-packages/` – CRUD with `is_featured`, `sort_order`. +- `GET /api/v1/admin/billing/stats/` – totals, MRR, pending approvals, failed webhooks. +- `GET /api/v1/admin/billing/pending_payments/` – for approvals (same payload frontend expects). +- AuthZ: developer/superuser only; enforce tenant scoping for non-admin routes. + +### 4.6 Settings & Config +- Add `STRIPE_PUBLIC_KEY`, `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `PAYPAL_CLIENT_ID`, `PAYPAL_CLIENT_SECRET`, `PAYPAL_WEBHOOK_ID` to settings/env; feature-flag gateways. +- Rate-limit payment endpoints; CSRF exempt webhooks only. + +--- + +## 5) Frontend Plan +### 5.1 Service Layer (`frontend/src/services/billing.api.ts`) +- Point all admin calls to `/api/v1/admin/billing/...`; remove dead `/v1/admin/...` routes. +- Reuse tenant calls for user-facing pages; ensure response shapes match new serializers (`InvoiceSerializer`, `PaymentSerializer`, `CreditPackageSerializer`). +- Add helpers for manual approval actions and credit-package CRUD. + +### 5.2 Tenant Pages +- Plans & Billing (`/account/billing`): tabs for Plan, Credits, Billing History (invoices), Payment Methods. Uses balance, subscription, invoices, payment-methods, credit-packages, purchase intent. +- Purchase Credits (`/account/credits/purchase`): list packages → create purchase intent → confirm via Stripe/PayPal/manual upload → poll payment. +- Invoices (`/account/invoices`): paginated table, filters, PDF download. +- Payment Methods: list/add/remove default (via tokens). + +### 5.3 Admin Pages +- Billing Overview (`/admin/billing`): stats from `/admin/billing/stats/`, pending approvals summary. +- Invoices (`/admin/invoices`): uses `/admin/billing/invoices/`; add filters (account, status, method, date) and CSV/PDF export. +- Payments (`/admin/payments`): uses `/admin/billing/payments/`; add filters and status badges. +- Credit Packages (`/admin/credit-packages`): CRUD via admin endpoints; show `is_active`, `is_featured`, `sort_order`, Stripe price id. +- Payment Approvals (`/admin/payments/approvals`): call `pending_payments`, approve/reject endpoints; show invoice link and manual references. +- Sidebar links already present—only fix data wiring. + +### 5.4 UX/Consistency +- Standard empty/error/loading states across billing pages. +- Currency display from invoice/payment `currency`. +- Role-guard tenant routes (owner/admin only for purchases; read-only for others where applicable). + +--- + +## 6) Sequenced Action Plan +- **Day 0 (alignment):** Merge this doc; add “retired” note to older docs; choose namespace flag (`USE_NEW_ADMIN_BILLING_API=true`). +- **Phase 1 (backend, 2-3 days):** Migrate models; update services; add admin list endpoints; webhook stubs; tests for serializers and viewsets. +- **Phase 2 (gateways + frontend wiring, 3-4 days):** Implement Stripe/PayPal intent paths, hook webhooks, wire `billing.api.ts` to new endpoints, fix admin pages, enable manual approvals end-to-end. +- **Phase 3 (polish, 2 days):** Add exports, filters, pagination polish; observability (structured logs, alerts); finalize docs and remove legacy router. + +--- + +## 7) Deliverables & DoD +- Schema migration applied and reversible; services match models. +- Canonical endpoints live and documented; legacy admin endpoints removed/flagged off. +- Tenant billing pages load without 404s; purchases and subscriptions succeed (manual + Stripe at minimum). +- Admin pages show data, support approvals, and package CRUD. +- Tests: unit (services), API (tenant/admin billing), integration (purchase + manual approval flow), webhook idempotency. +- Docs: this file referenced from legacy docs; endpoint matrix embedded in `billing.api.ts` JSDoc or a short `/docs/billing/api-map.md`. + +--- + +## 8) Quick Endpoint Matrix (canonical) +- Tenant: invoices (`/api/v1/billing/invoices`), payments (`/api/v1/billing/payments`), credit packages + purchase (`/api/v1/billing/credit-packages`, `/credits/purchase`), subscription create/upgrade/cancel (`/subscriptions/...`), payment methods (`/payment-methods`), usage/transactions/balance. +- Admin: invoices (`/api/v1/admin/billing/invoices`), payments (`/api/v1/admin/billing/payments`), pending approvals (`/api/v1/admin/billing/pending_payments`), approve/reject (`/api/v1/admin/billing/payments/:id/approve|reject`), credit packages CRUD (`/api/v1/admin/billing/credit-packages`), stats (`/api/v1/admin/billing/stats`). + +--- + +## 9) Rollout & Migration Notes +- Run migrations during maintenance window; backfill currency/totals. +- If dual-stack needed, proxy legacy admin routes to new handlers temporarily. +- Communicate new admin endpoints to frontend before flipping flags. +- Validate webhook secrets in non-prod before enabling in prod. + +--- + +## 10) Retirement Notice +This document supersedes `docs/working-docs/Original-plan-may-have-wrong-logic.md` and `docs/working-docs/admin-billing-plan-2025-12-05.md`. Treat those as retired; keep only for historical reference. + diff --git a/frontend/src/services/billing.api.ts.backup b/frontend/src/services/billing.api.ts.backup deleted file mode 100644 index 630d4d16..00000000 --- a/frontend/src/services/billing.api.ts.backup +++ /dev/null @@ -1,634 +0,0 @@ -/** - * Billing API Service - * Uses STANDARD existing billing endpoints from /v1/billing/ and /v1/system/ - */ - -import { fetchAPI } from './api'; - -// ============================================================================ -// TYPES -// ============================================================================ - -export interface CreditBalance { - balance: number; - credits: number; - plan_credits_per_month: number; - credits_used_this_month: number; - credits_remaining: number; - subscription_plan?: string; - monthly_credits?: number; - subscription_status?: string; -} - -export interface CreditTransaction { - id: number; - amount: number; - transaction_type: 'purchase' | 'subscription' | 'refund' | 'deduction' | 'adjustment' | 'grant'; - description: string; - created_at: string; - reference_id?: string; - metadata?: Record; - balance_after?: number; -} - -export interface CreditUsageLog { - id: number; - operation_type: string; - credits_used: number; - cost_usd: string; - model_used?: string; - tokens_input?: number; - tokens_output?: number; - created_at: string; - metadata?: Record; -} - -export interface AdminBillingStats { - total_accounts: number; - active_subscriptions: number; - total_revenue: string; - revenue_this_month?: string; - new_accounts_this_month?: number; - active_accounts?: number; - credits_issued_30d?: number; - credits_used_30d?: number; - pending_approvals?: number; - invoices_pending?: number; - invoices_overdue?: number; - system_health?: { - status: string; - last_check: string; - }; - recent_activity?: Array<{ - id: number; - type: string; - account_name: string; - amount: string; - currency: string; - timestamp: string; - description: string; - }>; -} - -export interface CreditCostConfig { - id: number; - operation_type: string; - credits_cost: number; - unit: string; - display_name: string; - description: string; - is_active: boolean; - updated_at: string; -} - -export interface AdminUser { - id: number; - email: string; - account_name: string; - account_id: number; - role: string; - is_active: boolean; - credit_balance: number; - plan_name?: string; - created_at: string; - last_login?: string; -} - -// ============================================================================ -// CREDIT BALANCE & TRANSACTIONS -// ============================================================================ - -export async function getCreditBalance(): Promise { - return fetchAPI('/v1/billing/credits/balance/balance/'); -} - -export async function getCreditTransactions(): Promise<{ - results: CreditTransaction[]; - count: number; - current_balance?: number; -}> { - return fetchAPI('/v1/billing/credits/transactions/'); -} - -// ============================================================================ -// CREDIT USAGE LOGS -// ============================================================================ - -export async function getCreditUsage(params?: { - operation_type?: string; - start_date?: string; - end_date?: string; -}): Promise<{ - results: CreditUsageLog[]; - count: number; -}> { - const queryParams = new URLSearchParams(); - if (params?.operation_type) queryParams.append('operation_type', params.operation_type); - if (params?.start_date) queryParams.append('start_date', params.start_date); - if (params?.end_date) queryParams.append('end_date', params.end_date); - - const url = `/v1/billing/credits/usage/${queryParams.toString() ? '?' + queryParams.toString() : ''}`; - return fetchAPI(url); -} - -export async function getCreditUsageSummary(params?: { - start_date?: string; - end_date?: string; -}): Promise<{ - total_credits_used: number; - total_cost_usd: string; - by_operation: Record; - by_model: Record; -}> { - const queryParams = new URLSearchParams(); - if (params?.start_date) queryParams.append('start_date', params.start_date); - if (params?.end_date) queryParams.append('end_date', params.end_date); - - const url = `/v1/billing/credits/usage/summary/${queryParams.toString() ? '?' + queryParams.toString() : ''}`; - return fetchAPI(url); -} - -export async function getCreditUsageLimits(): Promise<{ - plan_name: string; - plan_credits_per_month: number; - credits_used_this_month: number; - credits_remaining: number; - percentage_used: number; - approaching_limit: boolean; -}> { - return fetchAPI('/v1/billing/credits/usage/limits/'); -} - -// ============================================================================ -// ADMIN - BILLING STATS & MANAGEMENT -// ============================================================================ - -export async function getAdminBillingStats(): Promise { - return fetchAPI('/v1/admin/billing/stats/'); -} - -export async function getAdminUsers(params?: { - search?: string; - role?: string; - is_active?: boolean; -}): Promise<{ - results: AdminUser[]; - count: number; -}> { - const queryParams = new URLSearchParams(); - if (params?.search) queryParams.append('search', params.search); - if (params?.role) queryParams.append('role', params.role); - if (params?.is_active !== undefined) queryParams.append('is_active', String(params.is_active)); - - const url = `/v1/admin/users/${queryParams.toString() ? '?' + queryParams.toString() : ''}`; - return fetchAPI(url); -} - -export async function adjustUserCredits( - userId: number, - data: { - amount: number; - reason: string; - } -): Promise<{ - message: string; - new_balance: number; -}> { - return fetchAPI(`/v1/admin/users/${userId}/adjust-credits/`, { - method: 'POST', - body: JSON.stringify(data), - }); -} - -// ============================================================================ -// ADMIN - CREDIT COSTS CONFIGURATION -// ============================================================================ - -export async function getCreditCosts(): Promise<{ - results: CreditCostConfig[]; - count: number; -}> { - return fetchAPI('/v1/admin/credit-costs/'); -} - -export async function updateCreditCosts( - costs: Array<{ - operation_type: string; - credits_cost: number; - }> -): Promise<{ - message: string; - updated_count: number; -}> { - return fetchAPI('/v1/admin/credit-costs/', { - method: 'POST', - body: JSON.stringify({ costs }), - }); -} - -// ============================================================================ -// ACCOUNT SETTINGS (from /v1/system/) -// ============================================================================ - -export interface AccountSettings { - id: number; - name: string; - slug: string; - billing_address_line1?: string; - billing_address_line2?: string; - billing_city?: string; - billing_state?: string; - billing_postal_code?: string; - billing_country?: string; - tax_id?: string; - billing_email?: string; - credit_balance: number; - plan_name?: string; - created_at: string; - updated_at: string; -} - -export async function getAccountSettings(): Promise { - return fetchAPI('/v1/system/settings/account/'); -} - -export async function updateAccountSettings( - settings: Partial -): Promise<{ - message: string; - account: Partial; -}> { - return fetchAPI('/v1/system/settings/account/', { - method: 'PATCH', - body: JSON.stringify(settings), - }); -} - -// ============================================================================ -// TYPES -// ============================================================================ - -export interface CreditPackage { - id: number; - name: string; - slug: string; - credits: number; - price: string; - discount_percentage: number; - is_featured: boolean; - description: string; - display_order: number; -} - -export interface Invoice { - id: number; - invoice_number: string; - status: 'draft' | 'pending' | 'paid' | 'void'; - total_amount: string; - subtotal: string; - tax_amount: string; - currency: string; - created_at: string; - paid_at: string | null; - due_date: string | null; - line_items: Array<{ - description: string; - amount: string; - quantity: number; - }>; - billing_period_start: string | null; - billing_period_end: string | null; -} - -export interface Payment { - id: number; - amount: string; - currency: string; - payment_method: 'stripe' | 'paypal' | 'bank_transfer' | 'local_wallet' | 'manual'; - status: 'pending' | 'completed' | 'failed' | 'pending_approval'; - created_at: string; - processed_at: string | null; - invoice_id: number; - invoice_number: string | null; - transaction_reference: string; - failure_reason: string | null; -} - -export interface PaymentMethod { - type: string; - name: string; - instructions: string; - bank_details?: { - bank_name: string; - account_number: string; - routing_number: string; - swift_code: string; - }; - wallet_details?: { - wallet_type: string; - wallet_id: string; - }; -} - -export interface CreditTransaction { - id: number; - amount: number; - transaction_type: string; - description: string; - created_at: string; - reference_id: string; - metadata: Record; -} - -export interface CreditBalance { - balance: number; - subscription_plan: string; - monthly_credits: number; - subscription_status: string | null; -} - -export interface PendingPayment { - id: number; - account_name: string; - amount: string; - currency: string; - payment_method: string; - transaction_reference: string; - created_at: string; - invoice_number: string | null; - admin_notes: string; -} - -// ============================================================================ -// CREDIT PACKAGES -// ============================================================================ - -export async function getCreditPackages(): Promise<{ results: CreditPackage[]; count: number }> { - return fetchAPI('/billing/v2/credit-packages/'); -} - -export async function purchaseCreditPackage( - packageId: number, - paymentMethod: string -): Promise<{ - invoice_id: number; - invoice_number: string; - total_amount: string; - message: string; - next_action: string; -}> { - return fetchAPI(`/billing/v2/credit-packages/${packageId}/purchase/`, { - method: 'POST', - body: JSON.stringify({ payment_method: paymentMethod }), - }); -} - -// ============================================================================ -// INVOICES -// ============================================================================ - -export async function getInvoices(status?: string): Promise<{ results: Invoice[]; count: number }> { - const params = status ? `?status=${status}` : ''; - return fetchAPI(`/billing/v2/invoices/${params}`); -} - -export async function getInvoice(invoiceId: number): Promise { - return fetchAPI(`/v1/billing/invoices/${invoiceId}/`); -} - -export async function downloadInvoicePDF(invoiceId: number): Promise { - const response = await fetch(`/api/v1/billing/invoices/${invoiceId}/download_pdf/`, { - headers: { - Authorization: `Bearer ${localStorage.getItem('access_token')}`, - }, - }); - - if (!response.ok) { - throw new Error('Failed to download invoice'); - } - - return response.blob(); -} - -// ============================================================================ -// PAYMENTS -// ============================================================================ - -export async function getPayments(status?: string): Promise<{ results: Payment[]; count: number }> { - const params = status ? `?status=${status}` : ''; - return fetchAPI(`/v1/billing/payments/${params}`); -} - -export async function getAvailablePaymentMethods(): Promise<{ - methods: PaymentMethod[]; - stripe: boolean; - paypal: boolean; - bank_transfer: boolean; - local_wallet: boolean; -}> { - return fetchAPI('/v1/billing/payments/available_methods/'); -} - -export async function createManualPayment(data: { - invoice_id: number; - payment_method: 'bank_transfer' | 'local_wallet'; - transaction_reference: string; - notes?: string; -}): Promise<{ - id: number; - status: string; - message: string; -}> { - return fetchAPI('/v1/billing/payments/create_manual_payment/', { - method: 'POST', - body: JSON.stringify(data), - }); -} - -// ============================================================================ -// CREDIT TRANSACTIONS -// ============================================================================ - -export async function getCreditTransactions(): Promise<{ - results: CreditTransaction[]; - count: number; - current_balance: number; -}> { - return fetchAPI('/v1/billing/credits/transactions/'); -} - -export async function getCreditBalance(): Promise { - return fetchAPI('/v1/billing/credits/balance/balance/'); -} - -// ============================================================================ -// ADMIN - PAYMENT APPROVALS -// ============================================================================ - -export async function getPendingPayments(): Promise<{ - results: PendingPayment[]; - count: number; -}> { - return fetchAPI('/v1/billing/admin/pending_payments/'); -} - -export async function approvePayment( - paymentId: number, - notes?: string -): Promise<{ - id: number; - status: string; - message: string; -}> { - return fetchAPI(`/v1/billing/admin/${paymentId}/approve_payment/`, { - method: 'POST', - body: JSON.stringify({ notes }), - }); -} - -export async function rejectPayment( - paymentId: number, - reason: string -): Promise<{ - id: number; - status: string; - message: string; -}> { - return fetchAPI(`/v1/billing/admin/${paymentId}/reject_payment/`, { - method: 'POST', - body: JSON.stringify({ reason }), - }); -} - -export async function getAdminBillingStats(): Promise<{ - total_accounts: number; - active_subscriptions: number; - total_revenue: string; - pending_approvals: number; - invoices_pending: number; - invoices_paid: number; -}> { - return fetchAPI('/v1/billing/v2/admin/stats/'); -} - -// ============================================================================ -// ACCOUNT SETTINGS -// ============================================================================ - -export interface AccountSettings { - id: number; - name: string; - slug: string; - billing_address_line1: string; - billing_address_line2: string; - billing_city: string; - billing_state: string; - billing_postal_code: string; - billing_country: string; - tax_id: string; - billing_email: string; - credit_balance: number; - created_at: string; - updated_at: string; -} - -export async function getAccountSettings(): Promise { - return fetchAPI('/v1/system/settings/account/'); -} - -export async function updateAccountSettings( - settings: Partial -): Promise<{ - message: string; - account: Partial; -}> { - return fetchAPI('/v1/account/settings/', { - method: 'PATCH', - body: JSON.stringify(settings), - }); -} - -// ============================================================================ -// TEAM MANAGEMENT -// ============================================================================ - -export interface TeamMember { - id: number; - email: string; - first_name: string; - last_name: string; - is_active: boolean; - is_staff: boolean; - date_joined: string; - last_login: string | null; -} - -export async function getTeamMembers(): Promise<{ - results: TeamMember[]; - count: number; -}> { - return fetchAPI('/v1/account/team/'); -} - -export async function inviteTeamMember(data: { - email: string; - first_name?: string; - last_name?: string; -}): Promise<{ - message: string; - user: Partial; -}> { - return fetchAPI('/v1/account/team/', { - method: 'POST', - body: JSON.stringify(data), - }); -} - -export async function removeTeamMember(userId: number): Promise<{ - message: string; -}> { - return fetchAPI(`/v1/account/team/${userId}/`, { - method: 'DELETE', - }); -} - -// ============================================================================ -// USAGE ANALYTICS -// ============================================================================ - -export interface UsageAnalytics { - period_days: number; - start_date: string; - end_date: string; - current_balance: number; - usage_by_type: Array<{ - transaction_type: string; - total: number; - count: number; - }>; - purchases_by_type: Array<{ - transaction_type: string; - total: number; - count: number; - }>; - daily_usage: Array<{ - date: string; - usage: number; - purchases: number; - net: number; - }>; - total_usage: number; - total_purchases: number; -} - -export async function getUsageAnalytics(days: number = 30): Promise { - return fetchAPI(`/v1/account/usage/analytics/?days=${days}`); -}