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

# Checking Product Details

> Get real-time pricing, stock, and denomination details for gift card products

## Overview

Before placing orders, check product details to get real-time pricing, available denominations (types), and stock levels. This endpoint returns wholesale prices personalized to your account.

<Warning>
  **Never show wholesale prices to customers.** Apply your markup before
  displaying.
</Warning>

## API Reference

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

## Basic Product Check

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

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

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

  // Usage
  const productId = "507f1f77bcf86cd799439011";
  const product = await checkProduct(productId);

  console.log(`Product: ${product.productTitle}`);
  console.log(`Available types: ${product.types.length}`);
  product.types.forEach((type) => {
    console.log(`  - ${type.name}: ${type.price} DA (stock: ${type.quantity})`);
  });
  ```

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

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

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

  # Usage
  product_id = '507f1f77bcf86cd799439011'
  product = check_product(product_id)

  print(f"Product: {product['productTitle']}")
  print(f"Available types: {len(product['types'])}")
  for ptype in product['types']:
      print(f"  - {ptype['name']}: {ptype['price']} DA (stock: {ptype['quantity']})")
  ```

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

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

      $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 product: " . $httpCode);
      }

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

  // Usage
  $productId = '507f1f77bcf86cd799439011';
  $product = checkProduct($productId, getenv('API_KEY'));

  echo "Product: " . $product['productTitle'] . "\n";
  echo "Available types: " . count($product['types']) . "\n";
  foreach ($product['types'] as $type) {
      echo "  - {$type['name']}: {$type['price']} DA (stock: {$type['quantity']})\n";
  }
  ?>
  ```

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

## Response Structure

```json theme={null}
{
  "success": true,
  "data": {
    "productId": "507f1f77bcf86cd799439011",
    "productTitle": "PlayStation Network",
    "types": [
      {
        "id": "type_001",
        "name": "PSN 500 DA",
        "price": 490,
        "quantity": 150
      },
      {
        "id": "type_002",
        "name": "PSN 1000 DA",
        "price": 980,
        "quantity": 87
      },
      {
        "id": "type_003",
        "name": "PSN 2000 DA",
        "price": 1960,
        "quantity": 0
      }
    ]
  }
}
```

## Filtering Available Stock

Only show types that are in stock:

<CodeGroup>
  ```javascript Node.js theme={null}
  function getAvailableTypes(product) {
    return product.types.filter((type) => type.quantity > 0);
  }

  // Usage
  const product = await checkProduct(productId);
  const available = getAvailableTypes(product);

  if (available.length === 0) {
    console.log("Product currently out of stock");
  } else {
    console.log(`${available.length} denominations available`);
  }
  ```

  ```python Python theme={null}
  def get_available_types(product):
      return [t for t in product['types'] if t['quantity'] > 0]

  # Usage
  product = check_product(product_id)
  available = get_available_types(product)

  if not available:
      print('Product currently out of stock')
  else:
      print(f"{len(available)} denominations available")
  ```

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

  function getAvailableTypes($product) {
      return array_filter($product['types'], function($type) {
          return $type['quantity'] > 0;
      });
  }

  // Usage
  $product = checkProduct($productId, $apiKey);
  $available = array_values(getAvailableTypes($product));

  if (empty($available)) {
      echo "Product currently out of stock\n";
  } else {
      echo count($available) . " denominations available\n";
  }
  ?>
  ```
</CodeGroup>

## Applying Customer Markup

Add your profit margin to wholesale prices:

<CodeGroup>
  ```javascript Node.js theme={null}
  function applyMarkup(types, markupPercent = 5) {
    return types
      .filter((type) => type.quantity > 0)
      .map((type) => ({
        id: type.id,
        name: type.name,
        wholesalePrice: type.price, // Store but don't show
        customerPrice: Math.ceil(type.price * (1 + markupPercent / 100)),
        available: true,
      }));
  }

  // Usage
  const product = await checkProduct(productId);
  const customerPrices = applyMarkup(product.types, 5); // 5% markup

  customerPrices.forEach((type) => {
    console.log(`${type.name}: ${type.customerPrice} DA`);
    // Don't log wholesalePrice in production!
  });
  ```

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

  def apply_markup(types, markup_percent=5):
      available = [t for t in types if t['quantity'] > 0]

      return [
          {
              'id': t['id'],
              'name': t['name'],
              'wholesalePrice': t['price'],  # Store but don't show
              'customerPrice': math.ceil(t['price'] * (1 + markup_percent / 100)),
              'available': True
          }
          for t in available
      ]

  # Usage
  product = check_product(product_id)
  customer_prices = apply_markup(product['types'], markup_percent=5)

  for ptype in customer_prices:
      print(f"{ptype['name']}: {ptype['customerPrice']} DA")
  ```

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

  function applyMarkup($types, $markupPercent = 5) {
      $available = array_filter($types, function($type) {
          return $type['quantity'] > 0;
      });

      return array_map(function($type) use ($markupPercent) {
          return [
              'id' => $type['id'],
              'name' => $type['name'],
              'wholesalePrice' => $type['price'], // Store but don't show
              'customerPrice' => ceil($type['price'] * (1 + $markupPercent / 100)),
              'available' => true
          ];
      }, $available);
  }

  // Usage
  $product = checkProduct($productId, $apiKey);
  $customerPrices = applyMarkup($product['types'], 5); // 5% markup

  foreach ($customerPrices as $type) {
      echo "{$type['name']}: {$type['customerPrice']} DA\n";
  }
  ?>
  ```
</CodeGroup>

## Stock Validation Before Ordering

Always verify stock before allowing orders:

<CodeGroup>
  ```javascript Node.js theme={null}
  async function validateStock(productId, typeId, quantity) {
    const product = await checkProduct(productId);
    const type = product.types.find((t) => t.id === typeId);

    if (!type) {
      throw new Error("Invalid type ID");
    }

    if (type.quantity === 0) {
      throw new Error("Product out of stock");
    }

    if (type.quantity < quantity) {
      throw new Error(
        `Insufficient stock. Available: ${type.quantity}, Requested: ${quantity}`
      );
    }

    return {
      valid: true,
      type,
      totalCost: type.price * quantity,
    };
  }

  // Usage
  try {
    const validation = await validateStock(productId, "type_001", 5);
    console.log(`Order valid. Total cost: ${validation.totalCost} DA`);
  } catch (error) {
    console.error("Validation failed:", error.message);
  }
  ```

  ```python Python theme={null}
  def validate_stock(product_id, type_id, quantity):
      product = check_product(product_id)
      ptype = next((t for t in product['types'] if t['id'] == type_id), None)

      if not ptype:
          raise ValueError('Invalid type ID')

      if ptype['quantity'] == 0:
          raise ValueError('Product out of stock')

      if ptype['quantity'] < quantity:
          raise ValueError(
              f"Insufficient stock. Available: {ptype['quantity']}, Requested: {quantity}"
          )

      return {
          'valid': True,
          'type': ptype,
          'totalCost': ptype['price'] * quantity
      }

  # Usage
  try:
      validation = validate_stock(product_id, 'type_001', 5)
      print(f"Order valid. Total cost: {validation['totalCost']} DA")
  except ValueError as e:
      print(f"Validation failed: {e}")
  ```

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

  function validateStock($productId, $typeId, $quantity, $apiKey) {
      $product = checkProduct($productId, $apiKey);

      $type = null;
      foreach ($product['types'] as $t) {
          if ($t['id'] === $typeId) {
              $type = $t;
              break;
          }
      }

      if ($type === null) {
          throw new Exception('Invalid type ID');
      }

      if ($type['quantity'] === 0) {
          throw new Exception('Product out of stock');
      }

      if ($type['quantity'] < $quantity) {
          throw new Exception(
              "Insufficient stock. Available: {$type['quantity']}, Requested: {$quantity}"
          );
      }

      return [
          'valid' => true,
          'type' => $type,
          'totalCost' => $type['price'] * $quantity
      ];
  }

  // Usage
  try {
      $validation = validateStock($productId, 'type_001', 5, $apiKey);
      echo "Order valid. Total cost: {$validation['totalCost']} DA\n";
  } catch (Exception $e) {
      echo "Validation failed: " . $e->getMessage() . "\n";
  }
  ?>
  ```
</CodeGroup>

## Best Practices

<CardGroup cols={2}>
  <Card title="Check Before Order" icon="magnifying-glass">
    Always verify stock before placing orders
  </Card>

  <Card title="Hide Wholesale Prices" icon="eye-slash">
    Never display raw `price` values to customers
  </Card>

  <Card title="Cache Briefly" icon="clock">
    Cache for 1-2 minutes during checkout flow
  </Card>

  <Card title="Handle Out of Stock" icon="ban">
    Gracefully handle zero quantity scenarios
  </Card>
</CardGroup>

## Error Handling

```javascript theme={null}
async function checkProductSafely(productId) {
  try {
    return await checkProduct(productId);
  } catch (error) {
    if (error.message.includes("404")) {
      throw new Error("Product not found or disabled");
    }

    if (error.message.includes("401")) {
      throw new Error("Invalid API key");
    }

    console.error("Failed to check product:", error);
    throw new Error("Unable to load product details. Please try again.");
  }
}
```

## Next Steps

<CardGroup cols={3}>
  <Card title="Place Orders" icon="cart-shopping" href="/en/gift-card-guides/3-placing-orders">
    Submit validated orders
  </Card>

  <Card title="Track Status" icon="chart-line" href="/en/gift-card-guides/4-status-tracking">
    Monitor order fulfillment
  </Card>

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

  <Card title="Load Catalog" icon="list" href="/en/gift-card-guides/1-loading-catalog">
    Fetch available products
  </Card>

  <Card title="Overview" icon="book-open" href="/en/gift-card-guides/overview">
    Back to integration overview
  </Card>

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