Skip to main content

What are Wallets?

Wallets are digital accounts that hold customer balances in multiple currencies. With Fossapay’s wallet infrastructure, you can create customer wallets, hold balances in NGN and stablecoins, and manage internal ledgers seamlessly.
Wallets enable you to build neobank features like balance holding, peer-to-peer transfers, and multi-currency accounts without managing complex ledger infrastructure.

Key Features

Multi-Currency Support

Hold balances in NGN, USDT, USDC, and other stablecoins

Instant Transfers

Move money between wallets in milliseconds

Real-time Balance

Query balances and transaction history instantly

Double-Entry Ledger

Bank-grade accounting with full audit trail

Wallet Types

Customer Wallets

Individual wallets for your end users. Each wallet can hold multiple currencies.
{
  "type": "customer",
  "customer_id": "cus_abc123",
  "customer_name": "John Doe",
  "customer_email": "[email protected]",
  "currencies": ["NGN", "USDT", "USDC"]
}

Merchant Wallets

Business wallets for merchants or sellers on your platform.
{
  "type": "merchant",
  "business_name": "Acme Store",
  "business_email": "[email protected]",
  "currencies": ["NGN"]
}

System Wallets

Internal wallets for fees, commissions, or reserves.
{
  "type": "system",
  "purpose": "commission",
  "currencies": ["NGN", "USDT"]
}

Supported Currencies

CurrencyCodeTypeStatus
Nigerian NairaNGNFiatActive
Tether USDUSDTStablecoinActive
USD CoinUSDCStablecoinActive
Binance USDBUSDStablecoinComing Soon
Celo DollarcUSDStablecoinComing Soon

Wallet Operations

Crediting Wallets (Adding Money)

Add funds to a wallet from various sources: From Virtual Account Payment:
// Automatic via webhook when payment is received
// Webhook handler
app.post('/webhooks/fossapay', (req, res) => {
  const { event, data } = req.body;

  if (event === 'payment.received') {
    await fossapay.wallets.credit({
      wallet_id: data.metadata.wallet_id,
      amount: data.amount,
      currency: 'NGN',
      reference: data.transaction_id,
      narration: 'Wallet top-up'
    });
  }
});
Manual Credit:
await fossapay.wallets.credit({
  wallet_id: 'wal_xyz789',
  amount: 50000,
  currency: 'NGN',
  reference: 'admin-credit-001',
  narration: 'Promotional credit',
  metadata: {
    admin_id: 'admin_123',
    reason: 'promotion'
  }
});

Debiting Wallets (Removing Money)

Remove funds from a wallet: For Payout:
// Debit wallet and send money out
const debit = await fossapay.wallets.debit({
  wallet_id: 'wal_xyz789',
  amount: 25000,
  currency: 'NGN',
  reference: 'withdrawal-001',
  narration: 'Bank withdrawal'
});

// Process payout
await fossapay.payouts.create({
  amount: 25000,
  account_number: '0123456789',
  bank_code: '058',
  reference: debit.reference
});
For Fees:
await fossapay.wallets.debit({
  wallet_id: 'wal_customer',
  amount: 100,
  currency: 'NGN',
  reference: 'fee-txn-001',
  narration: 'Transaction fee'
});

Wallet-to-Wallet Transfers

Transfer funds between wallets instantly:
await fossapay.wallets.transfer({
  from_wallet_id: 'wal_sender',
  to_wallet_id: 'wal_receiver',
  amount: 10000,
  currency: 'NGN',
  reference: 'p2p-transfer-001',
  narration: 'Payment for services',
  metadata: {
    sender_name: 'John Doe',
    receiver_name: 'Jane Smith'
  }
});
Wallet transfers are atomic - either both debit and credit succeed, or neither happens.

Balance Inquiry

Check wallet balance in real-time:
const balance = await fossapay.wallets.getBalance({
  wallet_id: 'wal_xyz789',
  currency: 'NGN'
});

console.log(balance);
// {
//   "wallet_id": "wal_xyz789",
//   "currency": "NGN",
//   "available_balance": 150000,
//   "ledger_balance": 150000,
//   "pending_balance": 0
// }

Balance Types

Available Balance

Funds that can be used immediately for transactions.

Ledger Balance

Total balance including pending transactions.

Pending Balance

Funds that are in transit or on hold.
Ledger Balance = Available Balance + Pending Balance

Transaction History

Retrieve wallet transaction history:
const transactions = await fossapay.wallets.getTransactions({
  wallet_id: 'wal_xyz789',
  currency: 'NGN',
  start_date: '2024-01-01',
  end_date: '2024-01-31',
  limit: 50,
  offset: 0
});
Response:
{
  "wallet_id": "wal_xyz789",
  "currency": "NGN",
  "transactions": [
    {
      "id": "txn_001",
      "type": "credit",
      "amount": 50000,
      "balance_before": 100000,
      "balance_after": 150000,
      "narration": "Wallet top-up",
      "reference": "ref_001",
      "created_at": "2024-01-15T10:30:00Z"
    },
    {
      "id": "txn_002",
      "type": "debit",
      "amount": 25000,
      "balance_before": 150000,
      "balance_after": 125000,
      "narration": "Transfer to Jane",
      "reference": "ref_002",
      "created_at": "2024-01-16T14:20:00Z"
    }
  ],
  "pagination": {
    "total": 125,
    "limit": 50,
    "offset": 0
  }
}

Wallet Freezing

Freeze wallets to prevent transactions:
// Freeze wallet
await fossapay.wallets.freeze({
  wallet_id: 'wal_xyz789',
  reason: 'Suspicious activity detected'
});

// Unfreeze wallet
await fossapay.wallets.unfreeze({
  wallet_id: 'wal_xyz789',
  reason: 'Investigation complete'
});
Frozen wallets cannot send or receive funds until unfrozen.

Currency Conversion

Convert between currencies within wallets:
await fossapay.wallets.convert({
  wallet_id: 'wal_xyz789',
  from_currency: 'NGN',
  to_currency: 'USDT',
  amount: 100000,
  reference: 'conversion-001'
});
Conversion rates are based on real-time market rates with a small spread.

Wallet Limits

OperationLimit
Wallets per businessUnlimited
Currencies per wallet10
Minimum balance₦0 (or equivalent)
Maximum balance₦100,000,000 (or equivalent)
Daily transaction limit₦50,000,000 (or equivalent)
Transactions per second100

Best Practices

Always provide unique references to prevent duplicate transactions:
const reference = `txn_${Date.now()}_${userId}`;
Verify sufficient balance before attempting to debit:
const balance = await fossapay.wallets.getBalance({
  wallet_id: walletId,
  currency: 'NGN'
});

if (balance.available_balance >= amount) {
  // Proceed with debit
}
Always store transaction IDs returned by Fossapay for reconciliation and support.
Listen to wallet webhooks for real-time updates:
  • wallet.credited
  • wallet.debited
  • wallet.frozen
  • wallet.unfrozen

Common Use Cases

Neobank Wallet

// Create wallet when user signs up
const wallet = await fossapay.wallets.create({
  type: 'customer',
  customer_id: user.id,
  customer_name: user.fullName,
  currencies: ['NGN', 'USDT']
});

// Create virtual account for top-ups
const virtualAccount = await fossapay.virtualAccounts.create({
  customer_id: user.id,
  metadata: { wallet_id: wallet.id }
});

Marketplace Split Payments

// Receive payment
const payment = event.data; // from webhook

// Credit merchant (80%)
await fossapay.wallets.credit({
  wallet_id: merchantWalletId,
  amount: payment.amount * 0.8,
  currency: 'NGN'
});

// Credit platform fee (20%)
await fossapay.wallets.credit({
  wallet_id: platformWalletId,
  amount: payment.amount * 0.2,
  currency: 'NGN'
});

Peer-to-Peer Transfers

// User sends money to another user
await fossapay.wallets.transfer({
  from_wallet_id: senderWalletId,
  to_wallet_id: receiverWalletId,
  amount: 5000,
  currency: 'NGN',
  narration: 'Payment from friend'
});

Next Steps