> ## 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 commandes de cartes-cadeaux avec des stratégies d'interrogation simples

## Vue d'ensemble

Après avoir passé une commande, interrogez l'endpoint `/checkOrder` pour suivre le statut et récupérer les codes de carte lors de l'exécution. La plupart des commandes sont traitées en quelques secondes.

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

## Référence API

<Card title="GET /v3/gift-cards/checkOrder/{orderId}" icon="magnifying-glass" href="/fr/api-reference/gift-cards/check-order">
  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. Continuez l'interrogation. La plupart des commandes se résolvent en 30 secondes.
  </Accordion>

  <Accordion title="FULFILLED" icon="check-circle">
    **Succès !** Toutes les cartes livrées. `fulfilled_quantity === quantity`. Cartes disponibles dans le tableau `cards`.
  </Accordion>

  <Accordion title="PARTIALLY_FILLED" icon="triangle-exclamation">
    **Succès partiel.** Certaines cartes livrées, le reste annulé. `fulfilled_quantity < quantity`. Remboursement partiel émis automatiquement.
  </Accordion>

  <Accordion title="REFUNDED" icon="rotate-left">
    **Échec.** La commande a complètement échoué. `fulfilled_quantity === 0`. Remboursement intégral émis automatiquement.
  </Accordion>
</AccordionGroup>

## Tests en mode Sandbox

Utilisez le mode sandbox pour tester sans dépenser de solde réel :

<CardGroup cols={2}>
  <Card title="Tester une commande échouée" icon="circle-xmark">
    Utilisez `TEST_REFUND` comme type ID → Simule une commande échouée (statut REFUNDED)
  </Card>

  <Card title="Tester un succès partiel" icon="triangle-exclamation">
    Utilisez `TEST_PARTIAL` comme type ID → Simule une exécution à 50% (statut PARTIALLY\_FILLED)
  </Card>
</CardGroup>

```javascript Sandbox Example theme={null}
// Tester différents scénarios sans frais réels
const testScenarios = [
  {
    productId: "507f1f77bcf86cd799439011",
    typeId: "TEST_REFUND", // Will fail and refund
    quantity: 2,
  },
  {
    productId: "507f1f77bcf86cd799439011",
    typeId: "TEST_PARTIAL", // Will deliver 50% of cards
    quantity: 4,
  },
];

// Place test order
const order = await placeOrder(
  testScenarios[0].productId,
  testScenarios[0].typeId,
  testScenarios[0].quantity
);

// Poll for results
const result = await pollOrderUntilComplete(order.orderId);
console.log("Test result:", result.status);
```

## Vérification de statut de base

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

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

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

  // Usage
  const orderId = "6901616fe9e88196b4eb64b3";
  const order = await checkOrderStatus(orderId);

  console.log(`Status: ${order.status}`);
  console.log(`Quantity: ${order.quantity}`);

  if (order.cards) {
    console.log(`Cards delivered: ${order.cards.length}`);
  }
  ```

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

  def check_order_status(order_id):
      response = requests.get(
          f'https://api.oneclickdz.com/v3/gift-cards/checkOrder/{order_id}',
          headers={'X-Access-Token': os.getenv('API_KEY')}
      )

      response.raise_for_status()
      return response.json()['data']

  # Usage
  order_id = '6901616fe9e88196b4eb64b3'
  order = check_order_status(order_id)

  print(f"Status: {order['status']}")
  print(f"Quantity: {order['quantity']}")

  if 'cards' in order:
      print(f"Cards delivered: {len(order['cards'])}")
  ```

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

  function checkOrderStatus($orderId, $apiKey) {
      $url = "https://api.oneclickdz.com/v3/gift-cards/checkOrder/{$orderId}";

      $ch = curl_init($url);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, [
          'X-Access-Token: ' . $apiKey
      ]);

      $response = curl_exec($ch);
      $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
      curl_close($ch);

      if ($httpCode !== 200) {
          throw new Exception("Failed to check order: " . $httpCode);
      }

      $result = json_decode($response, true);
      return $result['data'];
  }

  // Usage
  $orderId = '6901616fe9e88196b4eb64b3';
  $order = checkOrderStatus($orderId, getenv('API_KEY'));

  echo "Status: {$order['status']}\n";
  echo "Quantity: {$order['quantity']}\n";

  if (isset($order['cards'])) {
      echo "Cards delivered: " . count($order['cards']) . "\n";
  }
  ?>
  ```

  ```bash cURL theme={null}
  curl https://api.oneclickdz.com/v3/gift-cards/checkOrder/6901616fe9e88196b4eb64b3 \
    -H "X-Access-Token: YOUR_API_KEY"
  ```
</CodeGroup>

## Exemples de réponse

### En cours de traitement

```json theme={null}
{
  "success": true,
  "data": {
    "_id": "6901616fe9e88196b4eb64b3",
    "status": "HANDLING",
    "quantity": 2,
    "product": "507f1f77bcf86cd799439011",
    "type": "type_001",
    "time": "2025-10-29T01:00:00.000Z"
  }
}
```

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

```json theme={null}
{
  "success": true,
  "data": {
    "_id": "6901616fe9e88196b4eb64b3",
    "status": "FULFILLED",
    "quantity": 2,
    "fulfilled_quantity": 2,
    "fulfilled_amount": 980,
    "price_per_card": 490,
    "cards": [
      {
        "value": "XXXX-XXXX-XXXX-XXXX",
        "serial": "123456789"
      },
      {
        "value": "YYYY-YYYY-YYYY-YYYY",
        "serial": "987654321"
      }
    ],
    "time": "2025-10-29T01:00:00.000Z"
  }
}
```

### Partiellement exécuté

```json theme={null}
{
  "success": true,
  "data": {
    "_id": "6901616fe9e88196b4eb64b3",
    "status": "PARTIALLY_FILLED",
    "quantity": 5,
    "fulfilled_quantity": 3,
    "fulfilled_amount": 1470,
    "price_per_card": 490,
    "cards": [
      {
        "value": "AAAA-AAAA-AAAA-AAAA",
        "serial": "111111111"
      },
      {
        "value": "BBBB-BBBB-BBBB-BBBB",
        "serial": "222222222"
      },
      {
        "value": "CCCC-CCCC-CCCC-CCCC",
        "serial": "333333333"
      }
    ],
    "time": "2025-10-29T01:00:00.000Z"
  }
}
```

## Implémentation de l'interrogation simple

<CodeGroup>
  ```javascript Node.js theme={null}
  async function pollOrderUntilComplete(orderId, maxAttempts = 60) {
    for (let attempt = 1; attempt <= maxAttempts; attempt++) {
      console.log(`Checking order status (${attempt}/${maxAttempts})...`);

      const order = await checkOrderStatus(orderId);

      // Order is complete
      if (["FULFILLED", "PARTIALLY_FILLED", "REFUNDED"].includes(order.status)) {
        console.log(`Order completed: ${order.status}`);
        return order;
      }

      // Wait 5 seconds before next check
      if (attempt < maxAttempts) {
        await new Promise((resolve) => setTimeout(resolve, 5000));
      }
    }

    throw new Error("Order still processing after timeout");
  }

  // Usage
  try {
    const order = await pollOrderUntilComplete("6901616fe9e88196b4eb64b3");

    if (order.status === "FULFILLED") {
      console.log("Success! Cards:", order.cards);
    } else if (order.status === "PARTIALLY_FILLED") {
      console.log(
        `Partial delivery: ${order.fulfilled_quantity}/${order.quantity}`
      );
    } else {
      console.log("Order failed and refunded");
    }
  } catch (error) {
    console.error("Error:", error.message);
  }
  ```

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

  def poll_order_until_complete(order_id, max_attempts=60):
      for attempt in range(1, max_attempts + 1):
          print(f"Checking order status ({attempt}/{max_attempts})...")

          order = check_order_status(order_id)

          # Order is complete
          if order['status'] in ['FULFILLED', 'PARTIALLY_FILLED', 'REFUNDED']:
              print(f"Order completed: {order['status']}")
              return order

          # Wait 5 seconds before next check
          if attempt < max_attempts:
              time.sleep(5)

      raise Exception('Order still processing after timeout')

  # Usage
  try:
      order = poll_order_until_complete('6901616fe9e88196b4eb64b3')

      if order['status'] == 'FULFILLED':
          print(f"Success! Cards: {len(order['cards'])}")
      elif order['status'] == 'PARTIALLY_FILLED':
          print(f"Partial delivery: {order['fulfilled_quantity']}/{order['quantity']}")
      else:
          print('Order failed and refunded')
  except Exception as e:
      print(f"Error: {e}")
  ```

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

  function pollOrderUntilComplete($orderId, $apiKey, $maxAttempts = 60) {
      for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
          echo "Checking order status ({$attempt}/{$maxAttempts})...\n";

          $order = checkOrderStatus($orderId, $apiKey);

          // Order is complete
          $finalStates = ['FULFILLED', 'PARTIALLY_FILLED', 'REFUNDED'];
          if (in_array($order['status'], $finalStates)) {
              echo "Order completed: {$order['status']}\n";
              return $order;
          }

          // Wait 5 seconds before next check
          if ($attempt < $maxAttempts) {
              sleep(5);
          }
      }

      throw new Exception('Order still processing after timeout');
  }

  // Usage
  try {
      $order = pollOrderUntilComplete('6901616fe9e88196b4eb64b3', getenv('API_KEY'));

      if ($order['status'] === 'FULFILLED') {
          echo "Success! Cards: " . count($order['cards']) . "\n";
      } elseif ($order['status'] === 'PARTIALLY_FILLED') {
          echo "Partial delivery: {$order['fulfilled_quantity']}/{$order['quantity']}\n";
      } else {
          echo "Order failed and refunded\n";
      }
  } catch (Exception $e) {
      echo "Error: " . $e->getMessage() . "\n";
  }
  ?>
  ```
</CodeGroup>

## Gestion des différents résultats

<CodeGroup>
  ```javascript Node.js theme={null}
  function handleOrderResult(order) {
    switch (order.status) {
      case "FULFILLED":
        console.log(`✅ Success: ${order.fulfilled_quantity} cards delivered`);
        console.log(`Cost: ${order.fulfilled_amount} DA`);

        // Process each card
        order.cards.forEach((card, index) => {
          console.log(`Card ${index + 1}: ${card.value}`);
          // Encrypt and deliver to customer
        });
        break;

      case "PARTIALLY_FILLED":
        console.log(
          `⚠️ Partial: ${order.fulfilled_quantity}/${order.quantity} cards`
        );
        console.log(`Charged: ${order.fulfilled_amount} DA`);

        const refund =
          (order.quantity - order.fulfilled_quantity) * order.price_per_card;
        console.log(`Refunded: ${refund} DA`);

        // Deliver available cards
        order.cards.forEach((card) => {
          console.log(`Delivered: ${card.value}`);
        });
        break;

      case "REFUNDED":
        console.log("❌ Order failed - full refund issued");
        break;
    }
  }
  ```

  ```python Python theme={null}
  def handle_order_result(order):
      if order['status'] == 'FULFILLED':
          print(f"✅ Success: {order['fulfilled_quantity']} cards delivered")
          print(f"Cost: {order['fulfilled_amount']} DA")

          # Process each card
          for i, card in enumerate(order['cards']):
              print(f"Card {i + 1}: {card['value']}")
              # Encrypt and deliver to customer

      elif order['status'] == 'PARTIALLY_FILLED':
          print(f"⚠️ Partial: {order['fulfilled_quantity']}/{order['quantity']} cards")
          print(f"Charged: {order['fulfilled_amount']} DA")

          refund = (order['quantity'] - order['fulfilled_quantity']) * order['price_per_card']
          print(f"Refunded: {refund} DA")

          # Deliver available cards
          for card in order['cards']:
              print(f"Delivered: {card['value']}")

      elif order['status'] == 'REFUNDED':
          print('❌ Order failed - full refund issued')
  ```

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

  function handleOrderResult($order) {
      switch ($order['status']) {
          case 'FULFILLED':
              echo "✅ Success: {$order['fulfilled_quantity']} cards delivered\n";
              echo "Cost: {$order['fulfilled_amount']} DA\n";

              // Process each card
              foreach ($order['cards'] as $index => $card) {
                  echo "Card " . ($index + 1) . ": {$card['value']}\n";
                  // Encrypt and deliver to customer
              }
              break;

          case 'PARTIALLY_FILLED':
              echo "⚠️ Partial: {$order['fulfilled_quantity']}/{$order['quantity']} cards\n";
              echo "Charged: {$order['fulfilled_amount']} DA\n";

              $refund = ($order['quantity'] - $order['fulfilled_quantity']) * $order['price_per_card'];
              echo "Refunded: {$refund} DA\n";

              // Deliver available cards
              foreach ($order['cards'] as $card) {
                  echo "Delivered: {$card['value']}\n";
              }
              break;

          case 'REFUNDED':
              echo "❌ Order failed - full refund issued\n";
              break;
      }
  }
  ?>
  ```
</CodeGroup>

## Exemple complet d'interrogation

```javascript theme={null}
async function processOrder(productId, typeId, quantity) {
  try {
    // 1. Passer la commande
    console.log("Placing order...");
    const order = await placeOrder(productId, typeId, quantity);
    console.log(`Order placed: ${order.orderId}`);

    // 2. Interroger jusqu'à l'achèvement
    console.log("Waiting for fulfillment...");
    const result = await pollOrderUntilComplete(order.orderId);

    // 3. Traiter le résultat
    handleOrderResult(result);

    return result;
  } catch (error) {
    console.error("Order processing failed:", error.message);
    throw error;
  }
}

// Usage
await processOrder("507f1f77bcf86cd799439011", "type_001", 2);
```

## Bonnes pratiques

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

  <Card title="Définir un délai d'expiration" icon="stopwatch">
    Arrêter l'interrogation après 5 minutes (60 tentatives)
  </Card>

  <Card title="Gérer tous les états" icon="list-check">
    Traiter FULFILLED, PARTIALLY\_FILLED et REFUNDED
  </Card>

  <Card title="Tester d'abord" icon="flask">
    Utiliser le mode sandbox avec TEST\_REFUND et TEST\_PARTIAL
  </Card>
</CardGroup>

## Étapes suivantes

<CardGroup cols={3}>
  <Card title="Livraison sécurisée" icon="lock" href="/fr/gift-card-guides/5-secure-delivery">
    Chiffrer et livrer les cartes aux clients
  </Card>

  <Card title="Passer des commandes" icon="cart-shopping" href="/fr/gift-card-guides/3-placing-orders">
    Soumettre des commandes avec validation
  </Card>

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