757 lines
49 KiB
Markdown
757 lines
49 KiB
Markdown
# IGNY8 Billing & Payments - Complete Reference
|
|
|
|
> **Last Updated:** January 20, 2026
|
|
> **Version:** 2.0 (Two-Pool Credit System)
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [System Overview](#1-system-overview)
|
|
2. [Credit System](#2-credit-system)
|
|
3. [Payment Methods](#3-payment-methods)
|
|
4. [Subscription Lifecycle](#4-subscription-lifecycle)
|
|
5. [Credit Packages](#5-credit-packages)
|
|
6. [Invoice System](#6-invoice-system)
|
|
7. [Renewal Workflow](#7-renewal-workflow)
|
|
8. [Admin Operations](#8-admin-operations)
|
|
9. [API Reference](#9-api-reference)
|
|
10. [Database Schema](#10-database-schema)
|
|
|
|
---
|
|
|
|
## 1. System Overview
|
|
|
|
### Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
│ IGNY8 BILLING SYSTEM │
|
|
├─────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ STRIPE │ │ PAYPAL │ │ BANK TRANSFER│ │
|
|
│ │ (Card/Intl) │ │ (Intl) │ │ (PK Only) │ │
|
|
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
|
|
│ │ │ │ │
|
|
│ ▼ ▼ ▼ │
|
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
|
│ │ PAYMENT GATEWAY LAYER │ │
|
|
│ │ • Webhook Processing • Payment Verification • Logging │ │
|
|
│ └─────────────────────────────┬───────────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
|
│ │ INVOICE SERVICE │ │
|
|
│ │ • Create Invoice • Update Status • PDF Generation │ │
|
|
│ └─────────────────────────────┬───────────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
|
│ │ CREDIT SERVICE │ │
|
|
│ │ • Plan Credits • Bonus Credits • Deduction • Reset │ │
|
|
│ └─────────────────────────────┬───────────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
|
│ │ ACCOUNT │ │
|
|
│ │ credits (plan) │ bonus_credits (purchased) │ status │ │
|
|
│ └─────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Key Files
|
|
|
|
| Component | File Path |
|
|
|-----------|-----------|
|
|
| Credit Service | `business/billing/services/credit_service.py` |
|
|
| Invoice Service | `business/billing/services/invoice_service.py` |
|
|
| Payment Service | `business/billing/services/payment_service.py` |
|
|
| Email Service | `business/billing/services/email_service.py` |
|
|
| Stripe Webhooks | `business/billing/views/stripe_views.py` |
|
|
| PayPal Webhooks | `business/billing/views/paypal_views.py` |
|
|
| Subscription Renewal | `business/billing/tasks/subscription_renewal.py` |
|
|
| Invoice Lifecycle | `business/billing/tasks/invoice_lifecycle.py` |
|
|
| Billing Admin | `modules/billing/admin.py` |
|
|
| Billing Models | `business/billing/models.py` |
|
|
|
|
---
|
|
|
|
## 2. Credit System
|
|
|
|
### Two-Pool Credit Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ ACCOUNT CREDITS │
|
|
├────────────────────────────┬────────────────────────────────┤
|
|
│ PLAN CREDITS │ BONUS CREDITS │
|
|
│ (account.credits) │ (account.bonus_credits) │
|
|
├────────────────────────────┼────────────────────────────────┤
|
|
│ • From subscription plan │ • From credit packages │
|
|
│ • Resets on renewal │ • NEVER expire │
|
|
│ • Used FIRST │ • Used SECOND (after plan=0) │
|
|
│ • Max = plan.included_ │ • No maximum limit │
|
|
│ credits │ │
|
|
└────────────────────────────┴────────────────────────────────┘
|
|
```
|
|
|
|
### Credit Deduction Flow
|
|
|
|
```
|
|
┌──────────────────┐
|
|
│ CREDIT REQUEST │
|
|
│ (e.g., 50) │
|
|
└────────┬─────────┘
|
|
│
|
|
▼
|
|
┌──────────────────┐
|
|
│ Check Total │
|
|
│ credits + bonus │
|
|
│ >= requested? │
|
|
└────────┬─────────┘
|
|
│
|
|
┌──────────────┴──────────────┐
|
|
│ NO │ YES
|
|
▼ ▼
|
|
┌────────────────┐ ┌────────────────────┐
|
|
│ INSUFFICIENT │ │ Plan Credits >= 50?│
|
|
│ Return False │ └─────────┬──────────┘
|
|
└────────────────┘ │
|
|
┌──────────┴──────────┐
|
|
│ YES │ NO
|
|
▼ ▼
|
|
┌───────────────┐ ┌────────────────────┐
|
|
│ Deduct from │ │ Deduct plan credits│
|
|
│ plan credits │ │ to 0, remainder │
|
|
│ only │ │ from bonus_credits │
|
|
└───────────────┘ └────────────────────┘
|
|
```
|
|
|
|
> **Note:** The two-pool logic is internal to `CreditService.deduct_credits()`. All AI functions and other credit consumers are unaffected - they call the same credit check/deduct methods as before.
|
|
|
|
### Credit Operations
|
|
|
|
| Operation | Method | Affects | Description |
|
|
|-----------|--------|---------|-------------|
|
|
| Add Plan Credits | `add_credits()` | `credits` | Initial subscription, manual adjustment |
|
|
| Add Bonus Credits | `add_bonus_credits()` | `bonus_credits` | Credit package purchases |
|
|
| Deduct Credits | `deduct_credits()` | Both pools | AI operations, uses plan first |
|
|
| Reset on Renewal | `reset_credits_for_renewal()` | `credits` only | Sets plan credits to new amount |
|
|
| Check Balance | `check_credits()` | Read-only | Returns total available |
|
|
|
|
### Credit Transaction Types
|
|
|
|
| Type | Description |
|
|
|------|-------------|
|
|
| `subscription` | Plan credits from subscription |
|
|
| `purchase` | Bonus credits from credit package |
|
|
| `usage` | Credit consumption for AI operations |
|
|
| `refund` | Credits returned due to failed operation |
|
|
| `manual` | Admin adjustment |
|
|
| `renewal` | Reset during subscription renewal |
|
|
| `bonus` | Promotional bonus credits |
|
|
|
|
---
|
|
|
|
## 3. Payment Methods
|
|
|
|
### Payment Method by Country
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ PAYMENT METHOD MATRIX │
|
|
├─────────────────┬───────────────────────────────────────────┤
|
|
│ COUNTRY │ AVAILABLE METHODS │
|
|
├─────────────────┼───────────────────────────────────────────┤
|
|
│ Pakistan (PK) │ ✅ Bank Transfer ✅ Stripe (Card) │
|
|
│ │ ❌ PayPal (not available) │
|
|
├─────────────────┼───────────────────────────────────────────┤
|
|
│ Other (Intl) │ ✅ Stripe (Card) ✅ PayPal │
|
|
│ │ ❌ Bank Transfer (not available) │
|
|
└─────────────────┴───────────────────────────────────────────┘
|
|
```
|
|
|
|
### Payment Flow by Method
|
|
|
|
#### Stripe (Card) Flow
|
|
|
|
```
|
|
┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐
|
|
│ User │────▶│ Frontend │────▶│ Create │────▶│ Stripe │
|
|
│ Clicks │ │ Checkout │ │ Checkout │ │ Hosted │
|
|
│ Pay │ │ │ │ Session │ │ Page │
|
|
└─────────┘ └──────────┘ └─────────────┘ └────┬─────┘
|
|
│
|
|
▼
|
|
┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐
|
|
│ Account │◀────│ Credit │◀────│ Invoice │◀────│ Webhook │
|
|
│ Active │ │ Added │ │ Paid │ │ Received │
|
|
└─────────┘ └──────────┘ └─────────────┘ └──────────┘
|
|
```
|
|
|
|
#### PayPal Flow
|
|
|
|
```
|
|
┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐
|
|
│ User │────▶│ Frontend │────▶│ Create │────▶│ PayPal │
|
|
│ Clicks │ │ Checkout │ │ Order/Sub │ │ Hosted │
|
|
│ Pay │ │ │ │ │ │ Page │
|
|
└─────────┘ └──────────┘ └─────────────┘ └────┬─────┘
|
|
│
|
|
▼
|
|
┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐
|
|
│ Account │◀────│ Credit │◀────│ Invoice │◀────│ Webhook │
|
|
│ Active │ │ Added │ │ Paid │ │ CAPTURE │
|
|
└─────────┘ └──────────┘ └─────────────┘ └──────────┘
|
|
```
|
|
|
|
#### Bank Transfer Flow (PK Only)
|
|
|
|
```
|
|
┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐
|
|
│ User │────▶│ View │────▶│ Manual │────▶│ Upload │
|
|
│ Selects │ │ Bank │ │ Transfer │ │ Proof │
|
|
│ Bank │ │ Details │ │ to Bank │ │ │
|
|
└─────────┘ └──────────┘ └─────────────┘ └────┬─────┘
|
|
│
|
|
▼
|
|
┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐
|
|
│ Account │◀────│ Credit │◀────│ Admin │◀────│ Payment │
|
|
│ Active │ │ Added │ │ Approves │ │ Created │
|
|
└─────────┘ └──────────┘ └─────────────┘ └──────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Subscription Lifecycle
|
|
|
|
### Subscription States
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ SUBSCRIPTION STATE MACHINE │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌─────────┐
|
|
│ NEW │
|
|
│ SIGNUP │
|
|
└────┬────┘
|
|
│ Create subscription + invoice
|
|
▼
|
|
┌─────────────┐ Payment Failed ┌─────────────┐
|
|
│ PENDING │─────────────────────────▶│ FAILED │
|
|
│ (awaiting │ │ │
|
|
│ payment) │ └─────────────┘
|
|
└──────┬──────┘
|
|
│ Payment Success
|
|
▼
|
|
┌─────────────┐
|
|
│ ACTIVE │◀─────────────────────────────────────┐
|
|
│ │ Renewal Payment Success │
|
|
└──────┬──────┘ │
|
|
│ Renewal Date │
|
|
▼ │
|
|
┌─────────────┐ Payment Within ┌───────────┴─┐
|
|
│ PENDING │ Grace Period │ │
|
|
│ RENEWAL │────────────────────────▶│ ACTIVE │
|
|
│ │ │ (renewed) │
|
|
└──────┬──────┘ └─────────────┘
|
|
│ Grace Period Expired (7 days)
|
|
▼
|
|
┌─────────────┐
|
|
│ EXPIRED │ Manual Reactivation
|
|
│ │────────────────────────▶ Back to PENDING
|
|
└─────────────┘
|
|
|
|
┌─────────────┐
|
|
│ CANCELLED │ User-initiated cancellation
|
|
│ │ (end of current period)
|
|
└─────────────┘
|
|
```
|
|
|
|
### Subscription Status Reference
|
|
|
|
| Status | Credits Access | Can Use Features | Next Action |
|
|
|--------|----------------|------------------|-------------|
|
|
| `pending` | ❌ No | ❌ No | Complete payment |
|
|
| `active` | ✅ Yes | ✅ Yes | None (auto-renews) |
|
|
| `pending_renewal` | ✅ Yes (24h) | ✅ Yes | Pay invoice |
|
|
| `expired` | ❌ No | ❌ Limited | Resubscribe |
|
|
| `cancelled` | ✅ Until end | ✅ Until end | None |
|
|
| `failed` | ❌ No | ❌ No | Retry payment |
|
|
|
|
---
|
|
|
|
## 5. Credit Packages
|
|
|
|
### Available Packages
|
|
|
|
| Package | Credits | USD Price | PKR Price | Per Credit |
|
|
|---------|---------|-----------|-----------|------------|
|
|
| Starter | 500 | $50.00 | ≈ PKR 14,000 | $0.10 |
|
|
| Growth | 2,000 | $200.00 | ≈ PKR 56,000 | $0.10 |
|
|
| Scale | 5,000 | $300.00 | ≈ PKR 83,000 | $0.06 |
|
|
| Enterprise | 20,000 | $1,200.00 | ≈ PKR 334,000 | $0.06 |
|
|
|
|
### Credit Package Purchase Flow
|
|
|
|
```
|
|
┌───────────────────────────────────────────────────────────────────────────┐
|
|
│ CREDIT PACKAGE PURCHASE FLOW │
|
|
└───────────────────────────────────────────────────────────────────────────┘
|
|
|
|
User selects package
|
|
│
|
|
▼
|
|
┌───────────────────┐
|
|
│ Create Invoice │
|
|
│ type='credit_ │
|
|
│ package' │
|
|
└─────────┬─────────┘
|
|
│
|
|
▼
|
|
┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐
|
|
│ Stripe/PayPal? │────▶│ Auto-process via │────▶│ Webhook confirms │
|
|
│ │ │ payment gateway │ │ payment success │
|
|
└─────────┬─────────┘ └───────────────────┘ └─────────┬─────────┘
|
|
│ │
|
|
│ Bank Transfer? │
|
|
▼ │
|
|
┌───────────────────┐ ┌───────────────────┐ │
|
|
│ Payment created │────▶│ Admin reviews & │ │
|
|
│ status='pending_ │ │ approves payment │ │
|
|
│ approval' │ └─────────┬─────────┘ │
|
|
└───────────────────┘ │ │
|
|
▼ ▼
|
|
┌───────────────────────────────────────┐
|
|
│ PAYMENT APPROVED │
|
|
└─────────────────┬─────────────────────┘
|
|
│
|
|
▼
|
|
┌───────────────────────────────────────┐
|
|
│ CreditService.add_bonus_credits() │
|
|
│ • Adds to account.bonus_credits │
|
|
│ • Creates CreditTransaction │
|
|
│ • NEVER expires │
|
|
└───────────────────────────────────────┘
|
|
```
|
|
|
|
### Credit Package Invoice Lifecycle
|
|
|
|
```
|
|
Invoice Created ──▶ 48 hours ──▶ Reminder Sent ──▶ 48 hours ──▶ Invoice Voided
|
|
│ │ │
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
status='pending' status='pending' status='void'
|
|
(reminder sent) (auto-cancelled)
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Invoice System
|
|
|
|
### Invoice Types
|
|
|
|
| Type | Description | Auto-Pay | Manual Pay |
|
|
|------|-------------|----------|------------|
|
|
| `subscription` | Monthly plan payment | Stripe/PayPal | Bank Transfer |
|
|
| `credit_package` | One-time credit purchase | Stripe/PayPal | Bank Transfer |
|
|
| `addon` | Additional features | Stripe/PayPal | Bank Transfer |
|
|
| `custom` | Manual/admin-created | ❌ | ✅ |
|
|
|
|
### Invoice Status Flow
|
|
|
|
```
|
|
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
│ DRAFT │────▶│ SENT │────▶│ PENDING │────▶│ PAID │
|
|
└─────────┘ └─────────┘ └────┬────┘ └─────────┘
|
|
│
|
|
┌────────┴────────┐
|
|
│ │
|
|
▼ ▼
|
|
┌──────────┐ ┌──────────┐
|
|
│ OVERDUE │ │ FAILED │
|
|
└────┬─────┘ └──────────┘
|
|
│
|
|
▼
|
|
┌──────────┐ ┌──────────┐
|
|
│ VOID │ │CANCELLED │
|
|
└──────────┘ └──────────┘
|
|
```
|
|
|
|
### Invoice Status Reference
|
|
|
|
| Status | Description | User Action |
|
|
|--------|-------------|-------------|
|
|
| `draft` | Being created | - |
|
|
| `sent` | Delivered to user | Pay Now |
|
|
| `pending` | Awaiting payment | Pay Now |
|
|
| `overdue` | Past due date | Pay Now (urgent) |
|
|
| `paid` | Payment received | Download PDF |
|
|
| `failed` | Payment failed | Retry/Pay Now |
|
|
| `void` | Cancelled by system | - |
|
|
| `cancelled` | Cancelled by admin | - |
|
|
|
|
---
|
|
|
|
## 7. Renewal Workflow
|
|
|
|
### Renewal Timeline by Payment Method
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
│ RENEWAL TIMELINE - STRIPE/PAYPAL (AUTO-PAY) │
|
|
│ Industry Standard: No Advance Notice │
|
|
├─────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ Day 0 (Renewal) Day +1 Day +7 │
|
|
│ │ │ │ │
|
|
│ ▼ ▼ ▼ │
|
|
│ ┌──────────┐ ┌────────────┐ ┌──────────┐ │
|
|
│ │Auto-Pay │ │ If Failed: │ │ Expired │ │
|
|
│ │ Attempt │ │ Retry + │ │ (after │ │
|
|
│ └────┬─────┘ │ Email Sent │ │ retries) │ │
|
|
│ │ └────────────┘ └──────────┘ │
|
|
│ ┌────┴────┐ │
|
|
│ │ SUCCESS │──▶ Receipt email + Credits reset to plan amount │
|
|
│ └────┬────┘ │
|
|
│ │ │
|
|
│ ┌────┴────┐ │
|
|
│ │ FAILURE │──▶ Payment failed email, Stripe retries 4x over 7 days │
|
|
│ └─────────┘ │
|
|
│ │
|
|
│ EMAIL SCHEDULE (Industry Standard - Netflix, Spotify, Adobe): │
|
|
│ • Payment Success: Receipt immediately │
|
|
│ • Payment Failed: Notification after each retry attempt │
|
|
│ • Final Warning: 1 day before account suspension │
|
|
│ • Account Suspended: When grace period ends │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
│ RENEWAL TIMELINE - BANK TRANSFER │
|
|
│ Simplified 3-Email Flow │
|
|
├─────────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ Day -3 Day 0 Day +1 Day +7 │
|
|
│ │ │ │ │ │
|
|
│ ▼ ▼ ▼ ▼ │
|
|
│ ┌────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
│ │Invoice │ │Reminder │ │ Urgent │ │ Expired │ │
|
|
│ │Created │ │ Email │ │Reminder │ │ │ │
|
|
│ │+Email │ │(if not │ │+Credits │ │ │ │
|
|
│ │ │ │ paid) │ │ Reset │ │ │ │
|
|
│ └────────┘ └─────────┘ └─────────┘ └─────────┘ │
|
|
│ │
|
|
│ Timeline: │
|
|
│ • Day -3: Invoice created + Email sent with payment instructions │
|
|
│ • Day 0: Reminder email (renewal day, if still unpaid) │
|
|
│ • Day +1: Urgent reminder + credits reset to 0 (if unpaid) │
|
|
│ • Day +7: Subscription expired │
|
|
│ │
|
|
│ EMAILS: │
|
|
│ 1. Invoice Email (Day -3): Invoice attached, bank details, Pay Now link │
|
|
│ 2. Renewal Reminder (Day 0): "Your subscription renews today" │
|
|
│ 3. Urgent Reminder (Day +1): "Payment overdue - action required" │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Renewal Credit Behavior
|
|
|
|
```
|
|
┌───────────────────────────────────────────────────────────────────┐
|
|
│ CREDIT RESET ON RENEWAL │
|
|
├───────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ SCENARIO 1: Payment Before Renewal │
|
|
│ ───────────────────────────────────── │
|
|
│ • Credits NOT reset early │
|
|
│ • On payment confirmation: │
|
|
│ - plan credits → reset to plan.included_credits │
|
|
│ - bonus_credits → UNCHANGED (never affected) │
|
|
│ │
|
|
│ SCENARIO 2: Payment After Renewal (within 24h) │
|
|
│ ────────────────────────────────────────────── │
|
|
│ • Credits stay unchanged for 24 hours │
|
|
│ • On payment confirmation: │
|
|
│ - plan credits → reset to plan.included_credits │
|
|
│ - bonus_credits → UNCHANGED │
|
|
│ │
|
|
│ SCENARIO 3: No Payment After 24 Hours │
|
|
│ ───────────────────────────────────── │
|
|
│ • plan credits → reset to 0 (task: send_day_after_reminders) │
|
|
│ • bonus_credits → UNCHANGED (user can still use these) │
|
|
│ • Warning email sent │
|
|
│ │
|
|
│ SCENARIO 4: Payment After Credit Reset │
|
|
│ ────────────────────────────────────── │
|
|
│ • On payment confirmation: │
|
|
│ - plan credits → reset to plan.included_credits (restored) │
|
|
│ - bonus_credits → UNCHANGED │
|
|
│ │
|
|
└───────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Celery Tasks Schedule
|
|
|
|
| Task | Schedule | Purpose |
|
|
|------|----------|---------|
|
|
| `create_bank_transfer_invoices` | Daily 09:00 | Create invoices 3 days before renewal (bank transfer only) |
|
|
| `process_subscription_renewals` | Daily 00:05 | Process auto-pay renewals (Stripe/PayPal) |
|
|
| `send_renewal_day_reminders` | Daily 10:00 | Send Day 0 reminder for bank transfer (if unpaid) |
|
|
| `send_day_after_reminders` | Daily 09:15 | Send Day +1 urgent reminders + reset credits |
|
|
| `check_expired_renewals` | Daily 00:15 | Mark subscriptions expired after 7-day grace period |
|
|
| `send_credit_invoice_expiry_reminders` | Daily 09:30 | Remind about expiring credit package invoices |
|
|
| `void_expired_credit_invoices` | Daily 00:45 | Auto-void credit invoices after 48h |
|
|
|
|
### Email Schedule Summary
|
|
|
|
**Stripe/PayPal (Auto-Pay) - Industry Standard:**
|
|
| Event | Email |
|
|
|-------|-------|
|
|
| Payment Success | ✅ Receipt/Confirmation |
|
|
| Payment Failed | ⚠️ Retry notification (per attempt) |
|
|
| Final Warning | 🚨 1 day before suspension |
|
|
| Account Suspended | ❌ Subscription expired |
|
|
|
|
**Bank Transfer (Manual Pay):**
|
|
| Day | Email |
|
|
|-----|-------|
|
|
| Day -3 | 📧 Invoice created + payment instructions |
|
|
| Day 0 | ⏰ Renewal day reminder (if unpaid) |
|
|
| Day +1 | 🚨 Urgent reminder + credits reset warning |
|
|
|
|
---
|
|
|
|
## 8. Admin Operations
|
|
|
|
### Webhook Events (Payment Logs)
|
|
|
|
**Location:** Admin → Billing → Webhook Events
|
|
|
|
| Column | Description |
|
|
|--------|-------------|
|
|
| Event ID | Unique ID from Stripe/PayPal |
|
|
| Provider | STRIPE or PAYPAL badge |
|
|
| Event Type | e.g., `checkout.session.completed`, `PAYMENT.CAPTURE.COMPLETED` |
|
|
| Status | Processed ✓, Failed ✗, Pending ⏳ |
|
|
| Process Time | Actual processing duration |
|
|
| Created | When webhook received |
|
|
|
|
**Actions:**
|
|
- Mark as processed
|
|
- Retry processing
|
|
- View full payload (JSON)
|
|
|
|
### Payment Approval (Bank Transfer)
|
|
|
|
**Location:** Admin → Billing → Payments
|
|
|
|
**Approval Flow:**
|
|
1. Filter by `status = pending_approval`
|
|
2. Review `manual_reference` and `manual_notes`
|
|
3. Check proof of payment upload
|
|
4. Change status to `succeeded`
|
|
5. System automatically:
|
|
- Updates invoice to `paid`
|
|
- Activates account (if subscription)
|
|
- Adds credits (plan or bonus based on invoice type)
|
|
|
|
### Manual Credit Adjustment
|
|
|
|
**Location:** Admin → Billing → Credit Transactions
|
|
|
|
**To add credits manually:**
|
|
1. Go to Account admin
|
|
2. Edit the account
|
|
3. Modify `credits` (plan) or `bonus_credits` (purchased)
|
|
4. Save with note in admin_notes
|
|
|
|
**OR use shell:**
|
|
```python
|
|
from igny8_core.business.billing.services.credit_service import CreditService
|
|
|
|
# Add plan credits
|
|
CreditService.add_credits(
|
|
account=account,
|
|
amount=500,
|
|
transaction_type='manual',
|
|
description='Manual adjustment - support ticket #123'
|
|
)
|
|
|
|
# Add bonus credits
|
|
CreditService.add_bonus_credits(
|
|
account=account,
|
|
amount=500,
|
|
description='Promotional bonus - January 2026'
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## 9. API Reference
|
|
|
|
### Endpoints
|
|
|
|
| Endpoint | Method | Description |
|
|
|----------|--------|-------------|
|
|
| `/api/v1/billing/credits/` | GET | Get credit balance |
|
|
| `/api/v1/billing/credits/usage/` | GET | Get usage statistics |
|
|
| `/api/v1/billing/invoices/` | GET | List invoices |
|
|
| `/api/v1/billing/invoices/{id}/` | GET | Invoice detail |
|
|
| `/api/v1/billing/invoices/{id}/pdf/` | GET | Download invoice PDF |
|
|
| `/api/v1/billing/payments/` | GET | List payments |
|
|
| `/api/v1/billing/plans/` | GET | List available plans |
|
|
| `/api/v1/billing/subscriptions/` | GET | List subscriptions |
|
|
| `/api/v1/billing/credit-packages/` | GET | List credit packages |
|
|
| `/api/v1/billing/purchase/credits/` | POST | Purchase credit package |
|
|
| `/api/v1/billing/subscribe/` | POST | Subscribe to plan |
|
|
| `/api/v1/webhooks/stripe/` | POST | Stripe webhook endpoint |
|
|
| `/api/v1/webhooks/paypal/` | POST | PayPal webhook endpoint |
|
|
|
|
### Credit Balance Response
|
|
|
|
```json
|
|
{
|
|
"credits": 3500,
|
|
"bonus_credits": 2000,
|
|
"total_credits": 5500,
|
|
"credits_used_this_month": 1500,
|
|
"plan_credits_per_month": 5000,
|
|
"subscription_plan": "Scale",
|
|
"period_end": "2026-02-12T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Database Schema
|
|
|
|
### Core Tables
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ accounts │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ id │ PK │
|
|
│ name │ Account name │
|
|
│ status │ pending, active, expired, etc. │
|
|
│ credits │ Plan credits (resets on renewal) │
|
|
│ bonus_credits │ Purchased credits (never expire) │
|
|
│ plan_id │ FK → plans │
|
|
│ billing_email │ Email for invoices │
|
|
│ billing_country │ Country code (PK, US, etc.) │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ subscriptions │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ id │ PK │
|
|
│ account_id │ FK → accounts │
|
|
│ plan_id │ FK → plans │
|
|
│ status │ pending, active, pending_renewal, expired, etc. │
|
|
│ current_period_start │ Start of current billing period │
|
|
│ current_period_end │ End of current billing period (renewal date) │
|
|
│ metadata │ JSON (stripe_subscription_id, paypal_sub_id) │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ invoices │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ id │ PK │
|
|
│ invoice_number │ Unique invoice number (INV-2026-00001) │
|
|
│ account_id │ FK → accounts │
|
|
│ subscription_id │ FK → subscriptions (nullable) │
|
|
│ invoice_type │ subscription, credit_package, addon, custom │
|
|
│ status │ draft, sent, pending, paid, overdue, void, etc. │
|
|
│ total_amount │ Total amount │
|
|
│ currency │ USD, PKR │
|
|
│ due_date │ Payment due date │
|
|
│ paid_at │ When payment received │
|
|
│ metadata │ JSON (credit_package_id, etc.) │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ payments │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ id │ PK │
|
|
│ invoice_id │ FK → invoices │
|
|
│ account_id │ FK → accounts │
|
|
│ amount │ Payment amount │
|
|
│ currency │ USD, PKR │
|
|
│ payment_method │ stripe, paypal, bank_transfer │
|
|
│ status │ pending_approval, processing, succeeded, failed│
|
|
│ stripe_payment_intent_id│ Stripe reference │
|
|
│ paypal_order_id │ PayPal reference │
|
|
│ manual_reference │ Bank transfer reference │
|
|
│ approved_by_id │ FK → users (admin who approved) │
|
|
│ approved_at │ When approved │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ credit_transactions │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ id │ PK │
|
|
│ account_id │ FK → accounts │
|
|
│ transaction_type │ subscription, purchase, usage, refund, manual, etc. │
|
|
│ amount │ Credits added (+) or deducted (-) │
|
|
│ balance_after │ Balance after this transaction │
|
|
│ description │ Human-readable description │
|
|
│ metadata │ JSON (invoice_id, payment_id, etc.) │
|
|
│ created_at │ Timestamp │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ webhook_events │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ id │ PK │
|
|
│ event_id │ Unique event ID from provider │
|
|
│ provider │ stripe, paypal │
|
|
│ event_type │ checkout.session.completed, PAYMENT.CAPTURE.COMPLETED │
|
|
│ payload │ JSON - full webhook payload │
|
|
│ processed │ Boolean - successfully processed? │
|
|
│ processed_at │ When processed │
|
|
│ error_message│ Error if processing failed │
|
|
│ retry_count │ Number of retry attempts │
|
|
│ created_at │ When received │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Quick Reference Card
|
|
|
|
### Credit Consumption Priority
|
|
1. **Plan credits** used first
|
|
2. **Bonus credits** used only when plan credits = 0
|
|
|
|
### What Happens on Renewal
|
|
|
|
| Event | Plan Credits | Bonus Credits |
|
|
|-------|--------------|---------------|
|
|
| Payment success | Reset to plan amount | No change |
|
|
| No payment (24h) | Reset to 0 | No change |
|
|
| Late payment | Reset to plan amount | No change |
|
|
|
|
### Payment Method Availability
|
|
|
|
| Country | Stripe | PayPal | Bank Transfer |
|
|
|---------|--------|--------|---------------|
|
|
| Pakistan (PK) | ✅ | ❌ | ✅ |
|
|
| Others | ✅ | ✅ | ❌ |
|
|
|
|
### Invoice Expiry
|
|
|
|
| Invoice Type | Expiry |
|
|
|--------------|--------|
|
|
| Subscription | 7 days (grace period) |
|
|
| Credit Package | 48 hours |
|
|
|
|
---
|
|
|
|
*Document generated from current codebase implementation as of January 20, 2026*
|