Skip to main content

Traditional Wallet API - Complete Wallet Management

The Traditional Wallet API provides comprehensive wallet management capabilities for fiat currencies, digital transactions, and cross-border transfers. Built for enterprise-grade financial applications with PSP integration, KYC compliance, and multi-currency support.

🎯 What Can You Manage?

Your complete wallet ecosystem with these powerful tools:

  • Wallet Operations: Create, activate, topup, and balance management
  • Transfer Systems: Internal, cross-PSP, and cross-border transfers
  • Currency Conversion: Multi-currency support with real-time rates
  • Payin/Offramp: VA generation, bank transfers, and fee calculations
  • Admin Controls: Wallet activation, key management, and oversight
  • Compliance: KYC integration, transaction limits, and audit trails

🧩 Your Wallet Building Blocks

💳 Core Wallet Blocks

  • POST /wallet/create - Create new wallet with KYC integration
  • POST /wallet/topup - Top-up with Firebase OTP (Mobile)
  • POST /wallet/topup/verify - Top-up with manual OTP (Web)
  • GET /wallet/balance - Check primary wallet balance
  • GET /wallet/balances - Check all user wallet balances
  • POST /wallet/mock_activate - Manual wallet activation

🔄 Transfer & Conversion Blocks

  • POST /wallet/transfer - Internal wallet transfers
  • POST /wallet/convert - Currency conversion
  • POST /wallet/cross_psp_transfer - Cross-PSP provider transfers
  • POST /wallet/cross_border - Cross-border bank transfers
  • POST /wallet/withdraw - Bank withdrawal operations

💱 Payin/Offramp Blocks

  • POST /wallet/payin/quote - Calculate payin fees and totals
  • GET /wallet/payins/:user_id - List pending payins
  • POST /wallet/offramp/quote - Calculate offramp fees
  • GET /wallet/offramps/:user_id - Offramp transaction history

🔧 Admin & Management Blocks

  • GET /wallet/admin/detail - Admin wallet overview
  • POST /wallet/admin/update_keys - Update wallet keys
  • GET /wallet/user/:user_id - User wallet management
  • GET /wallet/prefunded-accounts - Prefunded account management

🏗️ Common Wallet Patterns

Pattern 1: "I want to create and fund a new wallet"

User registration → createWallet → topUpWallet → checkBalance

Use: /wallet/create/wallet/topup/wallet/balance

Pattern 2: "I want to transfer money between wallets"

Balance check → internalTransfer → Confirmation

Use: /wallet/balance/wallet/transfer

Pattern 3: "I want to send money abroad"

Currency check → crossBorderTransfer → Bank processing

Use: /wallet/cross_border

Pattern 4: "I want to convert currencies"

Rate check → convertCurrency → Balance update

Use: /wallet/convert


🔧 Core Wallet Operations

Create New Wallet

POST/api/wallet/create

Create New Wallet

Create a new wallet for a user with automatic PSP integration and KYC compliance checking. Supports multiple currencies based on country code and includes automatic limit setting for non-KYC users.

Parameters

user_idnumberrequired

User ID who will own the wallet

country_codestringrequired

Country code for wallet currency (ID, SG, AU, etc.)

Request Body

{
  "user_id": 123,
  "country_code": "ID"
}

Response

201Wallet created successfully
{
  "success": true,
  "message": "Wallet created successfully!",
  "wallet_id": "wallet_456789",
  "wallet_code": "WL-202401-0001-A1B2",
  "country_code": "ID",
  "status": "ACTIVE",
  "is_limited": false,
  "balance_limit": null,
  "activation_info": "Wallet has been automatically activated by the system (MOCK_MODE)"
}
400User already has wallet or invalid data
{
  "error": "User already has a wallet in the country ID."
}
500Failed to create wallet
{
  "success": false,
  "error": "Failed to create wallet",
  "details": "PSP integration error"
}

Top-Up Wallet (Mobile - Firebase OTP)

POST/api/wallet/topup

Top-Up Wallet with Firebase OTP (Mobile Version)

Mobile-optimized top-up with Firebase push notification OTP. Two-step process: first call sends OTP, second call with OTP code completes the transaction. Includes PSP integration for real-time balance updates.

Parameters

wallet_idstringrequired

Wallet ID to top-up

amountnumberrequired

Amount to top-up

currencystringrequired

Currency code (IDR, SGD, USD, etc.)

firebase_tokenstring

Firebase token for push notification OTP (Step 1 only)

otp_codestring

OTP code for verification (Step 2 only)

Request Body

{
  "wallet_id": "wallet_456789",
  "amount": 100000,
  "currency": "IDR",
  "firebase_token": "firebase_token_here"
}

Response

201Top-up successful after OTP verification (Step 2)
{
  "status": "success",
  "message": "Top-up successful!",
  "transaction": {
    "transaction_id": "TOPUP-1705123456-A1B2",
    "wallet_id": "wallet_456789",
    "amount": 100000,
    "currency": "IDR",
    "status": "SUCCESS_RECEIVED",
    "provider": "DOKU_PSP"
  }
}
202OTP sent for verification (Step 1)
{
  "message": "OTP sent to your device",
  "otp_code": "123456"
}
401Invalid OTP code
{
  "error": "Invalid OTP code",
  "details": "OTP code expired or incorrect"
}
500Top-up failed
{
  "error": "Failed to process top-up",
  "details": "PSP service unavailable"
}

Top-Up Wallet (Web - Manual OTP)

POST/api/wallet/topup/verify

Top-Up Wallet with Manual OTP (Web Version)

Web-optimized top-up with manual OTP verification. Single-step process where OTP is provided directly. Designed for web applications where users manually enter OTP codes.

Parameters

wallet_idstringrequired

Wallet ID to top-up

otp_codestringrequired

OTP code for verification

Request Body

{
  "wallet_id": "wallet_456789",
  "otp_code": "123456"
}

Response

201Top-up successful after OTP verification
{
  "status": "success",
  "message": "Top-up successful!",
  "transaction": {
    "transaction_id": "TOPUP-1705123456-A1B2",
    "wallet_id": "wallet_456789",
    "amount": 100000,
    "currency": "IDR",
    "status": "SUCCESS_RECEIVED",
    "provider": "DOKU_PSP"
  }
}
401Invalid OTP code
{
  "error": "Invalid OTP code",
  "details": "OTP verification failed"
}
404Wallet not found or inactive
{
  "error": "Wallet not found or inactive"
}
500Top-up failed
{
  "error": "Top-up failed",
  "details": "PSP integration error"
}

Check Wallet Balance

GET/api/wallet/balance

Check Primary Wallet Balance

Get balance information for user's primary wallet using ledger-based calculation. Returns total received, total spent, and current balance with transaction breakdown.

Response

200Balance retrieved successfully
{
  "user_id": 123,
  "wallets": [
    {
      "wallet_id": "wallet_456789",
      "currency": "IDR",
      "total_received": 500000,
      "total_spent": 150000,
      "balance": 350000
    },
    {
      "wallet_id": "wallet_789012",
      "currency": "SGD",
      "total_received": 1000,
      "total_spent": 200,
      "balance": 800
    }
  ]
}
404No active wallet found
{
  "error": "No active wallet found for this user."
}
500Failed to get balance
{
  "error": "Failed to retrieve balance data",
  "details": "Database connection error"
}

Check All Wallet Balances

GET/api/wallet/balances

Check All User Wallet Balances

Get balance information for all user's active wallets across different currencies and PSP providers.

Response

200All balances retrieved successfully
{
  "user_id": 123,
  "wallets": [
    {
      "wallet_id": "wallet_456789",
      "currency": "IDR",
      "balance": 350000
    },
    {
      "wallet_id": "wallet_789012",
      "currency": "SGD",
      "balance": 800
    },
    {
      "wallet_id": "wallet_345678",
      "currency": "USD",
      "balance": 150
    }
  ]
}
404No active wallets found
{
  "error": "User has no active wallets."
}
500Failed to get balances
{
  "error": "Failed to get balances",
  "details": "PSP service error"
}

🔄 Transfer Operations

Internal Wallet Transfer

POST/api/wallet/transfer

Internal Wallet Transfer

Transfer funds between wallets within the same PSP provider. Supports same-currency transfers with atomic transaction processing and balance validation.

Parameters

from_wallet_idstringrequired

Source wallet ID

to_wallet_idstringrequired

Destination wallet ID

amountnumberrequired

Transfer amount

notestring

Optional transfer note

Request Body

{
  "from_wallet_id": "wallet_456789",
  "to_wallet_id": "wallet_789012",
  "amount": 50000,
  "note": "Payment for services"
}

Response

200Transfer successful
{
  "message": "Internal Transfer Successful",
  "transaction_id_transfer": "TX-wallet_456789-wallet_789012-50000-1705123456-FROM-wallet_456789",
  "transaction_id_receive": "TX-wallet_456789-wallet_789012-50000-1705123456-TO-wallet_789012",
  "from_wallet_balance_after": 300000,
  "to_wallet_balance_after": 850000
}
400Invalid transfer or insufficient balance
{
  "error": "Insufficient balance"
}
404Wallet not found
{
  "error": "Sender or receiver wallet not found"
}
500Transfer failed
{
  "error": "Failed to process transfer",
  "details": "PSP service error"
}

Currency Conversion

POST/api/wallet/convert

Currency Conversion

Convert funds between different currencies using real-time exchange rates. Supports multiple currency pairs with transparent fee structure.

Parameters

user_idnumberrequired

User ID performing conversion

amountnumberrequired

Amount to convert

from_currencystringrequired

Source currency code

to_currencystringrequired

Target currency code

Request Body

{
  "user_id": 123,
  "amount": 1000000,
  "from_currency": "IDR",
  "to_currency": "SGD"
}

Response

200Conversion successful
{
  "message": "Conversion successful",
  "data": {
    "original_amount": 1000000,
    "converted_amount": 90.09,
    "exchange_rate": 11100,
    "from_currency": "IDR",
    "to_currency": "SGD",
    "provider": "WISE",
    "conversion_fee": 5000,
    "reference_id": "CNV-1705123456-A1B2"
  }
}
400Invalid conversion parameters
{
  "error": "from_currency and to_currency cannot be the same"
}
500Conversion failed
{
  "error": "Conversion failed",
  "details": "Exchange rate unavailable"
}

Cross-Border Transfer

POST/api/wallet/cross_border

Cross-Border Bank Transfer

Transfer funds from wallet to international bank accounts with automatic currency conversion and multi-PSP routing support.

Parameters

from_wallet_idstringrequired

Source wallet ID

amountnumberrequired

Transfer amount

to_currencystringrequired

Target currency for bank transfer

bank_accountobjectrequired

Bank account details for transfer

notestring

Optional transfer note

Request Body

{
  "from_wallet_id": "wallet_456789",
  "amount": 500000,
  "to_currency": "SGD",
  "bank_account": {
    "account_number": "1234567890",
    "account_name": "John Doe",
    "bank_name": "DBS Bank",
    "bank_code": "DBS",
    "country_code": "SG"
  },
  "note": "Payment for invoice #INV-2024-001"
}

Response

200Cross-border transfer successful
{
  "message": "Cross Border Offramp Success",
  "transaction_id_transfer": "CBT-wallet_456789-500000-1705123456-BANK",
  "from_currency": "IDR",
  "to_currency": "SGD",
  "platform_fee": 25000,
  "partner_fee": 10000,
  "converted_amount": 450.45,
  "bank_transfer_status": "SUCCESS_RECEIVED",
  "bank_transaction_id": "BT-SGD-1705123456"
}
400Invalid transfer parameters or insufficient funds
{
  "error": "Insufficient IDR funds"
}
404Wallet not found
{
  "error": "Wallet not found"
}
500Transfer failed
{
  "error": "Failed cross-border offramp processing",
  "details": "Bank service unavailable"
}

Cross-PSP Transfer

POST/api/wallet/cross_psp_transfer

Cross-PSP Provider Transfer

Transfer funds between wallets using different PSP providers with automatic currency conversion and fallback routing.

Parameters

from_wallet_idstringrequired

Source wallet ID

to_wallet_idstringrequired

Destination wallet ID

amountnumberrequired

Transfer amount

notestring

Optional transfer note

Request Body

{
  "from_wallet_id": "wallet_456789",
  "to_wallet_id": "wallet_789012",
  "amount": 100000,
  "note": "Cross-PSP payment"
}

Response

200Cross-PSP transfer successful
{
  "message": "Cross PSP Transfer successful",
  "transaction_id_transfer": "CBT-wallet_456789-wallet_789012-100000-1705123456-FROM-wallet_456789",
  "transaction_id_receive": "CBT-wallet_456789-wallet_789012-100000-1705123456-TO-wallet_789012",
  "from_currency": "IDR",
  "to_currency": "SGD",
  "converted_amount": 90.09,
  "logSteps": [
    {
      "step": 1,
      "description": "Convert IDR to USDC via Circle",
      "provider": "CIRCLE",
      "amount": 100000,
      "converted_amount": 67.56,
      "exchange_rate": 1480.5
    },
    {
      "step": 2,
      "description": "Convert USDC to SGD via Wise",
      "provider": "WISE",
      "amount": 67.56,
      "converted_amount": 90.09,
      "exchange_rate": 1.334
    }
  ]
}
400Invalid transfer or same PSP
{
  "error": "Cross PSP Transfer only allowed for different PSP providers"
}
500Transfer failed
{
  "error": "Failed to process cross PSP transfer",
  "details": "Currency conversion failed"
}

💱 Payin/Offramp Operations

Get Payin Quote

POST/api/wallet/payin/quote

Calculate Payin Quote with Fees

Calculate total fees and amount for payin operations including platform fees, partner fees, and optional fee coverage.

Parameters

wallet_idstringrequired

Wallet ID for payin

amountnumberrequired

Base payin amount

currencystringrequired

Currency code

cover_feeboolean

Whether to include fees in total (default: true)

Request Body

{
  "wallet_id": "wallet_456789",
  "amount": 100000,
  "currency": "IDR",
  "cover_fee": true
}

Response

200Quote calculated successfully
{
  "quote_id": "QT-1705123456-9999",
  "currency": "IDR",
  "amount": 100000,
  "cover_fee": true,
  "total_with_fee": "105500.00",
  "platform_fee": "3000.00",
  "partner_fee": "2500.00"
}
400Missing required parameters
{
  "error": "wallet_id, amount, and currency are required"
}
404Wallet not found
{
  "error": "Wallet not found or inactive"
}
500Quote calculation failed
{
  "error": "Failed to calculate VA quote"
}

Get Pending Payins

GET/api/wallet/payins/:user_id

Get User's Pending Payins

Retrieve all pending payin transactions for a specific user including VA details, expiry times, and fee breakdowns.

Parameters

user_idstringrequired

User ID to get pending payins for

Response

200Pending payins retrieved successfully
{
  "payins": [
    {
      "transaction_id": "TOPUP-1705123456-A1B2",
      "wallet_id": "wallet_456789",
      "wallet_number": "WL-202401-0001-A1B2",
      "amount": 100000,
      "currency_from": "IDR",
      "va_number": "1234567890123456",
      "va_status": "ACTIVE",
      "va_expired_at": "2024-01-15T23:59:59Z",
      "platform_fee": 3000,
      "partner_fee": 2500,
      "bank_name": "Bank Mandiri"
    }
  ]
}
500Failed to get payins
{
  "error": "Failed to retrieve payin list"
}

Get Offramp Quote

POST/api/wallet/offramp/quote

Calculate Offramp Quote with Fees

Calculate fees and total amount for offramp operations to bank accounts.

Parameters

wallet_idstringrequired

Wallet ID for offramp

amountnumberrequired

Offramp amount

cover_feeboolean

Whether to include fees in calculation (default: true)

Request Body

{
  "wallet_id": "wallet_456789",
  "amount": 200000,
  "cover_fee": true
}

Response

200Offramp quote calculated successfully
{
  "quote_id": "OFFRAMP-QT-1705123456-9999",
  "currency": "IDR",
  "amount": 200000,
  "cover_fee": true,
  "total_with_fee": 211000,
  "platform_fee": 6000,
  "partner_fee": 5000
}
400Missing required parameters
{
  "error": "wallet_id and amount are required"
}
404Wallet not found
{
  "error": "Wallet not found or inactive"
}
500Quote calculation failed
{
  "error": "Failed to calculate off-ramp quote"
}

Get Offramp History

GET/api/wallet/offramps/:user_id

Get User's Offramp History

Retrieve offramp transaction history for a specific user including bank transfer details, fees, and status updates.

Parameters

user_idstringrequired

User ID to get offramp history for

Response

200Offramp history retrieved successfully
{
  "offramps": [
    {
      "transaction_id": "CBT-wallet_456789-200000-1705123456-BANK",
      "transaction_date": "2024-01-15T10:30:00Z",
      "wallet_id": "wallet_456789",
      "wallet_code": "WL-202401-0001-A1B2",
      "currency_from": "IDR",
      "currency_to": "SGD",
      "amount": 200000,
      "converted_amount": 180.18,
      "bank_name": "DBS Bank",
      "platform_fee": 6000,
      "partner_fee": 5000,
      "settlement_status": "SUCCESS_RECEIVED",
      "settled_date": "2024-01-15T10:35:00Z",
      "destination_reference": "CBT-wallet_456789-200000-1705123456-BANK"
    }
  ]
}
500Failed to get offramp history
{
  "error": "Failed to retrieve offramp data"
}

🔧 Admin Operations

Get Admin Wallet Detail

GET/api/wallet/admin/detail

Get Admin Wallet Overview

Retrieve comprehensive wallet information for admin users including balance breakdowns, transaction summaries, and wallet status across all currencies.

Response

200Admin wallet details retrieved successfully
{
  "message": "Wallet details found.",
  "wallets": [
    {
      "wallet_id": "wallet_456789",
      "user_id": 123,
      "wallet_code": "WL-202401-0001-A1B2",
      "public_key": "PUB-abcd1234...",
      "wallet_status": "ACTIVE",
      "currency": "IDR",
      "created_at": "2024-01-01T00:00:00Z",
      "total_received": 1000000,
      "total_spent": 350000,
      "balance": 650000
    },
    {
      "wallet_id": "wallet_789012",
      "user_id": 123,
      "wallet_code": "WL-202401-0002-B3C4",
      "public_key": "PUB-efgh5678...",
      "wallet_status": "ACTIVE",
      "currency": "SGD",
      "created_at": "2024-01-02T00:00:00Z",
      "total_received": 2000,
      "total_spent": 500,
      "balance": 1500
    }
  ]
}
404No wallets found for admin
{
  "error": "No wallets found for this user."
}
500Failed to get admin wallet details
{
  "error": "Failed to retrieve wallet details"
}

Get Wallets by User ID

GET/api/wallet/user/:user_id

Get User Wallets (Admin View)

Administrative view of all wallets belonging to a specific user including KYC status, limits, and detailed balance information.

Parameters

user_idstringrequired

User ID to get wallets for

Response

200User wallets retrieved successfully
{
  "wallets": [
    {
      "wallet_id": "wallet_456789",
      "wallet_code": "WL-202401-0001-A1B2",
      "currency": "IDR",
      "wallet_status": "ACTIVE",
      "created_at": "2024-01-01T00:00:00Z",
      "is_limited": false,
      "balance_limit": null,
      "psp_id": "DOKU_PSP",
      "public_key": "PUB-abcd1234...",
      "country_code": "ID",
      "balance": 650000,
      "total_received": 1000000,
      "total_spent": 350000,
      "is_kyc_verified": true,
      "limit_info": null
    }
  ]
}
500Failed to get wallet data
{
  "error": "Failed to get wallet data"
}

Mock Activate Wallet

Deprecated Endpoint

This endpoint has been deprecated and is no longer available. Wallet activation is now handled automatically during wallet creation. For development/testing purposes, wallets are auto-activated when MOCK_MODE is enabled.

POST/api/wallet/mock_activate

Mock Activate Wallet (Development)

Manually activate wallet in mock/development mode without PSP integration. Only available when MOCK_MODE environment variable is enabled.

Parameters

wallet_idstringrequired

Wallet ID to activate

country_codestringrequired

Country code for reference

Request Body

{
  "wallet_id": "wallet_456789",
  "country_code": "ID"
}

Response

200Wallet activated successfully
{
  "message": "Wallet wallet_456789 successfully activated.",
  "wallet_id": "wallet_456789",
  "country_code": "ID",
  "status": "ACTIVE",
  "currency": "IDR",
  "psp_id": "DOKU_PSP"
}
400Wallet already active
{
  "error": "Wallet is already active."
}
403Mock mode not enabled
{
  "error": "Wallet activation can only be performed in MOCK mode."
}
404Wallet not found
{
  "error": "Wallet not found."
}
500Activation failed
{
  "error": "Failed to activate wallet"
}

🚀 Complete Wallet Management Workflows

Workflow 1: New User Onboarding

// Complete new user wallet setup
async function onboardNewUser(userId, countryCode) {
console.log('Starting user onboarding...');

// Step 1: Create wallet
const wallet = await brdzSDK.wallet.createWallet({
user_id: userId,
country_code: countryCode
});

console.log(`Wallet created: ${wallet.wallet_id}`);

// Step 2: Activate if in mock mode
if (process.env.NODE_ENV === 'development') {
await brdzSDK.wallet.mockActivateWallet({
wallet_id: wallet.wallet_id,
country_code: countryCode
});
console.log('Wallet activated (mock mode)');
}

// Step 3: Initial balance check
const balance = await brdzSDK.wallet.checkBalance();
console.log(`Initial balance: ${balance.wallets[0].balance}`);

return {
wallet_id: wallet.wallet_id,
status: wallet.status,
currency: wallet.currency,
balance: balance.wallets[0].balance
};
}

Workflow 2: Mobile vs Web Top-Up

// Mobile top-up workflow (Firebase OTP)
async function mobileTopUp(walletId, amount, currency, firebaseToken) {
console.log('Starting mobile top-up workflow...');

// Step 1: Request OTP via Firebase
const otpRequest = await brdzSDK.wallet.topUpWallet({
wallet_id: walletId,
amount: amount,
currency: currency,
firebase_token: firebaseToken
});

console.log('OTP sent via Firebase push notification');

// Step 2: User receives push notification and provides OTP
// This would be handled by your mobile app's push notification handler
const otpCode = await waitForUserOTPInput(); // Your implementation

// Step 3: Complete top-up with OTP
const topupResult = await brdzSDK.wallet.topUpWallet({
wallet_id: walletId,
amount: amount,
currency: currency,
otp_code: otpCode
});

return topupResult;
}

// Web top-up workflow (Manual OTP)
async function webTopUp(walletId, otpCode) {
console.log('Starting web top-up workflow...');

// Single step: Verify OTP and complete top-up
// Amount and currency are retrieved from stored OTP session
const topupResult = await brdzSDK.wallet.verifyTopUpOTP({
wallet_id: walletId,
otp_code: otpCode
});

console.log(`Web top-up successful: ${topupResult.transaction.transaction_id}`);

return topupResult;
}

Workflow 3: Cross-Border Payment

// Complete cross-border payment workflow
async function crossBorderPayment(fromWalletId, amount, targetCurrency, bankAccount) {
console.log('Starting cross-border payment...');

// Step 1: Check wallet balance
const balance = await brdzSDK.wallet.checkBalance();
const senderWallet = balance.wallets.find(w => w.wallet_id === fromWalletId);

if (senderWallet.balance < amount) {
throw new Error('Insufficient balance for cross-border transfer');
}

// Step 2: Get offramp quote
const quote = await brdzSDK.wallet.getOfframpQuote({
wallet_id: fromWalletId,
amount: amount,
cover_fee: true
});

console.log(`Cross-border quote: ${quote.total_with_fee} ${senderWallet.currency}`);

// Step 3: Execute cross-border transfer
const transfer = await brdzSDK.wallet.crossBorderTransfer({
from_wallet_id: fromWalletId,
amount: amount,
to_currency: targetCurrency,
bank_account: bankAccount,
note: 'International payment'
});

console.log(`Bank transfer initiated: ${transfer.bank_transaction_id}`);
console.log(`Conversion: ${transfer.from_currency}${transfer.to_currency}`);
console.log(`Converted amount: ${transfer.converted_amount} ${transfer.to_currency}`);

return transfer;
}

Workflow 4: Multi-Currency Management

// Multi-currency wallet management
async function manageMutliCurrency(userId) {
console.log('Managing multi-currency wallets...');

// Step 1: Check all wallets
const allBalances = await brdzSDK.wallet.checkAllBalances();
console.log(`User has ${allBalances.wallets.length} wallets`);

// Step 2: Find wallet with highest balance
const richestWallet = allBalances.wallets.reduce((prev, current) =>
prev.balance > current.balance ? prev : current
);

console.log(`Richest wallet: ${richestWallet.currency} with ${richestWallet.balance}`);

// Step 3: Currency conversion if needed
if (richestWallet.currency !== 'USD' && richestWallet.balance > 1000) {
const conversion = await brdzSDK.wallet.convertCurrency({
user_id: userId,
amount: richestWallet.balance * 0.1, // Convert 10%
from_currency: richestWallet.currency,
to_currency: 'USD'
});

console.log(`Converted ${conversion.data.original_amount} ${conversion.data.from_currency} to ${conversion.data.converted_amount} ${conversion.data.to_currency}`);
}

// Step 4: Get admin view if user is admin
if (userId === 'admin_user_id') {
const adminDetail = await brdzSDK.wallet.getAdminWalletDetail();

console.log('Admin wallet overview:');
adminDetail.wallets.forEach(wallet => {
console.log(` ${wallet.currency}: ${wallet.balance} (Status: ${wallet.wallet_status})`);
});
}

return {
total_wallets: allBalances.wallets.length,
richest_wallet: richestWallet,
total_value_usd: calculateTotalUSDValue(allBalances.wallets)
};
}

🎯 When to Use Which API

Wallet Creation & Setup

  • New user: POST /wallet/create
  • Development testing: POST /wallet/mock_activate
  • Admin oversight: GET /wallet/user/:user_id

Funding Operations

  • Mobile app: POST /wallet/topup (Firebase OTP)
  • Web app: POST /wallet/topup/verify (Manual OTP)
  • Calculate costs: POST /wallet/payin/quote
  • Track pending: GET /wallet/payins/:user_id

Transfer Operations

  • Same PSP: POST /wallet/transfer
  • Different PSP: POST /wallet/cross_psp_transfer
  • To bank: POST /wallet/cross_border
  • Currency change: POST /wallet/convert

Balance Management

  • Quick check: GET /wallet/balance
  • All wallets: GET /wallet/balances
  • Admin view: GET /wallet/admin/detail

Withdrawal Operations

  • Calculate costs: POST /wallet/offramp/quote
  • Bank withdrawal: POST /wallet/withdraw
  • Track history: GET /wallet/offramps/:user_id

💡 Pro Tips for Wallet Management

Mobile vs Web Integration

// Platform-specific top-up handling
class WalletManager {
static async topUp(walletId, amount, currency, platform = 'web') {
if (platform === 'mobile') {
// Mobile: Use Firebase OTP flow
return this.mobileTopUp(walletId, amount, currency);
} else {
// Web: Assume OTP is already obtained through other means
return this.webTopUp(walletId, otpCode);
}
}

static async mobileTopUp(walletId, amount, currency) {
// Step 1: Request OTP
const otpRequest = await brdzSDK.wallet.topUpWallet({
wallet_id: walletId,
amount,
currency,
firebase_token: await getFirebaseToken()
});

// Step 2: Wait for user to provide OTP from push notification
const otpCode = await this.waitForOTPInput();

// Step 3: Complete with OTP
return await brdzSDK.wallet.topUpWallet({
wallet_id: walletId,
amount,
currency,
otp_code: otpCode
});
}

static async webTopUp(walletId, otpCode) {
// Single step for web
return await brdzSDK.wallet.verifyTopUpOTP({
wallet_id: walletId,
otp_code: otpCode
});
}
}

Error Handling

// Robust error handling for wallet operations
async function safeWalletOperation(operation) {
try {
return await operation();
} catch (error) {
if (error.message.includes('Insufficient balance')) {
console.log('Insufficient funds - consider topping up wallet');
return { error: 'insufficient_funds', suggestion: 'topup_required' };
} else if (error.message.includes('not found')) {
console.log('Wallet not found - check wallet ID');
return { error: 'wallet_not_found', suggestion: 'verify_wallet_id' };
} else if (error.message.includes('PSP')) {
console.log('PSP service issue - try again later');
return { error: 'psp_unavailable', suggestion: 'retry_later' };
} else if (error.message.includes('Invalid OTP')) {
console.log('OTP verification failed');
return { error: 'invalid_otp', suggestion: 'request_new_otp' };
} else {
console.error('Unexpected wallet error:', error.message);
throw error;
}
}
}

Fee Calculation

// Calculate total costs before operations
async function calculateTransactionCosts(walletId, amount, operation = 'payin') {
const quote = operation === 'payin'
? await brdzSDK.wallet.getPayinQuote({ wallet_id: walletId, amount, currency: 'IDR' })
: await brdzSDK.wallet.getOfframpQuote({ wallet_id: walletId, amount });

return {
base_amount: quote.amount,
platform_fee: parseFloat(quote.platform_fee),
partner_fee: parseFloat(quote.partner_fee),
total_cost: parseFloat(quote.total_with_fee),
fee_percentage: ((parseFloat(quote.platform_fee) + parseFloat(quote.partner_fee)) / quote.amount * 100).toFixed(2)
};
}

🔐 Authentication & Authorization

All wallet endpoints require authentication:

// Configure authentication
const config = await brdzSDK.config;
config.setToken('your-jwt-token');
config.setApiKey('your-api-key');

// User-level operations
await brdzSDK.wallet.createWallet({ user_id: 123, country_code: "ID" });
await brdzSDK.wallet.checkBalance();
await brdzSDK.wallet.topUpWallet(data);

// Admin-level operations (requires admin role)
await brdzSDK.wallet.getAdminWalletDetail();
await brdzSDK.wallet.updateWalletKeys(data);
await brdzSDK.wallet.getWalletsByUserId("123");

🌍 Supported Currencies & Countries

Currency & Country Support

Multi-currency wallet support based on country PSP availability:

  • IDR (Indonesia) - Country code: ID, PSP: DOKU
  • SGD (Singapore) - Country code: SG, PSP: Wise/Airwallex
  • USD (United States) - Country code: US, PSP: Circle/Wise
  • AUD (Australia) - Country code: AU, PSP: Wise
  • VND (Vietnam) - Country code: VN, PSP: Local partners
  • INR (India) - Country code: IN, PSP: Local partners

Transfer Types Support

  • Internal Transfer: Same PSP, same currency only
  • Cross-PSP Transfer: Different PSP, requires currency conversion
  • Cross-Border Transfer: Wallet to international bank account
  • Currency Conversion: Multi-currency support with real-time rates

Fee Structure

  • Platform Fee: 3% of transaction amount (configurable)
  • Partner Fee: Varies by PSP provider (2-5%)
  • Conversion Fee: Applied during currency conversion
  • Bank Transfer Fee: Applied for cross-border transfers

Top-Up Method Selection

Use POST /wallet/topup for mobile apps with Firebase integration for seamless push notification OTP. Use POST /wallet/topup/verify for web applications where users manually enter OTP codes from SMS, email, or authenticator apps.

PSP Integration

Wallet operations depend on PSP service availability. Always implement fallback mechanisms and retry logic for critical operations. Cross-PSP transfers may take longer due to currency conversion requirements.

KYC Integration

Wallet limits are automatically applied based on user KYC status. Non-KYC users have balance limits (typically 5M IDR equivalent). Completing KYC removes these limits and enables full functionality.