final docs

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-05 07:09:29 +00:00
parent d92a99ecc3
commit f91037b729
9 changed files with 173 additions and 2778 deletions

View File

@@ -5,16 +5,16 @@
## ✅ WORKING ENDPOINTS ## ✅ WORKING ENDPOINTS
### Billing V2 Endpoints (New) ### Billing API Endpoints
| Endpoint | Method | Status | Notes | | Endpoint | Method | Status | Notes |
|----------|--------|--------|-------| |----------|--------|--------|-------|
| `/api/v1/billing/v2/invoices/` | GET | ✅ 401 | Auth required (correct) | | `/api/v1/billing/invoices/` | GET | ✅ 401 | Auth required (correct) |
| `/api/v1/billing/v2/payments/` | GET | ✅ 401 | Auth required (correct) | | `/api/v1/billing/payments/` | GET | ✅ 401 | Auth required (correct) |
| `/api/v1/billing/v2/credit-packages/` | GET | ✅ 401 | Auth required (correct) | | `/api/v1/billing/credit-packages/` | GET | ✅ 401 | Auth required (correct) |
| `/api/v1/billing/v2/transactions/` | GET | ✅ 401 | Auth required (correct) | | `/api/v1/billing/transactions/` | GET | ✅ 401 | Auth required (correct) |
| `/api/v1/billing/v2/transactions/balance/` | GET | ✅ 401 | Auth required (correct) | | `/api/v1/billing/transactions/balance/` | GET | ✅ 401 | Auth required (correct) |
| `/api/v1/billing/v2/admin/stats/` | GET | ✅ 401 | Auth required (correct) | | `/api/v1/billing/admin/stats/` | GET | ✅ 401 | Auth required (correct) |
### Account Endpoints ### Account Endpoints
@@ -27,21 +27,19 @@
## ❌ ISSUES FIXED ## ❌ ISSUES FIXED
### Frontend API Path Issues ### Frontend API Path Alignment
**Problem:** Frontend was calling `/api/billing/v2/...` instead of `/api/v1/billing/v2/...` **Problem:** Frontend must always call the canonical `/api/v1/billing/...` endpoints (no `/v2` alias).
**Files Fixed:** **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:** **Changes:**
```typescript ```typescript
// Before: // Before:
fetchAPI('/billing/v2/invoices/') fetchAPI('/billing/invoices/')
fetchAPI('/account/settings/')
// After: // After:
fetchAPI('/v1/billing/v2/invoices/') fetchAPI('/v1/billing/invoices/')
fetchAPI('/v1/account/settings/')
``` ```
### Component Export Issues ### Component Export Issues
@@ -84,33 +82,33 @@ await createManualPayment({...}) // ✅
| Account Settings | `/account/settings` | ✅ Ready | `/v1/account/settings/` | | Account Settings | `/account/settings` | ✅ Ready | `/v1/account/settings/` |
| Team Management | `/account/team` | ✅ Ready | `/v1/account/team/` | | Team Management | `/account/team` | ✅ Ready | `/v1/account/team/` |
| Usage Analytics | `/account/usage` | ✅ Ready | `/v1/account/usage/analytics/` | | 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 ### Billing Pages
| Page | Route | Status | Backend API | | Page | Route | Status | Backend API |
|------|-------|--------|-------------| |------|-------|--------|-------------|
| Credits Overview | `/billing/credits` | ✅ Ready | `/v1/billing/v2/transactions/balance/` | | Credits Overview | `/billing/credits` | ✅ Ready | `/v1/billing/transactions/balance/` |
| Transactions | `/billing/transactions` | ✅ Ready | `/v1/billing/v2/transactions/` | | Transactions | `/billing/transactions` | ✅ Ready | `/v1/billing/transactions/` |
| Usage | `/billing/usage` | ✅ Ready | `/v1/billing/v2/transactions/` | | Usage | `/billing/usage` | ✅ Ready | `/v1/billing/transactions/` |
| Plans | `/settings/plans` | ✅ Ready | `/v1/auth/plans/` | | Plans | `/settings/plans` | ✅ Ready | `/v1/auth/plans/` |
### Admin Pages ### Admin Pages
| Page | Route | Status | Backend API | | 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 | | Billing Management | `/admin/billing` | ⏳ Partial | Multiple endpoints |
## 🔧 URL STRUCTURE ## 🔧 URL STRUCTURE
### Correct URL Pattern ### Correct URL Pattern
``` ```
Frontend calls: /v1/billing/v2/invoices/ Frontend calls: /v1/billing/invoices/
API Base URL: https://api.igny8.com/api 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 ### API Base URL Detection

View File

@@ -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')

View File

@@ -41,8 +41,7 @@ urlpatterns = [
path('api/v1/planner/', include('igny8_core.modules.planner.urls')), path('api/v1/planner/', include('igny8_core.modules.planner.urls')),
path('api/v1/writer/', include('igny8_core.modules.writer.urls')), path('api/v1/writer/', include('igny8_core.modules.writer.urls')),
path('api/v1/system/', include('igny8_core.modules.system.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')), # Billing (credits, invoices, payments, packages)
path('api/v1/billing/', include('igny8_core.business.billing.urls')), # Advanced billing (invoices, payments, packages)
path('api/v1/admin/', include('igny8_core.modules.billing.admin_urls')), # Admin billing 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/automation/', include('igny8_core.business.automation.urls')), # Automation endpoints
path('api/v1/linker/', include('igny8_core.modules.linker.urls')), # Linker endpoints path('api/v1/linker/', include('igny8_core.modules.linker.urls')), # Linker endpoints

View File

@@ -13,3 +13,4 @@ beautifulsoup4>=4.12.0
psutil>=5.9.0 psutil>=5.9.0
docker>=7.0.0 docker>=7.0.0
drf-spectacular>=0.27.0 drf-spectacular>=0.27.0
stripe>=7.10.0

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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 <migration_number>
python manage.py sqlmigrate auth <migration_number>
# 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
```

View File

@@ -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.

View File

@@ -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<string, any>;
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<string, any>;
}
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<CreditBalance> {
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<string, {
credits: number;
cost: number;
count: number;
}>;
by_model: Record<string, {
credits: number;
cost: number;
count: number;
}>;
}> {
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<AdminBillingStats> {
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<AccountSettings> {
return fetchAPI('/v1/system/settings/account/');
}
export async function updateAccountSettings(
settings: Partial<AccountSettings>
): Promise<{
message: string;
account: Partial<AccountSettings>;
}> {
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<string, any>;
}
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<Invoice> {
return fetchAPI(`/v1/billing/invoices/${invoiceId}/`);
}
export async function downloadInvoicePDF(invoiceId: number): Promise<Blob> {
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<CreditBalance> {
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<AccountSettings> {
return fetchAPI('/v1/system/settings/account/');
}
export async function updateAccountSettings(
settings: Partial<AccountSettings>
): Promise<{
message: string;
account: Partial<AccountSettings>;
}> {
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<TeamMember>;
}> {
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<UsageAnalytics> {
return fetchAPI(`/v1/account/usage/analytics/?days=${days}`);
}