This page covers billing.io’s internal architecture. You don’t need to read this to integrate —
start with the Quickstart instead.
Non-custodial model
billing.io is non-custodial. Payments flow directly from customers to your wallets on-chain. billing.io orchestrates the payment flow and monitors the blockchain — fees are charged separately via Stripe, not deducted from payments.Core Domains
billing.io is organized into four core domains, each handling a distinct part of the payment lifecycle.Payments
Payments
The entry point for all money flow. Payment Methods define how you receive crypto (chain + token + wallet + rules).
Checkouts are individual payment sessions. Payment Links are shareable URLs that generate checkouts on the fly.
Subscriptions
Subscriptions
Recurring billing for your customers. Plans define the terms (amount, interval, token).
Subscriptions track the customer-plan relationship through a full lifecycle. Renewals handle each
billing period. Entitlements let you gate features per plan.
Payouts
Payouts
Non-custodial payout orchestration. You define Payout Intents, execute them from your own wallet,
and the chain-watcher verifies Settlements on-chain. Reconciliation matches intents to settlements.
Revenue
Revenue
Complete financial tracking. Revenue Events form an immutable ledger.
Accounting provides period summaries. Adjustments handle credits, debits, and chargebacks.
Multi-tenancy
Every resource is scoped to an organization viaorg_id. Row Level Security (RLS) enforces isolation at the database level — you can only access data belonging to your organization.
Environment Isolation
Every resource has anenvironment column set to either live or sandbox. These environments are completely isolated — sandbox data never appears in live views and vice versa.
| Feature | Live | Sandbox |
|---|---|---|
| Real blockchain transactions | Yes | Simulated |
| Stripe billing | Charged | Free |
| Payment confirmations | Chain-watcher | Simulated via API |
| Data isolation | Full | Full |
| API endpoints | Same | Same |
Chain-Watcher Integration
The chain-watcher is a Go service that monitors supported blockchains for transaction activity. It connects to billing.io through authenticated internal endpoints.Transaction Detected
The chain-watcher monitors on-chain activity for addresses associated with active checkouts and payout intents.
Confirmation Tracking
Once a transaction is detected, the chain-watcher tracks block confirmations until the required threshold is met.
Callback to billing.io
The chain-watcher calls internal endpoints (authenticated via
CHAIN_WATCHER_SECRET Bearer token) to report:- Payment confirmations —
POST /api/billing/record-usage - Settlement verification —
POST /api/billing/verify-settlement - Subscription renewals —
POST /api/billing/subscription-renewal
ID Prefix Convention
All billing.io resources use prefixed IDs for easy identification. IDs are generated with 24 random hex characters (12 bytes of entropy).| Entity | Prefix | Example |
|---|---|---|
| Payment Method | pm_ | pm_a1b2c3d4e5f6a1b2c3d4e5f6 |
| Customer | cus_ | cus_a1b2c3d4e5f6a1b2c3d4e5f6 |
| Subscription | sub_ | sub_a1b2c3d4e5f6a1b2c3d4e5f6 |
| Subscription Plan | plan_ | plan_a1b2c3d4e5f6a1b2c3d4e5f6 |
| Payout Intent | po_ | po_a1b2c3d4e5f6a1b2c3d4e5f6 |
| Settlement | stl_ | stl_a1b2c3d4e5f6a1b2c3d4e5f6 |
| Revenue Event | rev_ | rev_a1b2c3d4e5f6a1b2c3d4e5f6 |
| Adjustment | adj_ | adj_a1b2c3d4e5f6a1b2c3d4e5f6 |
| Payment Link | pl_ | pl_a1b2c3d4e5f6a1b2c3d4e5f6 |
| Checkout | chk_ | chk_a1b2c3d4e5f6a1b2c3d4e5f6 |
Prefixed IDs make it easy to identify resource types in logs, URLs, and support requests.
When contacting support, sharing the full prefixed ID helps us locate your resource instantly.
Working with prefixed IDs
Node.js
Environment-aware API calls
Node.js