> ## 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.

# Transactions

> Understanding transaction management in Monei infrastructure

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

<Tabs>
  <Tab title="Fiat Transactions">
    **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 →](/naira-wallet/payouts)
  </Tab>

  <Tab title="Crypto Transactions">
    **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 →](/evm-blockchain/transactions)
  </Tab>

  <Tab title="Offramp Transactions">
    **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 →](/offramp/overview)
  </Tab>

  <Tab title="Bill Payments">
    **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 →](/bill-payments/overview)
  </Tab>
</Tabs>

***

## Transaction Lifecycle

Every transaction goes through several states:

<Steps>
  <Step title="Initiated">
    Transaction created and submitted to Monei

    **Actions:**

    * Request validation
    * Balance check
    * KYC limit verification
    * Fee calculation
  </Step>

  <Step title="Processing">
    Transaction being executed

    **For Fiat:**

    * Banking network processing
    * Account verification
    * Transfer execution

    **For Crypto:**

    * Blockchain submission
    * Network propagation
    * Miner/validator pickup
  </Step>

  <Step title="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)
  </Step>

  <Step title="Completed">
    Transaction successfully finalized

    **Updates:**

    * Balance updated
    * Transaction record created
    * Webhooks triggered
    * Receipts generated
  </Step>

  <Step title="Failed (if applicable)">
    Transaction could not be completed

    **Common reasons:**

    * Insufficient balance
    * Invalid recipient
    * Network congestion
    * Gas estimation failure
    * KYC limit exceeded
  </Step>
</Steps>

***

## Creating Transactions

### Bank Transfer (Fiat)

<CodeGroup>
  ```javascript Node.js theme={null}
  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);
  ```

  ```python Python theme={null}
  from monei import MoneiClient

  monei = MoneiClient(
      api_key=os.getenv('MONEI_API_KEY')
  )

  # Send Naira to bank account
  transaction = monei.payout.bank_transfer(
      amount=10000,
      bank='058',
      account_number='0123456789',
      transaction_pin='your-pin',
      narration='Payment for services'
  )

  print(f'Transaction ID: {transaction.transaction_id}')
  print(f'Status: {transaction.status}')
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.monei.cc/api/v1/payout/bank \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "amount": 10000,
      "bank": "058",
      "accountNumber": "0123456789",
      "transactionPin": "1234",
      "narration": "Payment for services"
    }'
  ```
</CodeGroup>

### EVM Token Transfer

<CodeGroup>
  ```javascript Node.js theme={null}
  // 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}`);

  ```

  ```python Python theme={null}
  # Send ERC-20 token
  crypto_tx = monei.evm.send_token(
      to='0xRecipientAddress',
      token_address='0x55d398326f99059fF775485246999027B3197955',
      amount='100',
      chain_id=56
  )

  print(f'Transaction Hash: {crypto_tx.tx_hash}')
  print(f'Status: {crypto_tx.status}')
  ```
</CodeGroup>

### Solana Transfer

<CodeGroup>
  ```javascript Node.js theme={null}
  // 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);
  ```

  ```python Python theme={null}
  # Send SOL
  sol_tx = monei.solana.send_token(
      to='5AH3qo1v1EZfT3QKQpSsx1F8W5JyGEVZPcD5DzkX1N1d',
      amount='0.5',
      network='mainnet-beta'
  )

  print(f'Signature: {sol_tx.signature}')
  ```
</CodeGroup>

***

## Monitoring Transactions

### Get Transaction Status

<CodeGroup>
  ```javascript Node.js theme={null}
  // 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);
  }
  ```

  ```python Python theme={null}
  # Get status by transaction ID
  status = monei.transactions.get_status(transaction_id)

  print(f'Status: {status.state}')
  print(f'Amount: {status.amount}')

  if status.state == 'completed':
      print('Transaction successful!')
  elif status.state == 'failed':
      print(f'Transaction failed: {status.error_message}')
  ```

  ```bash cURL theme={null}
  curl https://api.monei.cc/api/v1/transactions/{transactionId}/status \
    -H "x-api-key: YOUR_API_KEY"
  ```
</CodeGroup>

### Transaction States

| State        | Description               | Next Action                   |
| ------------ | ------------------------- | ----------------------------- |
| `initiated`  | Transaction created       | Wait for processing           |
| `processing` | Being executed            | Monitor status                |
| `confirming` | Waiting for confirmations | Wait for finality             |
| `completed`  | Successfully finalized    | None - done                   |
| `failed`     | Could not complete        | Review error, retry if needed |
| `cancelled`  | User cancelled            | Create new transaction        |

***

## Transaction History

### Get All Transactions

<CodeGroup>
  ```javascript Node.js theme={null}
  // 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}`);
  });
  ```

  ```python Python theme={null}
  # Get transaction history
  transactions = monei.transactions.get_all(
      page=1,
      limit=20,
      type='all',
      status='all'
  )

  print(f'Total: {transactions.total}')

  for tx in transactions.data:
      print(f'{tx.type}: ₦{tx.amount} - {tx.status}')
      print(f'  Date: {tx.created_at}')
  ```

  ```bash cURL theme={null}
  curl https://api.monei.cc/api/v1/transactions?page=1&limit=20 \
    -H "x-api-key: YOUR_API_KEY"
  ```
</CodeGroup>

### Filter Transactions

<CodeGroup>
  ```javascript Node.js theme={null}
  // 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'
  });
  ```

  ```python Python theme={null}
  # Filter by date range
  filtered = monei.transactions.get_all(
      start_date='2024-01-01',
      end_date='2024-01-31',
      type='crypto',
      status='completed'
  )

  # Filter by amount
  by_amount = monei.transactions.get_all(
      min_amount=1000,
      max_amount=100000
  )
  ```
</CodeGroup>

***

## Gas Fees (Crypto Transactions)

Understanding and managing blockchain transaction fees:

### Estimating Gas

<CodeGroup>
  ```javascript Node.js theme={null}
  // 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);
  ```

  ```python Python theme={null}
  # Estimate gas
  gas_estimate = monei.evm.estimate_gas(
      to='0xRecipientAddress',
      token_address='0xTokenContract',
      amount='100',
      chain_id=56
  )

  print(f'Total Fee: {gas_estimate.total_fee_eth} BNB')
  print(f'USD Value: ${gas_estimate.total_fee_usd}')
  ```
</CodeGroup>

### Gas Optimization Tips

<AccordionGroup>
  <Accordion icon="clock" title="Timing">
    * Check network congestion before transactions
    * Use off-peak hours for lower fees
    * Monitor gas price trends
    * Set max fee limits
  </Accordion>

  <Accordion icon="network-wired" title="Network Selection">
    * 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
  </Accordion>

  <Accordion icon="code" title="Batching">
    * Combine multiple operations when possible
    * Use multicall contracts
    * Batch token approvals
    * Group similar transactions
  </Accordion>
</AccordionGroup>

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

<Tabs>
  <Tab title="Insufficient Balance">
    **Error Code:** `INSUFFICIENT_BALANCE`

    **Cause:**

    * Not enough funds for transaction amount
    * Not enough native token for gas fees
    * Balance reserved for pending transactions

    **Solutions:**

    ```javascript theme={null}
    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
      }
    }
    ```
  </Tab>

  <Tab title="Invalid Recipient">
    **Error Code:** `INVALID_RECIPIENT`

    **Cause:**

    * Invalid address format
    * Wrong network for address
    * Contract address without ABI

    **Solutions:**

    ```javascript theme={null}
    // Validate address before sending
    const isValid = await monei.evm.validateAddress({
      address: '0xRecipientAddress',
      chainId: 56
    });

    if (!isValid.valid) {
      console.error('Invalid address:', isValid.reason);
      return;
    }
    ```
  </Tab>

  <Tab title="Network Congestion">
    **Error Code:** `NETWORK_CONGESTION`

    **Cause:**

    * High gas prices
    * Transaction timeout
    * RPC issues

    **Solutions:**

    ```javascript theme={null}
    // 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;
        }
      }
    }
    ```
  </Tab>

  <Tab title="KYC Limit Exceeded">
    **Error Code:** `KYC_LIMIT_EXCEEDED`

    **Cause:**

    * Transaction exceeds daily/monthly limit
    * KYC tier insufficient

    **Solutions:**

    ```javascript theme={null}
    // 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');
    }
    ```
  </Tab>
</Tabs>

***

## Webhooks for Real-Time Updates

Set up webhooks to receive transaction updates automatically:

### Webhook Events

<CodeGroup>
  ```javascript Webhook Handler theme={null}
  // 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');
  });
  ```

  ```python Flask Webhook Handler theme={null}
  from flask import Flask, request
  import hmac
  import hashlib

  app = Flask(__name__)

  @app.route('/webhooks/monei', methods=['POST'])
  def monei_webhook():
      event = request.json
      signature = request.headers.get('x-monei-signature')
      
      # Verify signature
      if not verify_webhook(event, signature):
          return 'Invalid signature', 401
      
      # Handle events
      if event['type'] == 'transaction.initiated':
          print(f"Transaction started: {event['data']['id']}")
      elif event['type'] == 'transaction.completed':
          print(f"Transaction completed: {event['data']['id']}")
      elif event['type'] == 'transaction.failed':
          print(f"Transaction failed: {event['data']['id']}")
          print(f"Reason: {event['data']['error']}")
      
      return 'OK', 200
  ```
</CodeGroup>

[Learn more about webhooks →](/security/webhooks)

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Verify Before Sending" icon="check">
    Always verify recipient address and amount before submitting transactions
  </Card>

  <Card title="Monitor Status" icon="eye">
    Use webhooks or polling to track transaction progress in real-time
  </Card>

  <Card title="Handle Errors" icon="triangle-exclamation">
    Implement proper error handling with user-friendly messages
  </Card>

  <Card title="Test Small First" icon="flask">
    Send small test transactions before large transfers
  </Card>
</CardGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Networks" icon="network-wired" href="/core-concepts/networks">
    Learn about supported blockchain networks
  </Card>

  <Card title="Error Handling" icon="bug" href="/core-concepts/error-handling">
    Comprehensive error handling guide
  </Card>

  <Card title="Transaction Management" icon="list" href="/transactions/management">
    Advanced transaction management features
  </Card>

  <Card title="Webhooks" icon="webhook" href="/security/webhooks">
    Set up real-time transaction notifications
  </Card>
</CardGroup>
