Skip to content

Digital Wallet & Financial Ledger Module Documentation

6 min readUpdated: Sep 26, 2026
View as Markdown

Module Code: billing/client/wallet-ledger
Route: /portal/wallet
Backend Service: clientService.ts (ring2all-billing-api)
Database Tables: wallets, transactions, customers
Brand Purity: 100% White-Label Compliant (Ring2All Billing)


  1. Executive Summary & Financial Control
  2. Technical Architecture & Dual-Entry Ledger Pipeline
  3. 🎯 User Roles & Key Capabilities
  4. Visual Interface & Screen Breakdown
  5. Prepaid Balance, Credit Line & Emergency Floor
  6. Double-Entry Transaction Record Specification
  7. Database Schema & Data Dictionary
  8. Diagnostic CLI & Operational Playbooks
  9. Domain Glossary

The Digital Wallet & Financial Ledger module provides corporate clients with a centralized financial control center for prepaid telephony funds, postpaid credit limit extensions, and an immutable, double-entry audit trail of every financial transaction.

+-------------------------------------------------------------------------------+
| COMMERCIAL & OPERATIONAL IMPACT |
+-------------------------------------------------------------------------------+
| β€’ Zero Dropped Calls: Combines live prepaid balance with an emergency credit |
| limit to prevent sudden call termination during high-volume periods. |
| β€’ Instant Auditability: Every top-up, subscription charge, and outbound usage |
| debit is permanently recorded with before-and-after balance snapshots. |
| β€’ Autonomous Refills: Integrated quick top-up buttons allow immediate funding |
| via vaulted Stripe payment methods. |
| β€’ Multi-Currency Support: Real-time ISO currency precision down to 4 decimals.|
+-------------------------------------------------------------------------------+

2. Technical Architecture & Dual-Entry Ledger Pipeline

Section titled β€œ2. Technical Architecture & Dual-Entry Ledger Pipeline”

When telephony calls or monthly recurring charges occur, the billing engine performs atomic balance adjustments and commits immutable transaction rows:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Financial Event Dispatcher β”‚
β”‚ β€’ Customer Fund Top-Up (Stripe PaymentIntent Webhook) β”‚
β”‚ β€’ Monthly Subscription Sweep (Cron Engine) β”‚
β”‚ β€’ CDR Toll Rating Debit (Online Charging System) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό BEGIN TRANSACTION (Serializable)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Atomic Ledger Transaction Processor β”‚
β”‚ β”‚
β”‚ 1. SELECT balance, credit_limit FROM wallets WHERE customer_id = $id β”‚
β”‚ 2. Verify: (CurrentBalance + CreditLimit - DebitAmount) >= 0.00 β”‚
β”‚ 3. UPDATE wallets SET balance = balance + Delta, updated_at = NOW() β”‚
β”‚ 4. INSERT INTO transactions (wallet_id, type, amount, balance_after) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ COMMIT
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Real-Time Balance Cache Sync β”‚
β”‚ Kamailio SBC In-Memory Cache (htable: cust_balance) β”‚
β”‚ Portal UI WebSocket / Polling Refresh (WalletPage.tsx) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Access to ledger records and fund operations is governed by enterprise authorization roles:

User Role Access Level Primary Operational Capabilities
Corporate Treasurer / Financial Officer Full Financial Monitors corporate balance, executes one-click top-ups, audits transaction statements.
Enterprise Telecom Manager Operational Monitoring Verifies available calling credit to ensure trunk availability; configures low-balance email alerts.
Staff Accountant / Bookkeeper Reconciliation Downloads ledger CSVs to reconcile recurring subscription charges against bank merchant statements.
Customer Service Representative View Only Reviews past customer deposits and refunds to answer billing inquiries.

The wallet view presents real-time fund metrics alongside an itemized ledger table:

Digital Wallet & Transaction Ledger Overview

  • Current Balance Card: Prominently displays the total available prepaid funds ($145.50) in USD.
  • Credit Limit Card: Reflects approved overdraft headroom ($50.00) available before outbound trunk shutdown.
  • Effective Spending Power: Combined liquidity available for active concurrent calls.
  • Quick Top-Up Actions: One-click deposit triggers ($25, $50, $100, $250, or custom amount).
  • Transaction Ledger Table: Detailed itemization displaying date, reference ID, transaction type (topup, recurring_charge, usage_debit), gross amount, and resulting balance.

The Ring2All Billing core enforces a multi-tier balance protection protocol:

  1. Prepaid Tier: Active calls first consume the customer’s prepaid balance (wallets.balance).
  2. Credit Line Tier: If the balance reaches $0.00, calls continue uninterrupted against the authorized credit_limit.
  3. Emergency Floor (Hard Cutoff): When total debt exceeds credit_limit, the SBC rejects new outbound call attempts with SIP/2.0 402 Payment Required.

Every row in the transactions ledger contains deterministic accounting data:

Transaction Field Example Value Description
Reference ID TX-891024 Unique alphanumeric tracking identifier.
Type topup Transaction category (topup, subscription, usage, refund).
Amount +$100.00 Net credit (green) or debit (red) applied to wallet.
Balance After $145.50 Exact wallet balance snapshot immediately following the transaction.
Status completed Processing state (pending, completed, failed, reversed).

CREATE TABLE public.wallets (
id BIGSERIAL PRIMARY KEY,
uuid UUID NOT NULL DEFAULT gen_random_uuid(),
customer_id BIGINT NOT NULL UNIQUE REFERENCES customers(id) ON DELETE CASCADE,
currency VARCHAR(3) NOT NULL DEFAULT 'USD',
balance NUMERIC(12,4) NOT NULL DEFAULT 0.0000,
credit_limit NUMERIC(12,4) NOT NULL DEFAULT 0.0000,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE public.transactions (
id BIGSERIAL PRIMARY KEY,
uuid UUID NOT NULL DEFAULT gen_random_uuid(),
customer_id BIGINT NOT NULL REFERENCES customers(id) ON DELETE CASCADE,
wallet_id BIGINT NOT NULL REFERENCES wallets(id) ON DELETE CASCADE,
type VARCHAR(30) NOT NULL,
amount NUMERIC(12,4) NOT NULL,
balance_after NUMERIC(12,4) NOT NULL,
currency VARCHAR(3) NOT NULL DEFAULT 'USD',
description TEXT,
reference_id VARCHAR(100),
status VARCHAR(20) NOT NULL DEFAULT 'completed',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Audit query index
CREATE INDEX idx_transactions_customer_time ON transactions (customer_id, created_at DESC);

Terminal window
su - postgres -c "psql -d ss_billing -c \"
SELECT w.balance, w.credit_limit, t.type, t.amount, t.balance_after, t.created_at
FROM wallets w
JOIN transactions t ON t.wallet_id = w.id
WHERE w.customer_id = 5
ORDER BY t.created_at DESC;
\""

  • Double-Entry Ledger: Bookkeeping architecture where every balance mutation records both credit/debit amount and resultant state.
  • Effective Spending Power: Sum of available positive balance plus approved credit limit.
  • Credit Limit: Maximum allowed negative balance before telecom services are suspended.