Backend Modules
apps.billing — Packages, Invoices & Recharges
Broadband packages, recurring invoicing, recharge workflows, and promotional offers.
apps.billing — Packages, Invoices & Recharges
IMPLEMENTED
- Location:
backend/apps/billing/ - Responsibilities: Broadband bandwidth tiers, package definitions, recurring monthly invoices, recharge transactions, and promotional discounts.
1. Database Models (5 Models)
| Model Name | Purpose | Key Fields |
|---|---|---|
Package | Broadband plan (speed, rate, validity, MikroTik profile) | name, price, bandwidth_mbps, mikrotik_profile, validity_days |
ResellerPricing | Custom wholesale rate for packages per reseller | reseller, package, custom_rate, is_active |
Invoice | Monthly recurring subscription bill | invoice_number, customer, amount, paid_amount, status, due_date |
Recharge | Record of subscription renewal and date extension | customer, package, amount, validity_days, recharged_by |
Offer | Promotional discounts or bundle campaigns | title, discount_type, discount_value, start_date, end_date |
2. Controllers & Workflows
Packages & Offers
GET/POST /api/v1/packages/: Manage broadband tiers and sync corresponding RouterOS queue profiles.GET/POST /api/v1/offers/: Campaign and discount configuration.
Invoices (InvoiceViewSet)
GET /api/v1/invoices/: View invoices, filter bystatus(UNPAID,PAID,PARTIAL,OVERDUE),customer,billing_month.POST /api/v1/invoices/: Create an invoice with optional itemizedlines. Iflinesare provided, line totals are computed ((quantity * unit_price) - discount + tax_amount), validated fields are preserved, and debit ledger entries are posted.POST /api/v1/invoices/generate-batch/: Trigger tenant-wide recurring monthly invoice generation.- Async Execution (Default): Automatically dispatches a Celery worker task (
generate_monthly_invoices.delay()) protected by a Redis distributed lock (lock:invoice_gen:{tenant_id}). Responds withHTTP 202 Accepted:{ "success": true, "task_id": "8a32b0c1-6b45-42f0-9a3d-3df798b1a234", "status": "QUEUED", "async": true } - Synchronous Override: Passing
?async=falseor payload{"async": false}executes inline synchronously, returningHTTP 200 OKwith generated invoice counts:{ "success": true, "invoices_created": 42, "month": "September 2026", "async": false }
- Async Execution (Default): Automatically dispatches a Celery worker task (
Recharges (RechargeViewSet)
POST /api/v1/recharges/: Atomic recharge action. Acceptscustomer_id,amount,validity_days. Updates expiry date, creates a completedPaymentTransaction, settles open invoices, and posts creditLedgerEntry.POST /api/v1/recharges/{id}/reverse/: Non-destructive compensating reversal for an erroneous recharge.- Accepts optional payload:
{"reason": "Customer requested cash refund"}. - Idempotent and audit-trailed: marks
recharge.is_reversed = True, marks linked payment transactionREFUNDED, posts debitREVERSALledger entry, restores original expiry date, and re-opens cleared invoices. - Returns
HTTP 200 OK:{ "success": true, "recharge": { "id": "7b7a5a8f-2879-4509-9fd6-ec412c96c568", "is_reversed": true, "customer": "user100" }, "reversed_by": "admin" }
- Accepts optional payload: