Documentation Index Fetch the complete documentation index at: https://docs.monei.cc/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Transactions are the core of Monei infrastructure. whether you’re sending Naira to a bank account, swapping tokens, or paying bills. This guide covers transaction types, lifecycle, monitoring, and troubleshooting.
What you’ll learn:
Transaction types and flows
Creating and submitting transactions
Monitoring transaction status
Transaction history and filtering
Error handling and recovery
Transaction Types
Monei supports multiple transaction types across different rails:
Fiat Transactions
Crypto Transactions
Offramp Transactions
Bill Payments
Naira-based operations
Bank transfers (payouts)
Virtual account deposits
Peer-to-peer transfers
Bill payments
Wallet funding
Characteristics:
Instant to near-instant
Nigerian Naira only
KYC limits apply
Requires transaction PIN
Learn more → Blockchain-based operations
Native token transfers (ETH, BNB, SOL, etc.)
ERC-20/SPL token transfers
Token swaps (DEX)
Cross-chain bridges
Smart contract interactions
Characteristics:
Network-dependent speed
Gas fees required
Blockchain confirmations
Irreversible
Learn more → Crypto-to-fiat conversions
USDT/USDC/CNGN to Naira
Instant bank settlement
Multi-network support
Rate-locked quotes
Characteristics:
Two-step process (swap + payout)
30-second quote validity
KYC tier limits
Bank account verification required
Learn more → Utility payments
Airtime purchases
Data bundles
Electricity bills
Cable TV subscriptions
Characteristics:
Instant processing
Validation required
Service-specific limits
Auto-retry on failure
Learn more →
Transaction Lifecycle
Every transaction goes through several states:
Initiated
Transaction created and submitted to Monei Actions:
Request validation
Balance check
KYC limit verification
Fee calculation
Processing
Transaction being executed For Fiat:
Banking network processing
Account verification
Transfer execution
For Crypto:
Blockchain submission
Network propagation
Miner/validator pickup
Confirming
Waiting for confirmations (crypto only) Confirmations required:
Ethereum: 12 blocks (~3 minutes)
BSC: 15 blocks (~45 seconds)
Polygon: 128 blocks (~4 minutes)
Solana: 32 slots (~13 seconds)
Completed
Transaction successfully finalized Updates:
Balance updated
Transaction record created
Webhooks triggered
Receipts generated
Failed (if applicable)
Transaction could not be completed Common reasons:
Insufficient balance
Invalid recipient
Network congestion
Gas estimation failure
KYC limit exceeded
Creating Transactions
Bank Transfer (Fiat)
import MoneiSDK from 'monei-sdk' ;
const monei = new MoneiSDK ({
apiKey: process . env . MONEI_API_KEY ,
});
// Send Naira to bank account
const transaction = await monei . payout . bankTransfer ({
amount: 10000 ,
bank: '058' , // Bank code
accountNumber: '0123456789' ,
transactionPin: 'your-4-digit-pin' ,
narration: 'Payment for services'
});
console . log ( 'Transaction ID:' , transaction . transactionId );
console . log ( 'Status:' , transaction . status );
console . log ( 'Reference:' , transaction . reference );
EVM Token Transfer
// Send ERC-20 token (e.g., USDT)
const cryptoTx = await monei . evm . sendToken ({
to: '0xRecipientAddress' ,
tokenAddress: '0x55d398326f99059fF775485246999027B3197955' , // USDT on BSC
amount: '100' ,
chainId: 56
});
console . log ( 'Transaction Hash:' , cryptoTx . txHash );
console . log ( 'Status:' , cryptoTx . status );
console . log ( 'Explorer:' , `https://bscscan.com/tx/ ${ cryptoTx . txHash } ` );
Solana Transfer
// Send SOL
const solTx = await monei . solana . sendToken ({
to: '5AH3qo1v1EZfT3QKQpSsx1F8W5JyGEVZPcD5DzkX1N1d' ,
amount: '0.5' ,
network: 'mainnet-beta'
});
console . log ( 'Signature:' , solTx . signature );
console . log ( 'Status:' , solTx . status );
Monitoring Transactions
Get Transaction Status
// Get status by transaction ID
const status = await monei . transactions . getStatus ( transactionId );
console . log ( 'Status:' , status . state );
console . log ( 'Amount:' , status . amount );
console . log ( 'Created:' , status . createdAt );
console . log ( 'Updated:' , status . updatedAt );
// Check if completed
if ( status . state === 'completed' ) {
console . log ( 'Transaction successful!' );
} else if ( status . state === 'failed' ) {
console . log ( 'Transaction failed:' , status . errorMessage );
}
Transaction States
State Description Next Action initiatedTransaction created Wait for processing processingBeing executed Monitor status confirmingWaiting for confirmations Wait for finality completedSuccessfully finalized None - done failedCould not complete Review error, retry if needed cancelledUser cancelled Create new transaction
Transaction History
Get All Transactions
// Get transaction history
const transactions = await monei . transactions . getAll ({
page: 1 ,
limit: 20 ,
type: 'all' , // 'fiat', 'crypto', 'offramp', 'bills'
status: 'all' // 'completed', 'pending', 'failed'
});
console . log ( 'Total:' , transactions . total );
console . log ( 'Page:' , transactions . page );
transactions . data . forEach ( tx => {
console . log ( ` ${ tx . type } : ₦ ${ tx . amount } - ${ tx . status } ` );
console . log ( ` Date: ${ tx . createdAt } ` );
console . log ( ` ID: ${ tx . id } ` );
});
Filter Transactions
// Filter by date range
const filtered = await monei . transactions . getAll ({
startDate: '2024-01-01' ,
endDate: '2024-01-31' ,
type: 'crypto' ,
status: 'completed'
});
// Filter by amount range
const byAmount = await monei . transactions . getAll ({
minAmount: 1000 ,
maxAmount: 100000
});
// Search by reference
const byReference = await monei . transactions . getByReference ({
reference: 'INV-2024-001'
});
Gas Fees (Crypto Transactions)
Understanding and managing blockchain transaction fees:
Estimating Gas
// Estimate gas for token transfer
const gasEstimate = await monei . evm . estimateGas ({
to: '0xRecipientAddress' ,
tokenAddress: '0xTokenContract' ,
amount: '100' ,
chainId: 56
});
console . log ( 'Estimated Gas:' , gasEstimate . gasLimit );
console . log ( 'Gas Price:' , gasEstimate . gasPrice , 'gwei' );
console . log ( 'Total Fee:' , gasEstimate . totalFeeEth , 'BNB' );
console . log ( 'USD Value:' , gasEstimate . totalFeeUsd );
Gas Optimization Tips
Check network congestion before transactions
Use off-peak hours for lower fees
Monitor gas price trends
Set max fee limits
Use Polygon or BSC for low-value transfers
Ethereum for high-value or security-critical transactions
Solana for ultra-low fees
Layer 2s (Arbitrum, Optimism) for balance
Combine multiple operations when possible
Use multicall contracts
Batch token approvals
Group similar transactions
Network Gas Comparison
Network Avg. Gas Fee Transfer Time Best For Polygon ~$0.01 ~30s Micro-transactions BSC ~$0.10 ~3s Low-cost transfers Arbitrum ~$0.20 ~1m Medium transfers Optimism ~$0.15 ~1m dApp interactions Ethereum ~$5.00 ~3m High-value transfers Base ~$0.05 ~2s Coinbase ecosystem Solana ~$0.001 ~13s High-frequency trading
Error Handling
Common Transaction Errors
Insufficient Balance
Invalid Recipient
Network Congestion
KYC Limit Exceeded
Error Code: INSUFFICIENT_BALANCECause:
Not enough funds for transaction amount
Not enough native token for gas fees
Balance reserved for pending transactions
Solutions: try {
await monei . evm . sendToken ({ ... });
} catch ( error ) {
if ( error . code === 'INSUFFICIENT_BALANCE' ) {
// Check balances
const balance = await monei . evm . getBalance ({ ... });
console . log ( 'Available:' , balance . available );
console . log ( 'Reserved:' , balance . reserved );
// Fund wallet or reduce amount
}
}
Error Code: INVALID_RECIPIENTCause:
Invalid address format
Wrong network for address
Contract address without ABI
Solutions: // Validate address before sending
const isValid = await monei . evm . validateAddress ({
address: '0xRecipientAddress' ,
chainId: 56
});
if ( ! isValid . valid ) {
console . error ( 'Invalid address:' , isValid . reason );
return ;
}
Error Code: NETWORK_CONGESTIONCause:
High gas prices
Transaction timeout
RPC issues
Solutions: // Implement retry logic with exponential backoff
async function sendWithRetry ( tx , maxRetries = 3 ) {
for ( let i = 0 ; i < maxRetries ; i ++ ) {
try {
return await monei . evm . sendToken ( tx );
} catch ( error ) {
if ( error . code === 'NETWORK_CONGESTION' && i < maxRetries - 1 ) {
await new Promise ( r => setTimeout ( r , Math . pow ( 2 , i ) * 1000 ));
continue ;
}
throw error ;
}
}
}
Error Code: KYC_LIMIT_EXCEEDEDCause:
Transaction exceeds daily/monthly limit
KYC tier insufficient
Solutions: // Check limits before transaction
const limits = await monei . user . getKycLimits ();
console . log ( 'Daily limit:' , limits . dailyLimit );
console . log ( 'Used today:' , limits . dailyUsed );
console . log ( 'Remaining:' , limits . dailyLimit - limits . dailyUsed );
if ( amount > limits . dailyLimit - limits . dailyUsed ) {
console . log ( 'Upgrade KYC tier or wait until tomorrow' );
}
Webhooks for Real-Time Updates
Set up webhooks to receive transaction updates automatically:
Webhook Events
Webhook Handler
Flask Webhook Handler
// Express.js webhook endpoint
app . post ( '/webhooks/monei' , async ( req , res ) => {
const event = req . body ;
// Verify webhook signature
const signature = req . headers [ 'x-monei-signature' ];
if ( ! monei . webhooks . verify ( event , signature )) {
return res . status ( 401 ). send ( 'Invalid signature' );
}
// Handle different event types
switch ( event . type ) {
case 'transaction.initiated' :
console . log ( 'Transaction started:' , event . data . id );
break ;
case 'transaction.completed' :
console . log ( 'Transaction completed:' , event . data . id );
// Update your database, notify user, etc.
break ;
case 'transaction.failed' :
console . log ( 'Transaction failed:' , event . data . id );
console . error ( 'Reason:' , event . data . error );
// Handle failure, retry, notify user
break ;
}
res . status ( 200 ). send ( 'OK' );
});
Learn more about webhooks →
Best Practices
Verify Before Sending Always verify recipient address and amount before submitting transactions
Monitor Status Use webhooks or polling to track transaction progress in real-time
Handle Errors Implement proper error handling with user-friendly messages
Test Small First Send small test transactions before large transfers
Next Steps
Networks Learn about supported blockchain networks
Error Handling Comprehensive error handling guide
Transaction Management Advanced transaction management features
Webhooks Set up real-time transaction notifications