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 integrationPOST /wallet/topup- Top-up with Firebase OTP (Mobile)POST /wallet/topup/verify- Top-up with manual OTP (Web)GET /wallet/balance- Check primary wallet balanceGET /wallet/balances- Check all user wallet balancesPOST /wallet/mock_activate- Manual wallet activation
🔄 Transfer & Conversion Blocks
POST /wallet/transfer- Internal wallet transfersPOST /wallet/convert- Currency conversionPOST /wallet/cross_psp_transfer- Cross-PSP provider transfersPOST /wallet/cross_border- Cross-border bank transfersPOST /wallet/withdraw- Bank withdrawal operations
💱 Payin/Offramp Blocks
POST /wallet/payin/quote- Calculate payin fees and totalsGET /wallet/payins/:user_id- List pending payinsPOST /wallet/offramp/quote- Calculate offramp feesGET /wallet/offramps/:user_id- Offramp transaction history
🔧 Admin & Management Blocks
GET /wallet/admin/detail- Admin wallet overviewPOST /wallet/admin/update_keys- Update wallet keysGET /wallet/user/:user_id- User wallet managementGET /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
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_idnumberrequiredUser ID who will own the wallet
country_codestringrequiredCountry code for wallet currency (ID, SG, AU, etc.)
Request Body
{
"user_id": 123,
"country_code": "ID"
}Response
{
"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)"
}{
"error": "User already has a wallet in the country ID."
}{
"success": false,
"error": "Failed to create wallet",
"details": "PSP integration error"
}Top-Up Wallet (Mobile - Firebase OTP)
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_idstringrequiredWallet ID to top-up
amountnumberrequiredAmount to top-up
currencystringrequiredCurrency code (IDR, SGD, USD, etc.)
firebase_tokenstringFirebase token for push notification OTP (Step 1 only)
otp_codestringOTP code for verification (Step 2 only)
Request Body
{
"wallet_id": "wallet_456789",
"amount": 100000,
"currency": "IDR",
"firebase_token": "firebase_token_here"
}Response
{
"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"
}
}{
"message": "OTP sent to your device",
"otp_code": "123456"
}{
"error": "Invalid OTP code",
"details": "OTP code expired or incorrect"
}{
"error": "Failed to process top-up",
"details": "PSP service unavailable"
}Top-Up Wallet (Web - Manual OTP)
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_idstringrequiredWallet ID to top-up
otp_codestringrequiredOTP code for verification
Request Body
{
"wallet_id": "wallet_456789",
"otp_code": "123456"
}Response
{
"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"
}
}{
"error": "Invalid OTP code",
"details": "OTP verification failed"
}{
"error": "Wallet not found or inactive"
}{
"error": "Top-up failed",
"details": "PSP integration error"
}Check 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
{
"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
}
]
}{
"error": "No active wallet found for this user."
}{
"error": "Failed to retrieve balance data",
"details": "Database connection error"
}Check All Wallet Balances
Check All User Wallet Balances
Get balance information for all user's active wallets across different currencies and PSP providers.
Response
{
"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
}
]
}{
"error": "User has no active wallets."
}{
"error": "Failed to get balances",
"details": "PSP service error"
}🔄 Transfer Operations
Internal 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_idstringrequiredSource wallet ID
to_wallet_idstringrequiredDestination wallet ID
amountnumberrequiredTransfer amount
notestringOptional transfer note
Request Body
{
"from_wallet_id": "wallet_456789",
"to_wallet_id": "wallet_789012",
"amount": 50000,
"note": "Payment for services"
}Response
{
"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
}{
"error": "Insufficient balance"
}{
"error": "Sender or receiver wallet not found"
}{
"error": "Failed to process transfer",
"details": "PSP service error"
}Currency Conversion
Currency Conversion
Convert funds between different currencies using real-time exchange rates. Supports multiple currency pairs with transparent fee structure.
Parameters
user_idnumberrequiredUser ID performing conversion
amountnumberrequiredAmount to convert
from_currencystringrequiredSource currency code
to_currencystringrequiredTarget currency code
Request Body
{
"user_id": 123,
"amount": 1000000,
"from_currency": "IDR",
"to_currency": "SGD"
}Response
{
"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"
}
}{
"error": "from_currency and to_currency cannot be the same"
}{
"error": "Conversion failed",
"details": "Exchange rate unavailable"
}Cross-Border Transfer
Cross-Border Bank Transfer
Transfer funds from wallet to international bank accounts with automatic currency conversion and multi-PSP routing support.
Parameters
from_wallet_idstringrequiredSource wallet ID
amountnumberrequiredTransfer amount
to_currencystringrequiredTarget currency for bank transfer
bank_accountobjectrequiredBank account details for transfer
notestringOptional 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
{
"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"
}{
"error": "Insufficient IDR funds"
}{
"error": "Wallet not found"
}{
"error": "Failed cross-border offramp processing",
"details": "Bank service unavailable"
}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_idstringrequiredSource wallet ID
to_wallet_idstringrequiredDestination wallet ID
amountnumberrequiredTransfer amount
notestringOptional transfer note
Request Body
{
"from_wallet_id": "wallet_456789",
"to_wallet_id": "wallet_789012",
"amount": 100000,
"note": "Cross-PSP payment"
}Response
{
"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
}
]
}{
"error": "Cross PSP Transfer only allowed for different PSP providers"
}{
"error": "Failed to process cross PSP transfer",
"details": "Currency conversion failed"
}💱 Payin/Offramp Operations
Get 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_idstringrequiredWallet ID for payin
amountnumberrequiredBase payin amount
currencystringrequiredCurrency code
cover_feebooleanWhether to include fees in total (default: true)
Request Body
{
"wallet_id": "wallet_456789",
"amount": 100000,
"currency": "IDR",
"cover_fee": true
}Response
{
"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"
}{
"error": "wallet_id, amount, and currency are required"
}{
"error": "Wallet not found or inactive"
}{
"error": "Failed to calculate VA quote"
}Get Pending Payins
Get User's Pending Payins
Retrieve all pending payin transactions for a specific user including VA details, expiry times, and fee breakdowns.
Parameters
user_idstringrequiredUser ID to get pending payins for
Response
{
"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"
}
]
}{
"error": "Failed to retrieve payin list"
}Get Offramp Quote
Calculate Offramp Quote with Fees
Calculate fees and total amount for offramp operations to bank accounts.
Parameters
wallet_idstringrequiredWallet ID for offramp
amountnumberrequiredOfframp amount
cover_feebooleanWhether to include fees in calculation (default: true)
Request Body
{
"wallet_id": "wallet_456789",
"amount": 200000,
"cover_fee": true
}Response
{
"quote_id": "OFFRAMP-QT-1705123456-9999",
"currency": "IDR",
"amount": 200000,
"cover_fee": true,
"total_with_fee": 211000,
"platform_fee": 6000,
"partner_fee": 5000
}{
"error": "wallet_id and amount are required"
}{
"error": "Wallet not found or inactive"
}{
"error": "Failed to calculate off-ramp quote"
}Get Offramp History
Get User's Offramp History
Retrieve offramp transaction history for a specific user including bank transfer details, fees, and status updates.
Parameters
user_idstringrequiredUser ID to get offramp history for
Response
{
"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"
}
]
}{
"error": "Failed to retrieve offramp data"
}🔧 Admin Operations
Get Admin Wallet Detail
Get Admin Wallet Overview
Retrieve comprehensive wallet information for admin users including balance breakdowns, transaction summaries, and wallet status across all currencies.
Response
{
"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
}
]
}{
"error": "No wallets found for this user."
}{
"error": "Failed to retrieve wallet details"
}Get Wallets by 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_idstringrequiredUser ID to get wallets for
Response
{
"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
}
]
}{
"error": "Failed to get wallet data"
}Mock Activate Wallet
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.
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_idstringrequiredWallet ID to activate
country_codestringrequiredCountry code for reference
Request Body
{
"wallet_id": "wallet_456789",
"country_code": "ID"
}Response
{
"message": "Wallet wallet_456789 successfully activated.",
"wallet_id": "wallet_456789",
"country_code": "ID",
"status": "ACTIVE",
"currency": "IDR",
"psp_id": "DOKU_PSP"
}{
"error": "Wallet is already active."
}{
"error": "Wallet activation can only be performed in MOCK mode."
}{
"error": "Wallet not found."
}{
"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
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.
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.
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.