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

# Tracking

> Monitor your offramp transactions from crypto to fiat

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

```mermaid theme={null}
graph TD
    A[initiated] --> B[awaiting_deposit]
    B --> C[deposit_received]
    C --> D[processing]
    D --> E[fiat_sent]
    E --> F[completed]
    B --> G[expired]
    D --> H[failed]
    H --> I[refunded]
```

| State              | Description                  | Action Required                |
| ------------------ | ---------------------------- | ------------------------------ |
| `initiated`        | Order created                | None                           |
| `awaiting_deposit` | Waiting for crypto           | Send crypto to deposit address |
| `deposit_received` | Crypto received              | None - processing              |
| `processing`       | Converting to fiat           | None - wait                    |
| `fiat_sent`        | Fiat transferred             | None - check bank              |
| `completed`        | Transaction complete         | None                           |
| `expired`          | Deposit not received in time | Create new order               |
| `failed`           | Processing failed            | Contact support                |
| `refunded`         | Crypto refunded              | Check wallet                   |

***

## Track Order

Monitor your offramp transaction using the reference number.

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

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

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

  # Track order
  order = monei.offramp_ledger.track_order('OFFRAMP-ABC123XYZ')

  print('Order Status:')
  print('=' * 15)
  print(f'Reference: {order.reference}')
  print(f'Status: {order.status}')
  print(f'Amount: {order.amount} {order.token}')
  print(f'Fiat: {order.fiat_amount} {order.fiat_currency}')
  print(f'Rate: {order.exchange_rate}')

  print(f'\nDeposit Address: {order.on_chain.deposit_address}')
  print(f'Network: {order.on_chain.network}')
  print(f'Expected: {order.on_chain.expected_amount}')
  print(f'Received: {order.on_chain.received_amount or "Pending"}')

  print(f'\nBank: {order.bank_details.bank_name}')
  print(f'Account: {order.bank_details.account_number}')

  print(f'\nCreated: {order.created_at}')
  print(f'Expires: {order.expires_at}')
  ```

  ```bash cURL theme={null}
  curl https://api.monei.cc/api/v1/offramp/exchange/track/OFFRAMP-ABC123XYZ \
    -H "x-api-key: YOUR_API_KEY"
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "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.

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

  ```python Python theme={null}
  import asyncio
  from datetime import datetime

  # Monitor order
  async def monitor_order(reference):
      print(f'Monitoring order: {reference}')
      print('=' * 20)
      
      last_status = None
      attempts = 0
      max_attempts = 60
      
      while attempts < max_attempts:
          try:
              order = monei.offramp_ledger.track_order(reference)
              
              # Check status change
              if order.status != last_status:
                  last_status = order.status
                  timestamp = datetime.now().strftime('%H:%M:%S')
                  
                  print(f'[{timestamp}] Status: {order.status}')
                  
                  # Status-specific info
                  if order.status == 'awaiting_deposit':
                      print(f'  → Send {order.on_chain.expected_amount} {order.token}')
                      print(f'  → To: {order.on_chain.deposit_address}')
                  
                  elif order.status == 'deposit_received':
                      print(f'  → Received {order.on_chain.received_amount}')
                      print(f'  → TX: {order.on_chain.transaction_hash}')
                  
                  elif order.status == 'processing':
                      print(f'  → Converting to {order.fiat_currency}')
                  
                  elif order.status == 'fiat_sent':
                      print(f'  → ₦{order.fiat_amount:,} sent')
                  
                  elif order.status == 'completed':
                      print('  → ✓ Completed!')
                      return order
                  
                  elif order.status in ['failed', 'expired']:
                      print(f'  → ✗ {order.status}')
                      return order
                  
                  print()
              
              # Break on terminal states
              if order.status in ['completed', 'failed', 'expired', 'refunded']:
                  break
          
          except Exception as error:
              print(f'Error: {error}')
          
          # Wait 30s
          await asyncio.sleep(30)
          attempts += 1
      
      print('Monitoring stopped')

  # Start
  await monitor_order('OFFRAMP-ABC123XYZ')
  ```
</CodeGroup>

***

## Expected Timeline

Typical offramp transaction timeline:

| Stage            | Duration            | Status             |
| ---------------- | ------------------- | ------------------ |
| Order creation   | Instant             | `initiated`        |
| Awaiting deposit | User dependent      | `awaiting_deposit` |
| Crypto deposit   | 1-5 minutes         | `deposit_received` |
| Conversion       | 2-10 minutes        | `processing`       |
| Fiat transfer    | 5-30 minutes        | `fiat_sent`        |
| **Total**        | **10 min - 1 hour** | `completed`        |

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

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

  ```python Python theme={null}
  # Get offramp history
  transactions = monei.offramp_ledger.get_user_transactions(
      page=1,
      limit=20,
  )

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

  for tx in transactions.transactions:
      print(f'Reference: {tx.reference}')
      print(f'Status: {tx.status}')
      print(f'Amount: {tx.amount} {tx.currency}')
      print(f'Fiat: {tx.metadata.fiat_amount} {tx.metadata.fiat_currency}')
      print(f'Date: {tx.created_at}')
      print('---')
  ```

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

***

## Webhooks

Receive real-time notifications for offramp status updates.

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

  ```python Python (Flask) theme={null}
  @app.route('/webhooks/monei', methods=['POST'])
  def monei_webhook():
      event = request.json
      signature = request.headers.get('x-monei-signature')
      
      # Verify signature
      if not verify_signature(event, signature):
          return 'Invalid signature', 401
      
      # Handle events
      event_type = event['type']
      
      if event_type == 'offramp.deposit_received':
          print('Crypto deposit confirmed')
          # Notify user
      
      elif event_type == 'offramp.processing':
          print('Converting to fiat')
          # Notify user
      
      elif event_type == 'offramp.fiat_sent':
          print(f"Fiat sent: {event['data']['fiatAmount']}")
          # Notify user
      
      elif event_type == 'offramp.completed':
          print('Transaction completed!')
          # Notify user
      
      elif event_type == 'offramp.failed':
          print(f"Failed: {event['data']['failureReason']}")
          # Notify user
      
      return 'OK', 200
  ```
</CodeGroup>

***

## Troubleshooting

<AccordionGroup>
  <Accordion icon="clock" title="Transaction Taking Too Long">
    **Problem:** Transaction stuck in processing

    **Expected times:**

    * `awaiting_deposit`: User dependent
    * `deposit_received` → `processing`: 1-5 min
    * `processing` → `fiat_sent`: 2-10 min
    * `fiat_sent` → `completed`: 5-30 min

    **Action:**

    * Check current status
    * If > 1 hour in processing, contact support
    * Provide transaction reference
  </Accordion>

  <Accordion icon="exclamation-triangle" title="Deposit Not Detected">
    **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
  </Accordion>

  <Accordion icon="circle-xmark" title="Transaction Failed">
    **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
  </Accordion>

  <Accordion icon="ban" title="Order Expired">
    **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
  </Accordion>

  <Accordion icon="wallet" title="Fiat Not in Bank">
    **Problem:** Status is "completed" but no fiat in bank

    **Timeline:**

    * 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
  </Accordion>
</AccordionGroup>

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Save Reference" icon="bookmark">
    Always save order reference number for tracking
  </Card>

  <Card title="Monitor Progress" icon="eye">
    Track order status until completed
  </Card>

  <Card title="Check Timeline" icon="clock">
    Know expected timelines for each stage
  </Card>

  <Card title="Use Webhooks" icon="webhook">
    Implement webhooks for real-time updates
  </Card>

  <Card title="Keep TX Hash" icon="receipt">
    Save crypto transaction hash for reference
  </Card>

  <Card title="Contact Support" icon="headset">
    Reach out if stuck for > 1 hour
  </Card>
</CardGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Overview" icon="circle-info" href="/offramp/overview">
    Learn offramp basics
  </Card>

  <Card title="Bank Verification" icon="building-columns" href="/offramp/bank-verification">
    Verify bank accounts
  </Card>

  <Card title="Exchange" icon="arrow-right-arrow-left" href="/offramp/exchange">
    Get quotes and initiate swaps
  </Card>

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