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

# Vérification des Détails du Produit

> Obtenir les tarifs en temps réel, le stock et les détails des dénominations pour les produits de cartes-cadeaux

## Vue d'ensemble

Avant de passer des commandes, vérifiez les détails des produits pour obtenir les tarifs en temps réel, les dénominations disponibles (types) et les niveaux de stock. Cet endpoint retourne des prix de gros personnalisés pour votre compte.

<Warning>
  **N'affichez jamais les prix de gros aux clients.** Appliquez votre marge avant d'afficher.
</Warning>

## Référence API

<Card title="GET /v3/gift-cards/checkProduct/{productId}" icon="magnifying-glass" href="/fr/api-reference/gift-cards/check-product">
  Documentation complète de l'endpoint
</Card>

## Vérification de base d'un produit

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

## Structure de la réponse

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

## Filtrage du stock disponible

N'afficher que les types en 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>

## Application de la marge client

Ajoutez votre marge bénéficiaire aux prix de gros :

<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`);
    // Ne pas journaliser wholesalePrice en 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>

## Validation du stock avant la commande

Vérifiez toujours le stock avant d'autoriser les commandes :

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

## Bonnes pratiques

<CardGroup cols={2}>
  <Card title="Vérifier avant la commande" icon="magnifying-glass">
    Vérifiez toujours le stock avant de passer des commandes
  </Card>

  <Card title="Masquer les prix de gros" icon="eye-slash">
    N'affichez jamais les valeurs brutes de `price` aux clients
  </Card>

  <Card title="Mettre en cache brièvement" icon="clock">
    Mettez en cache pendant 1-2 minutes lors du flux de paiement
  </Card>

  <Card title="Gérer les ruptures de stock" icon="ban">
    Gérez gracieusement les scénarios de quantité nulle
  </Card>
</CardGroup>

## Gestion des erreurs

```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.");
  }
}
```

## Étapes suivantes

<CardGroup cols={3}>
  <Card title="Passer des commandes" icon="cart-shopping" href="/fr/gift-card-guides/3-placing-orders">
    Soumettre des commandes validées
  </Card>

  <Card title="Suivre le statut" icon="chart-line" href="/fr/gift-card-guides/4-status-tracking">
    Surveiller l'exécution des commandes
  </Card>

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

  <Card title="Charger le catalogue" icon="list" href="/fr/gift-card-guides/1-loading-catalog">
    Récupérer les produits disponibles
  </Card>

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

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