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

# Lister les Partenaires

> Vérifiez quels facturiers sont actuellement disponibles

## Vue d'ensemble

Retourne la disponibilité de chaque facturier pris en charge. Appelez-le avant une découverte afin de masquer un partenaire indisponible à vos clients, plutôt que de les laisser tomber sur un `503` à la fin d'un formulaire.

La réponse est une table indexée par la valeur `partner` exacte que vous envoyez à [Découvrir les Factures](/fr/api-reference/bill-payment/discover-bills) — accents compris dans `Algérie Télécom`.

<Note>
  Une clé `PRODUCTION` voit la disponibilité en temps réel. Une clé `SANDBOX` voit une table fixe, car une requête sandbox n'atteint jamais un partenaire et la disponibilité réelle y serait trompeuse.
</Note>

## Réponse

<ResponseField name="success" type="boolean" required>
  `true` lorsque la table a été retournée.
</ResponseField>

<ResponseField name="data" type="object" required>
  Une entrée par partenaire. L'ensemble des clés est fixe.

  <Expandable title="properties">
    <ResponseField name="ADE" type="object">
      Algérienne Des Eaux — eau.
    </ResponseField>

    <ResponseField name="SONELGAZ" type="object">
      Électricité et gaz.
    </ResponseField>

    <ResponseField name="SEAAL" type="object">
      Eau pour Alger et Tipaza.
    </ResponseField>

    <ResponseField name="AADL" type="object">
      Échéances de logement.
    </ResponseField>

    <ResponseField name="Algérie Télécom" type="object">
      Téléphonie fixe et internet.
    </ResponseField>
  </Expandable>
</ResponseField>

Chaque entrée possède un seul champ :

<ResponseField name="status" type="string" required>
  `ACTIVE` — la découverte et le paiement sont acceptés.

  `UNAVAILABLE` — la découverte et le paiement pour ce partenaire répondent `503 PARTNER_UNAVAILABLE`.
</ResponseField>

<ResponseField name="meta" type="object" required>
  <Expandable title="properties">
    <ResponseField name="timestamp" type="string" required>
      Heure de la réponse, ISO 8601 UTC.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="requestId" type="string" required>
  Identifiant de corrélation, également envoyé dans l'en-tête de réponse `X-Request-Id`.
</ResponseField>

## Exemples

<CodeGroup>
  ```bash cURL theme={null}
  curl https://billapi.oneclickdz.com/v3/partners \
    -H "X-Access-Token: YOUR_API_KEY"
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://billapi.oneclickdz.com/v3/partners", {
    headers: { "X-Access-Token": process.env.ONECLICKDZ_API_KEY },
  });

  const body = await response.json();

  if (!body.success) {
    throw new Error(`${body.error.code}: ${body.error.message}`);
  }

  const available = Object.entries(body.data)
    .filter(([, partner]) => partner.status === "ACTIVE")
    .map(([name]) => name);

  console.log(available);
  ```

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

  response = requests.get(
      'https://billapi.oneclickdz.com/v3/partners',
      headers={'X-Access-Token': os.getenv('ONECLICKDZ_API_KEY')}
  )

  body = response.json()

  if not body['success']:
      raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")

  available = [
      name for name, partner in body['data'].items()
      if partner['status'] == 'ACTIVE'
  ]

  print(available)
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init('https://billapi.oneclickdz.com/v3/partners');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'X-Access-Token: ' . getenv('ONECLICKDZ_API_KEY')
  ]);

  $body = json_decode(curl_exec($ch), true);
  curl_close($ch);

  if (!$body['success']) {
      throw new Exception($body['error']['code'] . ': ' . $body['error']['message']);
  }

  $available = array_keys(array_filter(
      $body['data'],
      fn($partner) => $partner['status'] === 'ACTIVE'
  ));

  print_r($available);
  ?>
  ```
</CodeGroup>

### Réponse de succès

```json theme={null}
{
  "success": true,
  "data": {
    "ADE": { "status": "ACTIVE" },
    "SONELGAZ": { "status": "ACTIVE" },
    "SEAAL": { "status": "UNAVAILABLE" },
    "AADL": { "status": "UNAVAILABLE" },
    "Algérie Télécom": { "status": "ACTIVE" }
  },
  "meta": {
    "timestamp": "2026-08-31T10:15:32.194Z"
  },
  "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
}
```

## Réponses d'erreur

<AccordionGroup>
  <Accordion title="401 — Token d'Accès Manquant">
    **L'en-tête `X-Access-Token` n'a pas été envoyé.**

    ```json theme={null}
    {
      "success": false,
      "error": {
        "code": "MISSING_ACCESS_TOKEN",
        "message": "X-Access-Token header is required."
      },
      "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
    }
    ```

    **Que faire :** ajoutez l'en-tête et réessayez.
  </Accordion>

  <Accordion title="401 — Token d'Accès Invalide">
    **La clé a été rejetée.**

    ```json theme={null}
    {
      "success": false,
      "error": {
        "code": "INVALID_ACCESS_TOKEN",
        "message": "The provided access token is invalid."
      },
      "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
    }
    ```

    **Que faire :** vérifiez la clé avec [Valider la Clé API](/fr/api-reference/bill-payment/validate-key).
  </Accordion>

  <Accordion title="503 — Authentification Indisponible">
    **Nous n'avons pas pu vérifier votre clé à temps.**

    ```json theme={null}
    {
      "success": false,
      "error": {
        "code": "AUTH_UNAVAILABLE",
        "message": "Authentication is temporarily unavailable. Please retry shortly."
      },
      "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
    }
    ```

    **Que faire :** réessayez après le délai de l'en-tête `Retry-After`. Servez entre-temps la dernière table mise en cache.
  </Accordion>

  <Accordion title="503 — Service Indisponible">
    **L'API Bill Payment est en maintenance planifiée.**

    ```json theme={null}
    {
      "success": false,
      "error": {
        "code": "SERVICE_UNAVAILABLE",
        "message": "The service is temporarily unavailable. Please retry shortly."
      },
      "requestId": "req_9f3a1c72e0b84d51aB3xZq07"
    }
    ```

    **Que faire :** respectez `Retry-After` et réessayez.
  </Accordion>
</AccordionGroup>

## Disponibilité actuelle

`SEAAL` et `AADL` sont actuellement `UNAVAILABLE` aussi bien en sandbox qu'en production, et toute découverte ou tout paiement les concernant répond `503 PARTNER_UNAVAILABLE`. Il s'agit du réglage actuel de l'opérateur, et non d'une limitation permanente — gardez les deux partenaires dans votre code et laissez cet endpoint décider de ce qu'il faut afficher.

<Warning>
  Ne codez en dur la disponibilité d'aucun partenaire. Lisez cette table, et traitez un `503 PARTNER_UNAVAILABLE` lors d'une découverte comme un partenaire devenu indisponible entre votre dernier rafraîchissement et la requête.
</Warning>

## Mettre la table en cache

La disponibilité change rarement. Rafraîchissez-la sur une minuterie plutôt qu'avant chaque découverte, et continuez à servir la dernière copie valide lorsqu'un rafraîchissement échoue.

```javascript theme={null}
let cache = { map: null, fetchedAt: 0 };
const TTL_MS = 5 * 60 * 1000;

async function getPartners() {
  if (cache.map && Date.now() - cache.fetchedAt < TTL_MS) {
    return cache.map;
  }

  try {
    const response = await fetch("https://billapi.oneclickdz.com/v3/partners", {
      headers: { "X-Access-Token": process.env.ONECLICKDZ_API_KEY },
    });

    const body = await response.json();

    if (body.success) {
      cache = { map: body.data, fetchedAt: Date.now() };
    }
  } catch (error) {
    // Keep serving the previous map rather than blocking the customer.
  }

  return cache.map ?? {};
}

async function isAvailable(partner) {
  const map = await getPartners();
  return map[partner]?.status === "ACTIVE";
}
```

## Bonnes pratiques

<CardGroup cols={2}>
  <Card title="Mettre en Cache Quelques Minutes" icon="database">
    Un cache de 5 minutes suffit. Appeler cet endpoint avant chaque découverte ajoute un aller-retour et n'apporte rien.
  </Card>

  <Card title="Échouer en Douceur au Rafraîchissement" icon="shield-halved">
    Si le rafraîchissement échoue, conservez la table précédente. Une liste de partenaires vide est pire qu'une liste légèrement périmée.
  </Card>

  <Card title="Utiliser la Valeur Exacte du Partenaire" icon="quote-left">
    Envoyez `Algérie Télécom` avec ses accents. La valeur est la clé de cette table, caractère pour caractère.
  </Card>

  <Card title="Gérer la Situation de Concurrence" icon="triangle-exclamation">
    Un partenaire peut devenir indisponible après sa mise en cache. Gérez aussi `503 PARTNER_UNAVAILABLE` lors de la découverte.
  </Card>
</CardGroup>

## Endpoints associés

<CardGroup cols={2}>
  <Card title="Valider la Clé API" icon="key" href="/fr/api-reference/bill-payment/validate-key">
    Confirmez votre clé et votre environnement
  </Card>

  <Card title="Découvrir les Factures" icon="magnifying-glass-dollar" href="/fr/api-reference/bill-payment/discover-bills">
    Consultez ce qu'un compte doit
  </Card>

  <Card title="Partenaires et Comptes" icon="address-card" href="/fr/bill-payment-guides/1-partners-and-accounts">
    Identifiants de chaque partenaire
  </Card>

  <Card title="Vue d'ensemble Bill Payment" icon="file-invoice-dollar" href="/fr/bill-payment-guides/overview">
    Comment tout le flux s'articule
  </Card>
</CardGroup>
