8.4 KiB
8.4 KiB
Billing Module Reference
Purpose
Explain how billing is implemented: invoices, payments, credit packages, credit history/usage, payment methods, and limits, as exposed by billing services and API viewsets.
Code Locations (exact paths)
- Models:
backend/igny8_core/business/billing/models.py - Services:
backend/igny8_core/business/billing/services/credit_service.py,invoice_service.py,payment_service.py - API (business billing):
backend/igny8_core/business/billing/views.py,backend/igny8_core/business/billing/urls.py - API (core billing endpoints):
backend/igny8_core/modules/billing/views.py,backend/igny8_core/modules/billing/urls.py - Plan metadata (included credits/limits):
backend/igny8_core/auth/models.py(Plan,Account)
High-Level Responsibilities
- Maintain credit ledger, usage logs, configurable per-operation costs, invoices, payments, credit packages, country-level payment method configs, and account-scoped payment methods.
- Expose endpoints for invoices/payments/credit packages/transactions, credit balance/usage/limits, and admin billing operations.
- Deduct or add credits atomically while recording both transactions and usage logs.
- Provide manual and (placeholder) Stripe/PayPal payment flows.
Detailed Behavior
- Invoices (
InvoiceViewSet):list/retrieve: fetch account-scoped invoices; include totals, line items, billing period, dates.download_pdf: returns PDF bytes fromInvoiceService.generate_pdf(currently placeholder text payload).
- Payments (
PaymentViewSet):list: account-scoped payments with amounts, methods, status, invoice linkage, timestamps.available_methods: delegates toPaymentService.get_available_payment_methods(country/config-driven; returns methods plus metadata).create_manual_payment: creates a manual payment for an invoice (bank/local wallet); requires invoice_id, method, reference; rejects already-paid invoices; returns pending-approval status.
- Account payment methods (
AccountPaymentMethodViewSet):- CRUD for account-level payment metadata (non-sensitive).
perform_create/perform_updateenforce one default by resetting others whenis_defaulttrue or none exists. set_defaulttoggles default within the account.
- CRUD for account-level payment metadata (non-sensitive).
- Credit packages (
CreditPackageViewSet):list: active packages with credits/price/discount/featured/sort order.purchase: creates invoice viaInvoiceService.create_credit_package_invoice; returns next action depending on requested payment method (stripe/paypalplaceholders, manual fallback returns invoice info).
- Credit transactions (
CreditTransactionViewSetin business billing views; also registered undercredits/transactionsin URLs): lists credit ledger entries per account. - Core billing endpoints (
modules/billing/views.py):CreditBalanceViewSet.list: returns current credits, plan monthly credits, credits used this month.CreditUsageViewSet: paginated credit usage logs with filters (operation_type, date range);summaryaggregates by operation/model and totals (credits, USD);limitsreturns plan/account limits and usage (users/sites/etc.) based onPlanfields.
- Routing (
business/billing/urls.py):- Routers for invoices, payments, credit packages, transactions, payment methods, and canonical credit endpoints (balance/usage/transactions). Legacy available-methods endpoint exposed at
/payment-methods/available/.
- Routers for invoices, payments, credit packages, transactions, payment methods, and canonical credit endpoints (balance/usage/transactions). Legacy available-methods endpoint exposed at
Data Structures / Models Involved (no code)
CreditTransaction: ledger with type, amount (positive/negative), balance_after, metadata.CreditUsageLog: per-AI-operation usage with operation_type, credits_used, cost_usd, model_used, tokens, related object references, metadata.CreditCostConfig: per-operation cost config with unit, display metadata, active flag, audit of previous cost.Invoice: invoice_number, status, amounts (subtotal/tax/total), currency, billing_period, line_items JSON, subscription link, payment metadata, timestamps.Payment: status lifecycle, method (stripe/paypal/bank/local wallet/manual), provider references, manual notes/approval, failure reason, metadata.CreditPackage,PaymentMethodConfig(country/method availability + instructions/bank/local wallet data),AccountPaymentMethod(account-scoped payment metadata).- Plan/account credits and limits:
Plan.included_credits,Plan.max_users/sites/industries/author_profiles,Account.credits.
Execution Flow
- Credits:
- Operations call
CreditService.get_credit_cost→check_credits/deduct_creditsordeduct_credits_for_operation→ updatesAccount.credits, writesCreditTransactionandCreditUsageLog. - Costs resolved from
CreditCostConfigwhen active; otherwise constants. Units support per request, per 100/200 words, per item/image/idea.
- Operations call
- Invoicing/Payments:
- Credit package purchase → invoice creation → next-action response (manual vs pending Stripe/PayPal integration).
- Manual payment submission →
PaymentService.create_manual_paymentpersists pending approval.
- Credit balance/usage:
- Balance endpoint computes plan credits and month-to-date usage (from
CreditUsageLog). - Usage endpoint filters logs; summary aggregates by operation/model and totals; limits endpoint computes plan-based limits and usage (users/sites/etc.) per account.
- Balance endpoint computes plan credits and month-to-date usage (from
Cross-Module Interactions
- AI/automation/planner/writer flows trigger credit checks/deductions through
CreditService; usage logs can be filtered by operation_type (clustering, idea_generation, content_generation, image_generation, optimization, reparse). - Plan limits surfaced in billing limits endpoint affect account/user/site management elsewhere.
- Invoice/payment metadata may be used by frontend billing UI; manual payments require admin follow-up.
State Transitions
- Credits mutate
Account.credits; ledger captures each change; usage logs accumulate per operation. - Invoices move through statuses (
draft/pending/paid/void/uncollectible); payments through (pending/pending_approval/processing/succeeded/completed/failed/refunded/cancelled). - Credit packages and payment methods have active/default flags; cost configs can be toggled active/inactive.
Error Handling
- Insufficient credits raise
InsufficientCreditsError; API returns 402 when caught (e.g., content generation, credit deduct flows). - Manual payment rejects missing fields or already-paid invoices.
- Usage/balance endpoints return empty data when account/plan missing instead of hard errors.
- Validation errors on site/sector/account scoping propagate from base viewsets and model constraints.
Tenancy Rules
- Account scoping enforced via
AccountModelViewSetor explicit account filtering in viewsets; all billing data is per-account. - Payment methods, invoices, payments, transactions, usage logs, and balances are filtered to
request.user.account(orrequest.accountfrom middleware). - Plan data comes from the account’s associated plan; no cross-tenant visibility.
Billing Rules
- Credit costs configurable via
CreditCostConfig; fallback constants apply when no config. - Credit deductions and ledger entries are atomic; usage logs record the same operation with optional model/token metadata.
- Balance endpoint includes plan monthly credits; limits endpoint reports plan/user/site limits but does not enforce them here.
Background Tasks / Schedulers
- None specific to billing in this module; Stripe/PayPal integrations are placeholders. Any future webhooks should persist to these models and adjust credits/invoices/payments accordingly.
Key Design Considerations
- Credit handling is centralized in
CreditServiceto keep ledger and usage logs consistent. - Usage/balance endpoints are read-mostly, with graceful handling when plan/account data is missing.
- Manual payments support bank/local wallet flows without storing sensitive data; account payment methods store display metadata only.
How Developers Should Work With This Module
- Use
CreditServicefor all credit checks/deductions/additions; do not mutateAccount.creditsdirectly. - When adding new AI operations, add
operation_typetoCreditUsageLog.OPERATION_TYPE_CHOICESandCreditCostConfigseed/constants, then usededuct_credits_for_operation. - Extend payment flows by implementing Stripe/PayPal handlers in
PaymentServiceand wiring webhooks to updatePayment/Invoice. - Use existing serializers/viewsets when exposing billing data; keep queries scoped to
request.account.