Skip to content

Wallets and Accounts

In FWallet, a wallet is the user-facing concept (something a person or business holds), while a ledger account is the bookkeeping mechanism behind it. Every wallet is backed by exactly one ledger account.

Wallets

A wallet represents a balance holder. You create wallets via the API:

Terminal window
curl -X POST https://api.fwallet.co.ug/v1/wallets \
-H "Content-Type: application/json" \
-H "X-API-Key: fwk_test_a1b2c3d4e5f6..." \
-H "Idempotency-Key: create-wallet-user-001-ugx" \
-d '{
"ownerType": "user",
"ownerId": "user-001",
"currencyCode": "UGX"
}'

Response:

{
"id": "wl_01JQHXYZ...",
"tenantId": "tn_01JQHXYZ...",
"ownerType": "user",
"ownerId": "user-001",
"currencyCode": "UGX",
"balance": "0",
"status": "active",
"createdAt": "2026-03-18T10:00:00.000Z"
}

Key Properties

Single-currency. Each wallet holds exactly one currency. If a user needs to hold both UGX and USD, they need two wallets.

Owner types. Wallets can be owned by:

  • user — an individual end-user
  • branch — a physical branch or agent location
  • company — a business entity

Unique per owner + currency. Within a tenant, there is at most one wallet per (ownerType, ownerId, currencyCode) combination.

Wallet States

StateCan ReceiveCan SendDescription
activeYesYesNormal operating state
frozenYesNoWallet can receive deposits but cannot initiate transfers or payouts

Freezing a wallet is useful for compliance holds, dispute resolution, or account review. The wallet continues to accumulate incoming funds but cannot move money out.

Ledger Accounts

Every wallet is backed by a ledger account. The ledger account is what appears in journal entries. When you see a journal line like:

DR wallet:user-001 100,000 UGX

The wallet:user-001 refers to the ledger account that backs the wallet with ownerId: "user-001" and currencyCode: "UGX".

The wallet’s balance is a materialized view of the net position of its ledger account (sum of credits minus sum of debits). This materialized balance is updated atomically with each journal entry posting, so it is always consistent with the ledger.

System Accounts

Each tenant automatically gets a set of system accounts that track money flows in and out of the system. These are not user-facing wallets — they are internal ledger accounts used for reconciliation.

AccountPurpose
momo-floatTracks funds received from mobile money providers. Debited when a MoMo deposit arrives, representing money the platform is now responsible for.
bank-floatTracks funds received via bank transfers. Debited when a verified bank deposit arrives.
suspenseHolds funds in an intermediate state (e.g., pending approval, unmatched bank slips).
revenue:feesAccumulates fee income. Credited whenever a fee is charged on a transfer or payout.

How System Accounts Participate in Entries

MoMo deposit (500,000 UGX):

DR momo-float:ug-mtn 500,000 UGX (external funds received)
CR wallet:user-001 500,000 UGX (user balance increased)

Transfer with fee (100,000 UGX + 2,000 UGX fee):

DR wallet:alice 100,000 UGX (sender debited)
DR wallet:alice 2,000 UGX (fee debited from sender)
CR wallet:bob 100,000 UGX (receiver credited)
CR revenue:fees 2,000 UGX (platform fee revenue)

Bank payout (200,000 UGX):

DR wallet:user-001 200,000 UGX (user balance decreased)
CR bank-float:ug-stanbic 200,000 UGX (funds sent to bank)

Balance Derivation

A wallet’s balance is always derivable from the ledger. The formula is:

balance = sum(credits to this account) - sum(debits from this account)

FWallet maintains a materialized balance for fast reads, but this can be verified against the ledger at any time through reconciliation. If the materialized balance ever disagrees with the ledger-derived balance, something has gone wrong at the system level.

Querying Wallets

List wallets for the current tenant:

Terminal window
curl https://api.fwallet.co.ug/v1/wallets \
-H "X-API-Key: fwk_test_a1b2c3d4e5f6..."

Response:

{
"data": [
{
"id": "wl_01JQHXYZ...",
"ownerType": "user",
"ownerId": "user-001",
"currencyCode": "UGX",
"balance": "500000",
"status": "active"
},
{
"id": "wl_02ABCDEF...",
"ownerType": "user",
"ownerId": "user-002",
"currencyCode": "UGX",
"balance": "100000",
"status": "active"
}
]
}

Get a single wallet by ID:

Terminal window
curl https://api.fwallet.co.ug/v1/wallets/wl_01JQHXYZ... \
-H "X-API-Key: fwk_test_a1b2c3d4e5f6..."