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

# Status Tracking & Polling

> Monitor gift card order fulfillment with simple polling strategies

## Overview

After placing an order, poll the `/checkOrder` endpoint to track status and retrieve card codes when fulfilled. Most orders process within seconds.

<Info>
  Poll every **5-10 seconds** until order reaches a final state: FULFILLED,
  PARTIALLY\_FILLED, or REFUNDED.
</Info>

## API Reference

<Card title="GET /v3/gift-cards/checkOrder/{orderId}" icon="magnifying-glass" href="/en/api-reference/gift-cards/check-order">
  Complete endpoint documentation
</Card>

## Order Status Values

<AccordionGroup>
  <Accordion title="HANDLING" icon="spinner">
    Order is processing. Continue polling. Most orders resolve within 30 seconds.
  </Accordion>

  <Accordion title="FULFILLED" icon="check-circle">
    **Success!** All cards delivered. `fulfilled_quantity === quantity`. Cards available in `cards` array.
  </Accordion>

  <Accordion title="PARTIALLY_FILLED" icon="triangle-exclamation">
    **Partial success.** Some cards delivered, rest cancelled. `fulfilled_quantity < quantity`. Partial refund issued automatically.
  </Accordion>

  <Accordion title="REFUNDED" icon="rotate-left">
    **Failed.** Order completely failed. `fulfilled_quantity === 0`. Full refund issued automatically.
  </Accordion>
</AccordionGroup>

## Sandbox Testing

Use sandbox mode to test without spending real balance:

<CardGroup cols={2}>
  <Card title="Test Failed Order" icon="circle-xmark">
    Use `TEST_REFUND` as type ID → Simulates failed order (REFUNDED status)
  </Card>

  <Card title="Test Partial Success" icon="triangle-exclamation">
    Use `TEST_PARTIAL` as type ID → Simulates 50% fulfillment (PARTIALLY\_FILLED
    status)
  </Card>
</CardGroup>

```javascript Sandbox Example theme={null}
// Test different scenarios without real charges
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);
```

## Basic Status Check

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

## Response Examples

### Handling (Processing)

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

### Fulfilled (Success)

```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"
  }
}
```

### Partially Filled

```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"
  }
}
```

## Simple Polling Implementation

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

## Handling Different Results

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

## Complete Polling Example

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

    // 2. Poll for completion
    console.log("Waiting for fulfillment...");
    const result = await pollOrderUntilComplete(order.orderId);

    // 3. Handle result
    handleOrderResult(result);

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

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

## Best Practices

<CardGroup cols={2}>
  <Card title="Poll Every 5 Seconds" icon="clock">
    Balance between responsiveness and API load
  </Card>

  <Card title="Set Timeout" icon="stopwatch">
    Stop polling after 5 minutes (60 attempts)
  </Card>

  <Card title="Handle All States" icon="list-check">
    Process FULFILLED, PARTIALLY\_FILLED, and REFUNDED
  </Card>

  <Card title="Test First" icon="flask">
    Use sandbox mode with TEST\_REFUND and TEST\_PARTIAL
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={3}>
  <Card title="Secure Delivery" icon="lock" href="/en/gift-card-guides/5-secure-delivery">
    Encrypt and deliver cards to customers
  </Card>

  <Card title="Place Orders" icon="cart-shopping" href="/en/gift-card-guides/3-placing-orders">
    Submit orders with validation
  </Card>

  <Card title="API Reference" icon="book" href="/en/api-reference/gift-cards/check-order">
    Complete endpoint documentation
  </Card>
</CardGroup>
