7.1 KiB
Concept Note: Generic Billing & Tracking Framework
1) Purpose
The model is designed to support a flexible, generic, and auditable billing environment that can be applied across diverse services and providers — from compute time billing to per-request API usage, across multiple currencies, with dynamic provider-specific overrides.
It is not tied to a single business domain — the same framework can be used for:
- Cloud compute time (per second)
- API transactions (per request)
- Data transfer charges
- Managed service subscriptions
- Brokered third-party service reselling
2) Key Concepts
2.1 Accounts
An account represents an economic actor in the system — typically a customer or a service provider.
- Identified by a public key (for authentication & cryptographic signing).
- Every billing action traces back to an account.
2.2 Currencies & Asset Codes
The system supports multiple currencies (crypto or fiat) via asset codes.
- Asset codes identify the unit of billing (e.g.
USDC-ETH
,EUR
,LND
). - Currencies are decoupled from services so you can add or remove supported assets at any time.
2.3 Services & Groups
-
Service = a billable offering (e.g., "Speech-to-Text", "VM Hosting").
- Has a billing mode (
per_second
orper_request
). - Has a default price and default currency.
- Supports multiple accepted currencies with optional per-currency pricing overrides.
- Has execution constraints (e.g.
max_request_seconds
). - Includes structured schemas for request payloads.
- Has a billing mode (
-
Service Group = a logical grouping of services.
- Groups make it easy to bundle related services and manage them together.
- Providers can offer entire groups rather than individual services.
2.4 Service Providers
A service provider is an account that offers services or service groups. They can:
- Override pricing for their offered services (per currency).
- Route requests to their own runners (execution agents).
- Manage multiple service groups under one provider identity.
2.5 Runners
A runner is an execution agent — a node, VM, or service endpoint that can fulfill requests.
- Identified by an IPv6 address (supports Mycelium or other overlay networks).
- Can be owned by one or multiple providers.
- Providers map services/groups → runners to define routing.
2.6 Subscriptions
A subscription is the authorization mechanism for usage and spending control:
- Links an account to a service or service group.
- Defines spending limits (amount, currency, period: hour/day/month).
- Restricts which providers are allowed to serve the subscription.
- Uses a secret chosen by the subscriber — providers use this to claim charges.
2.7 Requests
A request represents a single execution under a subscription:
- Tied to account, subscription, provider, service, and optionally runner.
- Has status (
pending
,running
,succeeded
,failed
,canceled
). - Records start/end times for duration-based billing.
2.8 Billing Ledger
The ledger is append-only — the source of truth for all charges and credits.
-
Each entry records:
amount
(positive = debit, negative = credit/refund)asset_code
- Links to
account
,provider
,service
, and/orrequest
-
From the ledger, balances can be reconstructed at any time.
3) How Billing Works — Step by Step
3.1 Setup
- Define services with default pricing & schemas.
- Define currencies and accepted currencies for services.
- Group services into service groups.
- Onboard providers (accounts) and associate them with service groups.
- Assign runners to services or groups for execution routing.
3.2 Subscription Creation
-
Customer creates a subscription:
- Chooses service or service group.
- Sets spending limit (amount, currency, period).
- Chooses secret.
- Selects allowed providers.
-
Subscription is stored in DB.
3.3 Request Execution
-
Customer sends a request to broker/API with:
subscription_id
- Target
service_id
- Payload + signature using account pubkey.
-
Broker:
-
Validates subscription active.
-
Validates provider allowed.
-
Checks spend limit hasn’t been exceeded for current period.
-
Resolves effective price via:
- Provider override (currency-specific)
- Service accepted currency override
- Service default
-
-
Broker selects runner from provider’s routing tables.
-
Runner executes request and returns result.
3.4 Billing Entry
-
When the request completes:
- If
per_second
mode → calculateduration × rate
. - If
per_request
mode → apply flat rate.
- If
-
Broker inserts ledger entry:
- Debit from customer account.
- Credit to provider account (can be separate entries or aggregated).
-
Ledger is append-only — historical billing cannot be altered.
3.5 Balance & Tracking
- Current balances are a sum of all ledger entries per account+currency.
- Spend limits are enforced by querying the ledger for the current period before each charge.
- Audit trails are guaranteed via immutable ledger entries.
4) Why This is Generic & Reusable
This design decouples:
- Service definition from provider pricing → multiple providers can sell the same service at different rates.
- Execution agents (runners) from service definitions → easy scaling or outsourcing of execution.
- Billing rules (per-second vs per-request) from subscription limits → same service can be sold in different billing modes.
- Currencies from the service → enabling multi-asset billing without changing the service definition.
Because of these separations, you can:
- Reuse the model for compute, APIs, storage, SaaS features, etc.
- Plug in different payment backends (on-chain, centralized payment processor, prepaid balance).
- Use the same model for internal cost allocation or external customer billing.
5) Potential Extensions
- Prepaid model: enforce that ledger debits can’t exceed balance.
- On-chain settlement: periodically export ledger entries to blockchain transactions.
- Discount models: percentage or fixed-amount discounts per subscription.
- Usage analytics: aggregate requests/billing by time period, provider, or service.
- SLAs: link billing adjustments to performance metrics in requests.
6) Conceptual Diagram — Billing Flow
sequenceDiagram
participant C as Customer Account
participant B as Broker/API
participant P as Provider
participant R as Runner
participant DB as Ledger DB
C->>B: Request(service, subscription, payload, secret)
B->>DB: Validate subscription & spend limit
DB-->>B: OK + effective pricing
B->>P: Forward request
P->>R: Execute request
R-->>P: Result + execution time
P->>B: Return result
B->>DB: Insert debit (customer) + credit (provider)
DB-->>B: Ledger updated
B-->>C: Return result + charge info