Phase 1 billing is per organization. All apps in a workspace share organization_balances. The ledger is organization_credit_ledger; app_id on entries is attribution only.
Organization pool
When App A verifies a phone, credits are held/captured from the org pool — not a separate app wallet.
Account access vs plan
Account access (trial_outcome) is separate from your subscription/plan. Test keys (pk_test_/sk_test_) and live keys (pk_live_/sk_live_) both use real gateways and consume credits. Account access controls free trial credits and pending review — not whether test keys work.
- Register → verify email → risk evaluation → FULL_TRIAL or SANDBOX_ONLY (no free trial credits)
- Trial credits are granted after email verification — not when you create an app
- SANDBOX_ONLY: no free trial credits; pk_live_ works when the org has balance
- Subscribe to a plan or top up for ongoing credits regardless of trial outcome
Recharge
- Dashboard → Billing → Top up credits tab → create request → submit proof + reference
- Admin approves → CREDIT ledger entry linked to recharge_request
- Credit rate from platform config (billing.recharge), not hardcoded
Subscribe to a plan
- Dashboard → Billing → Subscribe to plan tab (or Pricing → choose plan →
/dashboard/billing?plan=…) - Pick a billing package + payment method → create subscription request → pay manually → upload proof + transaction reference
- Admin approves → package credits granted to org pool, app subscription activated, plan updated
- Same manual review flow as recharge; fulfillment uses
app_subscriptions+ org ledger
Ledger types
CREDIT, HOLD, RELEASE, CAPTURE. View org ledger: GET /v1/organizations/:id/billing/ledger.
Legacy app billing API
GET /v1/apps/:id/billing returns org balance for the app's organization (compatibility shim).
Dashboard
- Developer:
/dashboard/billing— org balance, subscribe to plan, top-up credits - Admin:
/admin/billing— trial/abuse, payment methods, recharge queue, subscription request queue
