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

# Validation du Numéro de Téléphone

> Valider les numéros de téléphone ADSL et 4G avant de traiter les commandes

## Vue d'ensemble

Validez toujours les numéros de téléphone avant de soumettre des commandes de recharge internet. Cela prévient les erreurs, réduit les remboursements et améliore l'expérience utilisateur en détectant immédiatement les problèmes de format.

<Warning>
  **Étape critique :** La validation prévient 90% des échecs de commande. Ne sautez jamais cette étape.
</Warning>

## Référence API

<Card title="GET /v3/internet/check-number" icon="check" href="/fr/api-reference/internet/validate-number">
  Documentation complète de l'endpoint
</Card>

## Formats de numéro de téléphone

<Tabs>
  <Tab title="ADSL">
    **Modèle :** `^0[0-9]{8}$`

    **Description :** 9 chiffres commençant par 0

    **Exemples valides :**

    * ✅ `036362608`
    * ✅ `031417237`
    * ✅ `021123456`

    **Exemples invalides :**

    * ❌ `36362608` - Zéro de tête manquant
    * ❌ `0363626081` - Trop long (10 chiffres)
    * ❌ `213636362608` - Format incorrect (contient l'indicatif pays)
    * ❌ `+213636362608` - Format incorrect (contient +)
  </Tab>

  <Tab title="4G LTE">
    **Modèle :** `^213[0-9]{9}$`

    **Description :** 12 chiffres commençant par 213 (indicatif pays)

    **Exemples valides :**

    * ✅ `213472731602`
    * ✅ `213665983439`
    * ✅ `213778037340`

    **Exemples invalides :**

    * ❌ `0665983439` - Indicatif pays manquant
    * ❌ `665983439` - Indicatif pays manquant
    * ❌ `+213665983439` - Contient le symbole +
    * ❌ `2136659834399` - Trop long
  </Tab>
</Tabs>

## Validation de base

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

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.error.message);
    }

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

  // Usage
  try {
    await validateInternetNumber('ADSL', '036362608');
    console.log('✅ Number is valid');
  } catch (error) {
    console.error('❌ Validation failed:', error.message);
  }
  ```

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

  def validate_internet_number(service_type, number):
      response = requests.get(
          'https://api.oneclickdz.com/v3/internet/check-number',
          headers={'X-Access-Token': os.getenv('API_KEY')},
          params={'type': service_type, 'number': number}
      )
      
      if not response.ok:
          error = response.json()
          raise ValueError(error['error']['message'])
      
      return response.json()['data']

  # Usage
  try:
      validate_internet_number('ADSL', '036362608')
      print('✅ Number is valid')
  except ValueError as e:
      print(f'❌ Validation failed: {e}')
  ```

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

  function validateInternetNumber($type, $number) {
      $url = "https://api.oneclickdz.com/v3/internet/check-number";
      $url .= "?type=" . urlencode($type) . "&number=" . urlencode($number);
      
      $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) {
          $error = json_decode($response, true);
          throw new Exception($error['error']['message']);
      }
      
      return json_decode($response, true)['data'];
  }

  // Usage
  try {
      validateInternetNumber('ADSL', '036362608');
      echo "✅ Number is valid\n";
  } catch (Exception $e) {
      echo "❌ Validation failed: " . $e->getMessage() . "\n";
  }
  ?>
  ```

  ```bash cURL theme={null}
  # Valider un numéro ADSL
  curl "https://api.oneclickdz.com/v3/internet/check-number?type=ADSL&number=036362608" \
    -H "X-Access-Token: YOUR_API_KEY"

  # Valider un numéro 4G
  curl "https://api.oneclickdz.com/v3/internet/check-number?type=4G&number=213665983439" \
    -H "X-Access-Token: YOUR_API_KEY"
  ```
</CodeGroup>

## Validation de format côté client

Validez le format côté client en premier pour un retour instantané :

<CodeGroup>
  ```javascript Node.js theme={null}
  function validateADSLFormat(number) {
    const pattern = /^0[0-9]{8}$/;
    return pattern.test(number);
  }

  function validate4GFormat(number) {
    const pattern = /^213[0-9]{9}$/;
    return pattern.test(number);
  }

  function validateFormat(type, number) {
    if (type === 'ADSL') {
      return validateADSLFormat(number);
    } else if (type === '4G') {
      return validate4GFormat(number);
    }
    return false;
  }

  // Usage
  const number = '036362608';
  const type = 'ADSL';

  if (!validateFormat(type, number)) {
    console.error('Invalid format. Please check the number.');
  } else {
    // Le format est correct, validez maintenant avec l'API
    await validateInternetNumber(type, number);
  }
  ```

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

  def validate_adsl_format(number):
      pattern = r'^0[0-9]{8}$'
      return bool(re.match(pattern, number))

  def validate_4g_format(number):
      pattern = r'^213[0-9]{9}$'
      return bool(re.match(pattern, number))

  def validate_format(service_type, number):
      if service_type == 'ADSL':
          return validate_adsl_format(number)
      elif service_type == '4G':
          return validate_4g_format(number)
      return False

  # Usage
  number = '036362608'
  service_type = 'ADSL'

  if not validate_format(service_type, number):
      print('Invalid format. Please check the number.')
  else:
      # Le format est correct, validez maintenant avec l'API
      validate_internet_number(service_type, number)
  ```

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

  function validateADSLFormat($number) {
      return preg_match('/^0[0-9]{8}$/', $number) === 1;
  }

  function validate4GFormat($number) {
      return preg_match('/^213[0-9]{9}$/', $number) === 1;
  }

  function validateFormat($type, $number) {
      if ($type === 'ADSL') {
          return validateADSLFormat($number);
      } elseif ($type === '4G') {
          return validate4GFormat($number);
      }
      return false;
  }

  // Usage
  $number = '036362608';
  $type = 'ADSL';

  if (!validateFormat($type, $number)) {
      echo "Invalid format. Please check the number.\n";
  } else {
      // Le format est correct, validez maintenant avec l'API
      validateInternetNumber($type, $number);
  }
  ?>
  ```
</CodeGroup>

## Flux de validation complet

<CodeGroup>
  ```javascript Node.js theme={null}
  async function validateCompleteFlow(type, number) {
    // Étape 1 : Valider le type de service
    if (!['ADSL', '4G'].includes(type)) {
      return {
        valid: false,
        error: 'INVALID_TYPE',
        message: 'Service type must be ADSL or 4G'
      };
    }

    // Étape 2 : Vérification du format côté client
    if (!validateFormat(type, number)) {
      return {
        valid: false,
        error: 'INVALID_FORMAT',
        message: type === 'ADSL' 
          ? 'ADSL numbers must be 9 digits starting with 0 (e.g., 036362608)'
          : '4G numbers must be 12 digits starting with 213 (e.g., 213665983439)'
      };
    }

    // Étape 3 : Validation via API
    try {
      await validateInternetNumber(type, number);
      return {
        valid: true,
        type,
        number
      };
    } catch (error) {
      return {
        valid: false,
        error: 'API_VALIDATION_FAILED',
        message: error.message
      };
    }
  }

  // Usage
  const result = await validateCompleteFlow('ADSL', '036362608');

  if (!result.valid) {
    console.error(`Validation failed: ${result.message}`);
  } else {
    console.log('✅ Ready to place order');
  }
  ```

  ```python Python theme={null}
  async def validate_complete_flow(service_type, number):
      # Étape 1 : Valider le type de service
      if service_type not in ['ADSL', '4G']:
          return {
              'valid': False,
              'error': 'INVALID_TYPE',
              'message': 'Service type must be ADSL or 4G'
          }
      
      # Étape 2 : Vérification du format côté client
      if not validate_format(service_type, number):
          message = (
              'ADSL numbers must be 9 digits starting with 0 (e.g., 036362608)'
              if service_type == 'ADSL'
              else '4G numbers must be 12 digits starting with 213 (e.g., 213665983439)'
          )
          return {
              'valid': False,
              'error': 'INVALID_FORMAT',
              'message': message
          }
      
      # Étape 3 : Validation via API
      try:
          validate_internet_number(service_type, number)
          return {
              'valid': True,
              'type': service_type,
              'number': number
          }
      except Exception as e:
          return {
              'valid': False,
              'error': 'API_VALIDATION_FAILED',
              'message': str(e)
          }

  # Usage
  result = await validate_complete_flow('ADSL', '036362608')

  if not result['valid']:
      print(f"Validation failed: {result['message']}")
  else:
      print('✅ Ready to place order')
  ```

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

  function validateCompleteFlow($type, $number) {
      // Étape 1 : Valider le type de service
      if (!in_array($type, ['ADSL', '4G'])) {
          return [
              'valid' => false,
              'error' => 'INVALID_TYPE',
              'message' => 'Service type must be ADSL or 4G'
          ];
      }
      
      // Étape 2 : Vérification du format côté client
      if (!validateFormat($type, $number)) {
          $message = $type === 'ADSL'
              ? 'ADSL numbers must be 9 digits starting with 0 (e.g., 036362608)'
              : '4G numbers must be 12 digits starting with 213 (e.g., 213665983439)';
          
          return [
              'valid' => false,
              'error' => 'INVALID_FORMAT',
              'message' => $message
          ];
      }
      
      // Étape 3 : Validation via API
      try {
          validateInternetNumber($type, $number);
          return [
              'valid' => true,
              'type' => $type,
              'number' => $number
          ];
      } catch (Exception $e) {
          return [
              'valid' => false,
              'error' => 'API_VALIDATION_FAILED',
              'message' => $e->getMessage()
          ];
      }
  }

  // Usage
  $result = validateCompleteFlow('ADSL', '036362608');

  if (!$result['valid']) {
      echo "Validation failed: {$result['message']}\n";
  } else {
      echo "✅ Ready to place order\n";
  }
  ?>
  ```
</CodeGroup>

## Mise en cache de la validation

Mettez en cache brièvement les validations réussies pour réduire les appels API :

```javascript theme={null}
class ValidationCache {
  constructor(ttlSeconds = 300) { // 5 minutes
    this.cache = new Map();
    this.ttl = ttlSeconds * 1000;
  }

  async validate(type, number) {
    const key = `${type}:${number}`;
    const cached = this.cache.get(key);
    const now = Date.now();

    // Return cached if valid
    if (cached && (now - cached.timestamp) < this.ttl) {
      return cached.result;
    }

    // Validate with API
    try {
      const result = await validateInternetNumber(type, number);
      this.cache.set(key, {
        result: { valid: true, ...result },
        timestamp: now,
      });
      return { valid: true, ...result };
    } catch (error) {
      // Don't cache failures
      throw error;
    }
  }

  invalidate(type, number) {
    const key = `${type}:${number}`;
    this.cache.delete(key);
  }
}

// Usage
const validationCache = new ValidationCache(300); // 5 minutes

// First call - validates with API
const result1 = await validationCache.validate('ADSL', '036362608');

// Second call within 5 minutes - returns cached
const result2 = await validationCache.validate('ADSL', '036362608');
```

## Messages d'Erreur Conviviaux

Fournissez des retours clairs selon le type d'erreur :

```javascript theme={null}
function getValidationErrorMessage(type, error) {
  const messages = {
    INVALID_TYPE: 'Veuillez sélectionner ADSL ou 4G comme type de service.',
    
    INVALID_FORMAT: {
      ADSL: 'Veuillez saisir un numéro ADSL valide (9 chiffres commençant par 0).\nExemple : 036362608',
      '4G': 'Veuillez saisir un numéro 4G valide (12 chiffres commençant par 213).\nExemple : 213665983439'
    },
    
    API_VALIDATION_FAILED: {
      default: 'Ce numéro n\'est pas valide pour le type de service sélectionné.',
      'ERR_PHONE': 'Ce numéro ne peut pas être utilisé pour la recharge internet.'
    }
  };
  
  if (error === 'INVALID_FORMAT') {
    return messages.INVALID_FORMAT[type];
  }
  
  if (error === 'API_VALIDATION_FAILED') {
    return messages.API_VALIDATION_FAILED.default;
  }
  
  return messages[error] || 'Impossible de valider le numéro. Veuillez réessayer.';
}
```

## Tests de Validation

```javascript theme={null}
async function testValidation() {
  const testCases = [
    // Tests ADSL
    { type: 'ADSL', number: '036362608', expected: true },
    { type: 'ADSL', number: '031417237', expected: true },
    { type: 'ADSL', number: '36362608', expected: false },  // 0 manquant
    { type: 'ADSL', number: '0363626081', expected: false }, // Trop long
    
    // Tests 4G
    { type: '4G', number: '213665983439', expected: true },
    { type: '4G', number: '213472731602', expected: true },
    { type: '4G', number: '0665983439', expected: false },   // Mauvais format
    { type: '4G', number: '+213665983439', expected: false }, // Contient +
  ];

  console.log('🧪 Test de validation...\n');

  for (const test of testCases) {
    const result = await validateCompleteFlow(test.type, test.number);
    const passed = result.valid === test.expected;
    
    console.log(
      `${passed ? '✅' : '❌'} ${test.type} ${test.number}: ${result.valid ? 'VALIDE' : 'INVALIDE'}`
    );
    
    if (!passed) {
      console.log(`  Attendu : ${test.expected}, Obtenu : ${result.valid}`);
      if (!result.valid) {
        console.log(`  Erreur : ${result.message}`);
      }
    }
  }
}
```

## Bonnes pratiques

<CardGroup cols={2}>
  <Card title="Valider tôt" icon="bolt">
    Vérifier le format côté client avant l'appel API
  </Card>

  <Card title="Messages clairs" icon="message">
    Afficher des messages d'erreur spécifiques et utiles
  </Card>

  <Card title="Mettre en cache les résultats" icon="database">
    Mettre en cache les numéros valides pendant 5 minutes
  </Card>

  <Card title="Retour visuel" icon="eye">
    Afficher le statut de validation en temps réel pendant la saisie
  </Card>
</CardGroup>

## Étapes suivantes

<CardGroup cols={3}>
  <Card title="Envoyer les recharges" icon="paper-plane" href="/fr/internet-topup-guides/3-sending-topups">
    Soumettre des commandes validées
  </Card>

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

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

  <Card title="Charger les produits" icon="list" href="/fr/internet-topup-guides/1-loading-products">
    Récupérer les cartes disponibles
  </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="Livrer les cartes" icon="file-code" href="/fr/internet-topup-guides/5-card-delivery">
    Livrer les codes de carte en toute sécurité
  </Card>
</CardGroup>
