Skip to main content

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:
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 →

Transaction Lifecycle

Every transaction goes through several states:
1

Initiated

Transaction created and submitted to MoneiActions:
  • Request validation
  • Balance check
  • KYC limit verification
  • Fee calculation
2

Processing

Transaction being executedFor Fiat:
  • Banking network processing
  • Account verification
  • Transfer execution
For Crypto:
  • Blockchain submission
  • Network propagation
  • Miner/validator pickup
3

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)
4

Completed

Transaction successfully finalizedUpdates:
  • Balance updated
  • Transaction record created
  • Webhooks triggered
  • Receipts generated
5

Failed (if applicable)

Transaction could not be completedCommon 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}`);

// Monitor confirmation
const checkStatus = async () => {
  const status = await monei.evm.getTransactionStatus(cryptoTx.txHash);
  console.log('Confirmations:', status.confirmations);
  
  if (status.confirmations >= 15) {
    console.log('Transaction confirmed!');
  } else {
    setTimeout(checkStatus, 3000); // Check every 3 seconds
  }
};

checkStatus();

Solana Transfer

// Send SOL
const solTx = await monei.solana.transfer({
  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

StateDescriptionNext Action
initiatedTransaction createdWait for processing
processingBeing executedMonitor status
confirmingWaiting for confirmationsWait for finality
completedSuccessfully finalizedNone - done
failedCould not completeReview error, retry if needed
cancelledUser cancelledCreate new transaction

Transaction History

Get All Transactions

// Get transaction history
const transactions = await monei.transactions.getUserTransactions({
  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.getUserTransactions({
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  type: 'crypto',
  status: 'completed'
});

// Filter by amount range
const byAmount = await monei.transactions.getUserTransactions({
  minAmount: 1000,
  maxAmount: 100000
});

// Search by reference
const byReference = await monei.transactions.getTransactionByReference({
  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

NetworkAvg. Gas FeeTransfer TimeBest For
Polygon~$0.01~30sMicro-transactions
BSC~$0.10~3sLow-cost transfers
Arbitrum~$0.20~1mMedium transfers
Optimism~$0.15~1mdApp interactions
Ethereum~$5.00~3mHigh-value transfers
Base~$0.05~2sCoinbase ecosystem
Solana~$0.001~13sHigh-frequency trading

Error Handling

Common Transaction Errors

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
  }
}

Webhooks for Real-Time Updates

Set up webhooks to receive transaction updates automatically:

Webhook Events

// 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