# Billing Module

**Last Verified:** January 10, 2026
**Status:** ✅ Active (Image Generation Credit System Complete January 2026)  
**Backend Path:** `backend/igny8_core/modules/billing/` + `backend/igny8_core/business/billing/`  
**Frontend Path:** `frontend/src/pages/Billing/` + `frontend/src/pages/Account/`

> **Payment System Reference:** For comprehensive payment gateway documentation (Stripe, PayPal, Bank Transfer), see [PAYMENT-SYSTEM.md](../90-REFERENCE/PAYMENT-SYSTEM.md)

---

## Quick Reference

| What | File | Key Items |
|------|------|-----------|
| Models | `business/billing/models.py` | `CreditTransaction`, `CreditUsageLog`, `CreditCostConfig`, `AIModelConfig` |
| Service | `business/billing/services/credit_service.py` | `CreditService` |
| Limit Service | `business/billing/services/limit_service.py` | `LimitService` (4 limits only) |
| Views | `modules/billing/views.py` | `CreditBalanceViewSet`, `CreditUsageViewSet` |
| Frontend | `pages/Account/PlansAndBillingPage.tsx` | Plans, credits, billing history |
| Store | `store/billingStore.ts` | `useBillingStore` |

---

## Purpose

The Billing module manages:
- Credit balance and transactions
- AI model pricing and credit configuration (v1.4.0)
- Usage tracking with 4 simplified limits (v1.5.0)
- Plan enforcement
- Payment processing

---

## Data Models

### AIModelConfig (NEW v1.4.0)

Single Source of Truth for all AI models with pricing.

| Field | Type | Purpose |
|-------|------|---------|
| model_name | CharField(100) | Model identifier (gpt-4o-mini, dall-e-3) |
| model_type | CharField(20) | text / image |
| provider | CharField(50) | openai, anthropic, runware |
| display_name | CharField(200) | Human-readable name |
| is_default | BooleanField | One default per type |
| is_active | BooleanField | Enable/disable |
| cost_per_1k_input | DecimalField | USD cost per 1K input tokens (text) |
| cost_per_1k_output | DecimalField | USD cost per 1K output tokens (text) |
| tokens_per_credit | IntegerField | Text: tokens per 1 credit (e.g., 1000) |
| credits_per_image | IntegerField | Image: credits per image (1, 5, 15) |
| quality_tier | CharField(20) | basic / quality / premium |
| max_tokens | IntegerField | Model token limit |
| context_window | IntegerField | Model context size |
| capabilities | JSONField | vision, function_calling, etc. |

**Credit Examples:**

| Model | tokens_per_credit | credits_per_image | quality_tier |
|-------|-------------------|-------------------|--------------|
| gpt-4o | 1000 | - | - |
| gpt-4o-mini | 10000 | - | - |
| runware:97@1 | - | 1 | basic |
| dall-e-3 | - | 5 | quality |
| google:4@2 | - | 15 | premium |

### CreditTransaction (Ledger)

| Field | Type | Purpose |
|-------|------|---------|
| account | FK | Owner account |
| transaction_type | CharField | purchase/subscription/refund/deduction/adjustment |
| amount | Decimal | Positive (add) or negative (deduct) |
| balance_after | Decimal | Balance after transaction |
| description | CharField | Transaction description |
| metadata | JSON | Additional data |
| payment | FK(Payment) | Payment that triggered this (v1.4.0) |
| reference_id | CharField | DEPRECATED: Use payment FK |
| created_at | DateTime | Transaction time |

### CreditUsageLog (Analytics)

| Field | Type | Purpose |
|-------|------|---------|
| account | FK | Owner account |
| operation_type | CharField | clustering/idea_generation/content_generation/image_generation |
| credits_used | Decimal | Credits consumed |
| cost_usd | Decimal | USD cost |
| model_used | CharField | AI model used |
| tokens_in | Integer | Input tokens |
| tokens_out | Integer | Output tokens |
| content_type | FK | Related content type |
| object_id | Integer | Related object ID |
| metadata | JSON | Additional data |
| created_at | DateTime | Usage time |

### CreditCostConfig (Updated v1.4.0)

| Field | Type | Purpose |
|-------|------|---------|
| operation_type | CharField(50) PK | Unique operation ID |
| display_name | CharField(100) | Human-readable name |
| base_credits | IntegerField | Fixed credits per operation |
| is_active | BooleanField | Enable/disable |
| description | TextField | Admin notes |

**Note:** `tokens_per_credit` moved to AIModelConfig in v1.4.0.

---

## Credit Calculation Methods

### Method 1: Token-Based (Text Models) - Updated v1.4.0

Used for: Clustering, Ideas, Content Generation, Optimization

**Flow:**
1. AI call completes
2. OpenAI returns actual token usage
3. Calculate: `total_tokens = input_tokens + output_tokens`
4. Look up `AIModelConfig.tokens_per_credit` for the model used
5. Calculate: `credits = ceil(total_tokens / tokens_per_credit)`
6. Deduct from balance

**Example:**
- Model: `gpt-4o-mini` (tokens_per_credit = 10000)
- Tokens used: 15000
- Credits: `ceil(15000 / 10000)` = 2 credits

### Method 2: Fixed Cost (Image Models) - Updated v1.4.0

Used for: Image Generation

**Flow:**
1. User selects quality tier (basic/quality/premium)
2. Look up `AIModelConfig.credits_per_image` for selected tier
3. Check balance sufficient: `balance >= num_images * credits_per_image`
4. Deduct credits
5. Make AI call

**Example:**
- Quality Tier: "quality" (dall-e-3, credits_per_image = 5)
- Images: 3
- Credits: 3 × 5 = 15 credits
2. Calculate: `credits = num_images * cost_per_image`
3. Check balance sufficient
4. Deduct credits
5. Then make AI call

---

## API Endpoints

| Method | Path | Handler | Purpose |
|--------|------|---------|---------|
| GET | `/api/v1/billing/balance/` | `CreditBalanceViewSet.list` | Current balance + monthly usage |
| GET | `/api/v1/billing/usage/` | `CreditUsageViewSet.list` | Usage log (paginated) |
| GET | `/api/v1/billing/usage/summary/` | `CreditUsageViewSet.summary` | Aggregated by operation |
| GET | `/api/v1/billing/usage/limits/` | `CreditUsageViewSet.limits` | Plan limits + current usage |
| GET | `/api/v1/billing/transactions/` | `TransactionViewSet.list` | Transaction history |

---

## Credit Service API

### Check Credits

```python
CreditService.check_credits(account, required_credits)
# Raises InsufficientCreditsError if balance < required
```

### Deduct Credits

```python
CreditService.deduct_credits_for_operation(
    account=account,
    operation_type='content_generation',
    amount=word_count,  # For per_word operations
    model='gpt-4o-mini',
    tokens_in=2500,
    tokens_out=1500,
    metadata={'content_id': 123}
)
```

### Add Credits

```python
CreditService.add_credits(
    account=account,
    amount=1000,
    transaction_type='purchase',
    description='Credit package purchase'
)
```

### Calculate Credits for Images (NEW v1.4.0)

```python
# Calculate credits needed for image generation based on model
credits = CreditService.calculate_credits_for_image(
    model_name='dall-e-3',  # Model with credits_per_image = 5
    num_images=3
)
# Returns: 15 (3 images × 5 credits)
```

### Check Credits for Image Generation (NEW v1.7.1)

```python
# Pre-check credits before image generation starts
# Raises InsufficientCreditsError if not enough credits
required = CreditService.check_credits_for_image(
    account=account,
    model_name='dall-e-3',  # Model with credits_per_image = 5
    num_images=3
)
# Returns: 15 (required credits) if sufficient, raises exception if not
```

### Deduct Credits for Image Generation (v1.7.1 Verified)

```python
# Called after each successful image generation
credits_deducted = CreditService.deduct_credits_for_image(
    account=account,
    model_name='dall-e-3',
    num_images=1,
    description='Image generation: Article Title',
    metadata={'image_id': 123, 'content_id': 456},
    cost_usd=0.04,
    related_object_type='image',
    related_object_id=123
)
# Logs to CreditTransaction and CreditUsageLog
```

### Calculate Credits from Tokens by Model (NEW v1.4.0)

```python
# Calculate credits from token usage based on model's tokens_per_credit
credits = CreditService.calculate_credits_from_tokens_by_model(
    model_name='gpt-4o-mini',  # Model with tokens_per_credit = 10000
    total_tokens=15000
)
# Returns: 2 (ceil(15000 / 10000))
```

---

## Plan Limits

### Hard Limits (Never Reset)

| Limit | Field | Description |
|-------|-------|-------------|
| Sites | `max_sites` | Maximum sites per account |
| Users | `max_users` | Maximum team members |
| Keywords | `max_keywords` | Total keywords allowed |

### Monthly Limits (Reset on Billing Cycle)

| Limit | Field | Description |
|-------|-------|-------------|
| Ahrefs Queries | `max_ahrefs_queries` | Live Ahrefs API queries per month |

**Note:** As of January 2026, the limit system was simplified from 10+ limits to just 4. Credits handle all AI operation costs (content generation, image generation, clustering, etc.) instead of separate per-operation limits.

---

## Usage Limits Panel

**Component:** `UsageLimitsPanel.tsx`

Displays:
- Progress bars for 4 limits only (Sites, Users, Keywords, Ahrefs Queries)
- Color coding: blue (safe), yellow (warning), red (critical)
- Days until reset for monthly limits (Ahrefs Queries)
- Upgrade CTA when approaching limits

---

## Credit Costs Reference (Updated v1.4.0)

**Text Model Credits** (from `AIModelConfig.tokens_per_credit`):

| Model | tokens_per_credit | Cost/Credit | Notes |
|-------|-------------------|-------------|-------|
| gpt-4o | 1000 | ~$0.015 | High quality, lower throughput |
| gpt-4o-mini | 10000 | ~$0.001 | Fast, cost-effective |
| gpt-4.5-preview | 500 | ~$0.05 | Highest quality |

**Image Model Credits** (from `AIModelConfig.credits_per_image`):

| Quality Tier | credits_per_image | Model Example | Notes |
|--------------|-------------------|---------------|-------|
| Basic | 1 | runware:97@1 | Fast generation |
| Quality | 5 | dall-e-3 | Balanced |
| Premium | 15 | google:4@2 | Best quality |

**Operation Base Costs** (from `CreditCostConfig.base_credits`):

| Operation | Base Credits | Notes |
|-----------|--------------|-------|
| Clustering | 10 | Per clustering request |
| Idea Generation | 2 | Per idea generated |
| Content Optimization | 5 | Per optimization run |

---

## Frontend Pages

### Plans & Billing (`/account/plans`)

**Tabs:**
1. **Current Plan** - Active plan details, renewal date, "View Usage" link
2. **Upgrade Plan** - Pricing table with plan comparison
3. **Billing History** - Invoices and payment history

### Usage Analytics (`/account/usage`)

**Tabs:**
1. **Limits & Usage** - Plan limits with progress bars (4 limits only)
2. **Credit History** - Credit transaction history
3. **Credit Insights** - Charts: credits by type, daily timeline, operations breakdown
4. **Activity Log** - API call statistics and operation details

---

## Integration Points

| From | To | Trigger |
|------|----|---------| 
| AIEngine | CreditService | Pre-check and post-deduct |
| Automation | CreditService | Per-stage credit tracking |
| Subscription | Account | Credit allocation |
| Admin | CreditCostConfig | Price adjustments |

---

## Common Issues

| Issue | Cause | Fix |
|-------|-------|-----|
| 402 error | Insufficient credits | Add credits or reduce operation |
| Usage not showing | Log not created | Check CreditService called |
| Limits wrong | Cache stale | Clear cache, reload |
| Monthly usage high | Automation running | Pause automation |

---

## Planned Changes

| Feature | Status | Description |
|---------|--------|-------------|
| ~~AI Model Config database~~ | ✅ v1.4.0 | Model pricing moved to AIModelConfig |
| ~~Image model quality tiers~~ | ✅ v1.4.0 | credits_per_image per quality tier |
| ~~Credit service enhancements~~ | ✅ v1.7.1 | Model-specific calculation methods |
| ~~Image generation credit check~~ | ✅ v1.7.1 | Pre-generation credit verification |
| ~~Image generation logging~~ | ✅ v1.7.1 | AITaskLog + notifications for images |
