> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oneclickdz.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Suivi de Statut et Interrogation

> Surveiller l'exécution des recharges internet avec des stratégies d'interrogation efficaces

## Vue d'ensemble

Après avoir envoyé une commande de recharge internet, interrogez l'endpoint `/check-id` pour suivre le statut et récupérer les détails de la carte lors de l'exécution. La plupart des commandes se terminent en 3-45 secondes, mais certaines peuvent être QUEUED pendant 12-48 heures.

<Info>
  Interrogez toutes les **5-10 secondes** jusqu'à ce que la commande atteigne un état final : FULFILLED, REFUNDED ou QUEUED.
</Info>

## Référence API

<Card title="GET /v3/internet/check-id/{id}" icon="magnifying-glass" href="/fr/api-reference/internet/check-by-id">
  Documentation complète de l'endpoint
</Card>

## Valeurs de Statut de Commande

<AccordionGroup>
  <Accordion title="HANDLING" icon="spinner">
    La commande est en cours de traitement avec l'opérateur. Durée typique : 3-45 secondes. Continuez l'interrogation toutes les 5-10 secondes.
  </Accordion>

  <Accordion title="FULFILLED" icon="check-circle">
    **Succès !** Carte livrée. `card_code`, `num_trans` et `date_traitement` disponibles. Livrez immédiatement au client.
  </Accordion>

  <Accordion title="QUEUED" icon="clock">
    **Planifié pour plus tard.** La commande sera traitée dans les 12-48 heures. Ce n'est pas un échec - planifiez une nouvelle vérification après 24 heures et informez le client.
  </Accordion>

  <Accordion title="REFUNDED" icon="rotate-left">
    **Échec.** La commande a été annulée et remboursée automatiquement. Notifiez le client de l'échec.
  </Accordion>
</AccordionGroup>

## Vérification de statut de base

<CodeGroup>
  ```javascript Node.js theme={null}
  async function checkTopupStatus(topupId) {
    const response = await fetch(
      `https://api.oneclickdz.com/v3/internet/check-id/${topupId}`,
      {
        headers: {
          "X-Access-Token": process.env.API_KEY,
        },
      }
    );

    if (!response.ok) {
      throw new Error(`Failed to check status: ${response.status}`);
    }

    const result = await response.json();
    return result.data;
  }

  // Usage
  const topupId = "6901616fe9e88196b4eb64b2";
  const order = await checkTopupStatus(topupId);

  console.log(`Status: ${order.status}`);
  console.log(`Type: ${order.type}`);
  console.log(`Number: ${order.number}`);

  if (order.card_code) {
    console.log(`Card Code: ${order.card_code}`);
    console.log(`Transaction: ${order.num_trans}`);
  }
  ```

  ```python Python theme={null}
  import requests
  import os

  def check_topup_status(topup_id):
      response = requests.get(
          f'https://api.oneclickdz.com/v3/internet/check-id/{topup_id}',
          headers={'X-Access-Token': os.getenv('API_KEY')}
      )
      
      response.raise_for_status()
      return response.json()['data']

  # Usage
  topup_id = '6901616fe9e88196b4eb64b2'
  order = check_topup_status(topup_id)

  print(f"Status: {order['status']}")
  print(f"Type: {order['type']}")
  print(f"Number: {order['number']}")

  if 'card_code' in order:
      print(f"Card Code: {order['card_code']}")
      print(f"Transaction: {order['num_trans']}")
  ```

  ```php PHP theme={null}
  <?php

  function checkTopupStatus($topupId) {
      $url = "https://api.oneclickdz.com/v3/internet/check-id/{$topupId}";
      
      $ch = curl_init($url);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, [
          'X-Access-Token: ' . getenv('API_KEY')
      ]);
      
      $response = curl_exec($ch);
      $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
      curl_close($ch);
      
      if ($httpCode !== 200) {
          throw new Exception("Failed to check status: " . $httpCode);
      }
      
      $result = json_decode($response, true);
      return $result['data'];
  }

  // Usage
  $topupId = '6901616fe9e88196b4eb64b2';
  $order = checkTopupStatus($topupId);

  echo "Status: {$order['status']}\n";
  echo "Type: {$order['type']}\n";
  echo "Number: {$order['number']}\n";

  if (isset($order['card_code'])) {
      echo "Card Code: {$order['card_code']}\n";
      echo "Transaction: {$order['num_trans']}\n";
  }
  ?>
  ```

  ```bash cURL theme={null}
  curl https://api.oneclickdz.com/v3/internet/check-id/6901616fe9e88196b4eb64b2 \
    -H "X-Access-Token: YOUR_API_KEY"
  ```
</CodeGroup>

## Exemples de réponse

### En cours de traitement

```json theme={null}
{
  "success": true,
  "data": {
    "_id": "6901616fe9e88196b4eb64b2",
    "ref": "order-123456",
    "status": "HANDLING",
    "type": "ADSL",
    "number": "036362608",
    "topup_amount": 1000,
    "created_at": "2025-11-01T12:00:00.000Z"
  }
}
```

### Exécuté (Succès)

```json theme={null}
{
  "success": true,
  "data": {
    "_id": "6901616fe9e88196b4eb64b2",
    "ref": "order-123456",
    "status": "FULFILLED",
    "type": "ADSL",
    "number": "036362608",
    "topup_amount": 1000,
    "card_code": "123456789012",
    "num_trans": "AT-2025-12345",
    "date_traitement": "2025-11-01T12:00:45.000Z",
    "created_at": "2025-11-01T12:00:00.000Z"
  }
}
```

### En file d'attente (Planifié)

```json theme={null}
{
  "success": true,
  "data": {
    "_id": "6901616fe9e88196b4eb64b2",
    "ref": "order-123456",
    "status": "QUEUED",
    "type": "ADSL",
    "number": "036362608",
    "topup_amount": 1000,
    "created_at": "2025-11-01T12:00:00.000Z"
  }
}
```

## Implémentation de base de l'interrogation

<CodeGroup>
  ```javascript Node.js theme={null}
  async function pollTopupUntilComplete(topupId, maxAttempts = 60) {
    const pollInterval = 5000; // 5 seconds
    
    for (let attempt = 1; attempt <= maxAttempts; attempt++) {
      console.log(`Polling attempt ${attempt}/${maxAttempts}`);
      
      const order = await checkTopupStatus(topupId);
      
      // Check if order reached final state
      const finalStates = ['FULFILLED', 'REFUNDED', 'QUEUED'];
      if (finalStates.includes(order.status)) {
        console.log(`Order completed with status: ${order.status}`);
        return order;
      }
      
      // Wait before next poll
      if (attempt < maxAttempts) {
        await new Promise(resolve => setTimeout(resolve, pollInterval));
      }
    }
    
    throw new Error('Polling timeout - order still processing');
  }

  // Usage
  try {
    const order = await pollTopupUntilComplete('6901616fe9e88196b4eb64b2');
    
    if (order.status === 'FULFILLED') {
      console.log('✅ Card delivered:', order.card_code);
    } else if (order.status === 'QUEUED') {
      console.log('⏰ Order scheduled for later');
    } else if (order.status === 'REFUNDED') {
      console.log('❌ Order failed and refunded');
    }
  } catch (error) {
    console.error('Polling failed:', error.message);
  }
  ```

  ```python Python theme={null}
  import time

  def poll_topup_until_complete(topup_id, max_attempts=60):
      poll_interval = 5  # 5 seconds
      
      for attempt in range(1, max_attempts + 1):
          print(f"Polling attempt {attempt}/{max_attempts}")
          
          order = check_topup_status(topup_id)
          
          # Check if order reached final state
          final_states = ['FULFILLED', 'REFUNDED', 'QUEUED']
          if order['status'] in final_states:
              print(f"Order completed with status: {order['status']}")
              return order
          
          # Wait before next poll
          if attempt < max_attempts:
              time.sleep(poll_interval)
      
      raise Exception('Polling timeout - order still processing')

  # Usage
  try:
      order = poll_topup_until_complete('6901616fe9e88196b4eb64b2')
      
      if order['status'] == 'FULFILLED':
          print(f"✅ Card delivered: {order['card_code']}")
      elif order['status'] == 'QUEUED':
          print('⏰ Order scheduled for later')
      elif order['status'] == 'REFUNDED':
          print('❌ Order failed and refunded')
  except Exception as e:
      print(f"Polling failed: {e}")
  ```

  ```php PHP theme={null}
  <?php

  function pollTopupUntilComplete($topupId, $maxAttempts = 60) {
      $pollInterval = 5; // 5 seconds
      
      for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
          error_log("Polling attempt {$attempt}/{$maxAttempts}");
          
          $order = checkTopupStatus($topupId);
          
          // Check if order reached final state
          $finalStates = ['FULFILLED', 'REFUNDED', 'QUEUED'];
          if (in_array($order['status'], $finalStates)) {
              error_log("Order completed with status: {$order['status']}");
              return $order;
          }
          
          // Wait before next poll
          if ($attempt < $maxAttempts) {
              sleep($pollInterval);
          }
      }
      
      throw new Exception('Polling timeout - order still processing');
  }

  // Usage
  try {
      $order = pollTopupUntilComplete('6901616fe9e88196b4eb64b2');
      
      if ($order['status'] === 'FULFILLED') {
          echo "✅ Card delivered: {$order['card_code']}\n";
      } elseif ($order['status'] === 'QUEUED') {
          echo "⏰ Order scheduled for later\n";
      } elseif ($order['status'] === 'REFUNDED') {
          echo "❌ Order failed and refunded\n";
      }
  } catch (Exception $e) {
      echo "Polling failed: " . $e->getMessage() . "\n";
  }
  ?>
  ```
</CodeGroup>

## Stratégie d'interrogation adaptative

Ajustez la fréquence d'interrogation selon le temps écoulé :

```javascript theme={null}
async function pollTopupAdaptive(topupId, maxDuration = 5 * 60 * 1000) {
  const startTime = Date.now();
  let pollInterval = 3000; // Start with 3 seconds
  
  while (Date.now() - startTime < maxDuration) {
    const order = await checkTopupStatus(topupId);
    
    // Check for final state
    const finalStates = ['FULFILLED', 'REFUNDED', 'QUEUED'];
    if (finalStates.includes(order.status)) {
      return order;
    }
    
    // Adaptive interval: increase as time passes
    const elapsed = Date.now() - startTime;
    if (elapsed > 60000) {
      pollInterval = 10000; // 10 seconds after 1 minute
    } else if (elapsed > 30000) {
      pollInterval = 5000; // 5 seconds after 30 seconds
    }
    
    await new Promise(resolve => setTimeout(resolve, pollInterval));
  }
  
  throw new Error('Order processing timeout');
}
```

## Gestion des résultats de commande

<CodeGroup>
  ```javascript Node.js theme={null}
  async function handleTopupResult(topupId, order) {
    switch (order.status) {
      case 'FULFILLED':
        console.log(`✅ Order fulfilled`);
        console.log(`Card: ${order.card_code}`);
        
        await db.internetOrders.updateOne(
          { topupId },
          { $set: { status: 'FULFILLED', cardCode: order.card_code, fulfilledAt: new Date() } }
        );
        
        await deliverCard(order);
        break;
      
      case 'QUEUED':
        console.log(`⏰ Order scheduled for later delivery`);
        
        await db.internetOrders.updateOne(
          { topupId },
          { $set: { status: 'SCHEDULED', nextCheckAt: new Date(Date.now() + 24 * 60 * 60 * 1000) } }
        );
        
        await scheduleRecheck(topupId, 24 * 60 * 60 * 1000);
        await notifyCustomer(order, 'Your order is scheduled and will be delivered within 48 hours.');
        break;
      
      case 'REFUNDED':
        console.log(`❌ Order failed and refunded`);
        
        await db.internetOrders.updateOne(
          { topupId },
          { $set: { status: 'REFUNDED', refundedAt: new Date() } }
        );
        
        await notifyCustomer(order, 'Your order could not be completed. A full refund has been issued.');
        break;
    }
  }
  ```

  ```python Python theme={null}
  from datetime import datetime, timedelta

  async def handle_topup_result(topup_id, order):
      if order['status'] == 'FULFILLED':
          print('✅ Order fulfilled')
          
          db.internet_orders.update_one(
              {'topupId': topup_id},
              {'$set': {'status': 'FULFILLED', 'cardCode': order['card_code'], 'fulfilledAt': datetime.now()}}
          )
          
          await deliver_card(order)
      
      elif order['status'] == 'QUEUED':
          print('⏰ Order scheduled for later delivery')
          
          db.internet_orders.update_one(
              {'topupId': topup_id},
              {'$set': {'status': 'SCHEDULED', 'nextCheckAt': datetime.now() + timedelta(hours=24)}}
          )
          
          await schedule_recheck(topup_id, 24 * 60 * 60 * 1000)
          await notify_customer(order, 'Your order is scheduled and will be delivered within 48 hours.')
      
      elif order['status'] == 'REFUNDED':
          print('❌ Order failed and refunded')
          
          db.internet_orders.update_one(
              {'topupId': topup_id},
              {'$set': {'status': 'REFUNDED', 'refundedAt': datetime.now()}}
          )
          
          await notify_customer(order, 'Your order could not be completed. A full refund has been issued.')
  ```

  ```php PHP theme={null}
  <?php

  function handleTopupResult($topupId, $order) {
      switch ($order['status']) {
          case 'FULFILLED':
              updateOrderStatus($topupId, 'FULFILLED', [
                  'cardCode' => $order['card_code'],
                  'fulfilledAt' => date('Y-m-d H:i:s')
              ]);
              deliverCard($order);
              break;
          
          case 'QUEUED':
              updateOrderStatus($topupId, 'SCHEDULED', [
                  'nextCheckAt' => date('Y-m-d H:i:s', time() + 24 * 60 * 60)
              ]);
              scheduleRecheck($topupId, 24 * 60 * 60);
              notifyCustomer($order, 'Your order is scheduled and will be delivered within 48 hours.');
              break;
          
          case 'REFUNDED':
              updateOrderStatus($topupId, 'REFUNDED', ['refundedAt' => date('Y-m-d H:i:s')]);
              notifyCustomer($order, 'Your order could not be completed. A full refund has been issued.');
              break;
      }
  }
  ?>
  ```
</CodeGroup>

## Gestion du statut QUEUED

<Info>
  **Les commandes QUEUED ne sont pas des échecs !** Elles sont programmées pour être livrées dans les 12 à 48 heures.
</Info>

```javascript theme={null}
async function scheduleRecheck(topupId, delayMs) {
  await recheckQueue.add(
    'recheck-topup',
    { topupId },
    {
      delay: delayMs,
      attempts: 3,
      backoff: { type: 'exponential', delay: 3600000 },
    }
  );
  
  console.log(`Scheduled recheck for ${topupId} in ${delayMs / 1000 / 60 / 60} hours`);
}

recheckQueue.process('recheck-topup', async (job) => {
  const { topupId } = job.data;
  const order = await checkTopupStatus(topupId);
  
  if (order.status === 'QUEUED') {
    await scheduleRecheck(topupId, 12 * 60 * 60 * 1000);
  } else {
    await handleTopupResult(topupId, order);
  }
});
```

## Bonnes pratiques

<CardGroup cols={2}>
  <Card title="Interroger toutes les 5-10 secondes" icon="clock">
    Équilibre entre réactivité et charge API
  </Card>

  <Card title="Gérer QUEUED correctement" icon="calendar">
    Ne pas traiter QUEUED comme un échec - planifier des nouvelles vérifications
  </Card>

  <Card title="Définir des limites de délai" icon="stopwatch">
    Échouer gracieusement après 5 minutes d'interrogation
  </Card>

  <Card title="Mettre à jour la base de données" icon="database">
    Stocker les changements de statut et les détails de carte
  </Card>
</CardGroup>

## Étapes suivantes

<CardGroup cols={3}>
  <Card title="Livrer les cartes" icon="file-code" href="/fr/internet-topup-guides/5-card-delivery">
    Livrer les codes de carte en toute sécurité aux clients
  </Card>

  <Card title="Envoyer les recharges" icon="paper-plane" href="/fr/internet-topup-guides/3-sending-topups">
    Soumettre des commandes avec validation
  </Card>

  <Card title="Référence API" icon="book" href="/fr/api-reference/internet/check-by-id">
    Documentation complète de l'endpoint
  </Card>

  <Card title="Vue d'ensemble" icon="book-open" href="/fr/internet-topup-guides/overview">
    Retour à la vue d'ensemble de l'intégration
  </Card>

  <Card title="Valider les numéros" icon="check" href="/fr/internet-topup-guides/2-validation">
    Vérifier les numéros de téléphone
  </Card>

  <Card title="Charger les produits" icon="list" href="/fr/internet-topup-guides/1-loading-products">
    Récupérer les cartes disponibles
  </Card>
</CardGroup>
