Skip to main content

Overview

Track your offramp transactions in real-time from crypto deposit to fiat settlement. This guide covers transaction monitoring, status updates, and troubleshooting. What you’ll learn:
  • Track transaction status
  • Understand transaction states
  • Monitor progress
  • Handle different scenarios
  • Get transaction history

Transaction States

Your offramp transaction progresses through multiple states:
StateDescriptionAction Required
initiatedOrder createdNone
awaiting_depositWaiting for cryptoSend crypto to deposit address
deposit_receivedCrypto receivedNone - processing
processingConverting to fiatNone - wait
fiat_sentFiat transferredNone - check bank
completedTransaction completeNone
expiredDeposit not received in timeCreate new order
failedProcessing failedContact support
refundedCrypto refundedCheck wallet

Track Order

Monitor your offramp transaction using the reference number.
import MoneiSDK from 'monei-sdk';

const monei = new MoneiSDK({
  apiKey: process.env.MONEI_API_KEY,
});

// Track order by reference
const order = await monei.offrampLedger.trackOrder('OFFRAMP-ABC123XYZ');

console.log('Order Status:');
console.log('=============');
console.log('Reference:', order.reference);
console.log('Status:', order.status);
console.log('Amount:', order.amount, order.token);
console.log('Fiat Amount:', order.fiatAmount, order.fiatCurrency);
console.log('Exchange Rate:', order.exchangeRate);

console.log('\nDeposit Details:');
console.log('Address:', order.onChain.depositAddress);
console.log('Network:', order.onChain.network);
console.log('Expected:', order.onChain.expectedAmount, order.token);
console.log('Received:', order.onChain.receivedAmount || 'Pending');

console.log('\nBank Details:');
console.log('Bank:', order.bankDetails.bankName);
console.log('Account:', order.bankDetails.accountNumber);
console.log('Account Name:', order.bankDetails.accountName);

console.log('\nTimestamps:');
console.log('Created:', new Date(order.createdAt).toLocaleString());
console.log('Expires:', new Date(order.expiresAt).toLocaleString());
if (order.completedAt) {
  console.log('Completed:', new Date(order.completedAt).toLocaleString());
}
Response:
{
  "statusCode": 200,
  "message": "Order retrieved successfully",
  "data": {
    "reference": "OFFRAMP-ABC123XYZ",
    "status": "processing",
    "amount": 100,
    "token": "USDT",
    "network": "base",
    "fiatCurrency": "NGN",
    "fiatAmount": 155025,
    "exchangeRate": 1550.25,
    "onChain": {
      "network": "base",
      "depositAddress": "0x1234567890abcdef1234567890abcdef12345678",
      "expectedAmount": 100,
      "receivedAmount": 100,
      "transactionHash": "0xabc...",
      "confirmations": 15,
      "confirmedAt": "2024-02-15T11:35:00Z"
    },
    "bankDetails": {
      "bankCode": "058",
      "bankName": "Guaranty Trust Bank",
      "accountNumber": "0123456789",
      "accountName": "JOHN DOE"
    },
    "createdAt": "2024-02-15T11:30:00Z",
    "expiresAt": "2024-02-15T12:00:00Z",
    "completedAt": null
  }
}

Monitor Progress

Track transaction progress in real-time.
// Poll for status updates
async function monitorOrder(reference) {
  console.log('Monitoring order:', reference);
  console.log('================\n');
  
  let lastStatus = null;
  let attempts = 0;
  const maxAttempts = 60; // 30 minutes (every 30s)
  
  while (attempts < maxAttempts) {
    try {
      const order = await monei.offrampLedger.trackOrder(reference);
      
      // Check if status changed
      if (order.status !== lastStatus) {
        lastStatus = order.status;
        const timestamp = new Date().toLocaleTimeString();
        
        console.log(`[${timestamp}] Status: ${order.status}`);
        
        // Display relevant info based on status
        switch (order.status) {
          case 'awaiting_deposit':
            console.log(`  → Send ${order.onChain.expectedAmount} ${order.token} to:`);
            console.log(`  → ${order.onChain.depositAddress}`);
            break;
            
          case 'deposit_received':
            console.log(`  → Received ${order.onChain.receivedAmount} ${order.token}`);
            console.log(`  → TX: ${order.onChain.transactionHash}`);
            break;
            
          case 'processing':
            console.log(`  → Converting ${order.amount} ${order.token} to ${order.fiatCurrency}`);
            break;
            
          case 'fiat_sent':
            console.log(`  → ₦${order.fiatAmount.toLocaleString()} sent to ${order.bankDetails.bankName}`);
            break;
            
          case 'completed':
            console.log(`  → ✓ Transaction completed!`);
            console.log(`  → Check your bank account`);
            return order;
            
          case 'failed':
            console.log(`  → ✗ Transaction failed`);
            console.log(`  → Contact support with reference: ${reference}`);
            return order;
            
          case 'expired':
            console.log(`  → ✗ Order expired - no deposit received`);
            return order;
        }
        
        console.log('');
      }
      
      // Break if terminal state
      if (['completed', 'failed', 'expired', 'refunded'].includes(order.status)) {
        break;
      }
      
    } catch (error) {
      console.error('Error checking status:', error.message);
    }
    
    // Wait 30 seconds before next check
    await new Promise(resolve => setTimeout(resolve, 30000));
    attempts++;
  }
  
  console.log('Monitoring stopped');
}

// Start monitoring
await monitorOrder('OFFRAMP-ABC123XYZ');

Expected Timeline

Typical offramp transaction timeline:
StageDurationStatus
Order creationInstantinitiated
Awaiting depositUser dependentawaiting_deposit
Crypto deposit1-5 minutesdeposit_received
Conversion2-10 minutesprocessing
Fiat transfer5-30 minutesfiat_sent
Total10 min - 1 hourcompleted
Factors affecting speed:
  • Network congestion (crypto)
  • Number of confirmations needed
  • Bank processing time
  • Transaction amount
  • Peak hours

Get Transaction History

View all your offramp transactions.
// Get all offramp transactions
const transactions = await monei.offrampLedger.getTransactions({
  page: 1,
  limit: 20,
});

console.log(`Total Offramp Transactions: ${transactions.pagination.total}\n`);

transactions.transactions.forEach(tx => {
  console.log('Reference:', tx.reference);
  console.log('Status:', tx.status);
  console.log('Amount:', tx.amount, tx.currency);
  console.log('Fiat:', tx.metadata.fiatAmount, tx.metadata.fiatCurrency);
  console.log('Rate:', tx.metadata.exchangeRate);
  console.log('Bank:', tx.metadata.bankName);
  console.log('Date:', new Date(tx.createdAt).toLocaleString());
  console.log('---');
});

Webhooks

Receive real-time notifications for offramp status updates.
app.post('/webhooks/monei', (req, res) => {
  const event = req.body;
  
  // Verify webhook signature
  const signature = req.headers['x-monei-signature'];
  if (!verifySignature(event, signature)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Handle offramp events
  switch (event.type) {
    case 'offramp.deposit_received':
      console.log('Crypto deposit confirmed');
      console.log('Reference:', event.data.reference);
      console.log('Amount:', event.data.amount);
      // Notify user: "Crypto received, converting to fiat"
      break;
      
    case 'offramp.processing':
      console.log('Converting to fiat');
      // Notify user: "Converting your crypto..."
      break;
      
    case 'offramp.fiat_sent':
      console.log('Fiat sent to bank');
      console.log('Fiat Amount:', event.data.fiatAmount);
      console.log('Bank:', event.data.bankName);
      // Notify user: "₦X sent to your account"
      break;
      
    case 'offramp.completed':
      console.log('Transaction completed!');
      // Notify user: "Transaction complete!"
      break;
      
    case 'offramp.failed':
      console.log('Transaction failed');
      console.log('Reason:', event.data.failureReason);
      // Notify user of failure
      break;
  }
  
  res.status(200).send('OK');
});

Troubleshooting

Problem: Transaction stuck in processingExpected times:
  • awaiting_deposit: User dependent
  • deposit_receivedprocessing: 1-5 min
  • processingfiat_sent: 2-10 min
  • fiat_sentcompleted: 5-30 min
Action:
  • Check current status
  • If > 1 hour in processing, contact support
  • Provide transaction reference
Problem: Sent crypto but status still “awaiting_deposit”Checks:
  1. Verify transaction hash on block explorer
  2. Confirm correct network used
  3. Check if transaction confirmed
  4. Ensure exact amount sent
Solution:
  • Wait for network confirmations
  • Base/Polygon: 15+ confirmations
  • If confirmed but not detected, contact support with:
    • Order reference
    • Transaction hash
    • Network used
Problem: Status changed to “failed”Common causes:
  • Crypto deposit issues
  • Conversion failed
  • Bank transfer rejected
  • Compliance issues
Action:
  • Check order for failure reason
  • Crypto will be refunded if issue on our end
  • Contact support with reference number
Problem: Status changed to “expired”Cause: No crypto deposit received within time limit (30 min)Solution:
  • Create new offramp order
  • Get new deposit address
  • Send crypto promptly
  • Set reminder for faster sending
Problem: Status is “completed” but no fiat in bankTimeline:
  • Same bank: Instant - 5 minutes
  • Different bank: 5 - 30 minutes
  • Some banks: Up to 1 hour
Action:
  1. Wait up to 1 hour
  2. Check bank app/statement
  3. Contact your bank
  4. If still missing, contact support with:
    • Order reference
    • Bank name & account
    • Timestamp

Best Practices

Save Reference

Always save order reference number for tracking

Monitor Progress

Track order status until completed

Check Timeline

Know expected timelines for each stage

Use Webhooks

Implement webhooks for real-time updates

Keep TX Hash

Save crypto transaction hash for reference

Contact Support

Reach out if stuck for > 1 hour

Next Steps

Overview

Learn offramp basics

Bank Verification

Verify bank accounts

Exchange

Get quotes and initiate swaps

Webhooks

Set up real-time notifications