> For the complete documentation index, see [llms.txt](https://qosic.gitbook.io/qospay/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://qosic.gitbook.io/qospay/merchant-api/integration-rules/error-handling.md).

# error handling

Il existe quatre indicateurs distincts. Lisez les quatre lorsqu’ils sont présents :

1. Statut HTTP — résultat du transport/de l’API.
2. `responseCode` et `success` de l’enveloppe externe — résultat de l’opération au niveau de la plateforme.
3. `data.code` ou `data.responseCode` imbriqué dans la transaction — résultat du provider/de la transaction.
4. `status` de la transaction — état du cycle de vie et principal indicateur de règlement.

## Référence des statuts HTTP

| Statut HTTP                  | Signification dans les API marchand                                                                                          | Action                                                                                                                          |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `200 OK`                     | La requête a été traitée. Pour les opérations financières, inspectez le code/statut imbriqué.                                | Analysez le body ; ne supposez pas qu’un paiement a réussi uniquement parce que le statut HTTP est 200.                         |
| `400 Bad Request`            | Échec de validation, configuration, règle métier, wallet, provider ou référence inconnue.                                    | Corrigez les erreurs d’entrée déterministes. En cas d’incertitude financière, vérifiez le statut avant de réessayer.            |
| `401 Unauthorized`           | Token bearer manquant/expiré/invalide, mauvais rôle, identifiants de connexion invalides ou identité dashboard non reconnue. | Renouvelez le token local une seule fois. Si la connexion elle-même renvoie 401, corrigez les identifiants ou l’état du compte. |
| `403 Forbidden`              | Verrouillage de connexion, service marchand désactivé ou rejet par la liste blanche IP du service.                           | Attendez la fin du verrouillage ; sinon utilisez une IP source autorisée ou demandez l’activation du service.                   |
| `404 Not Found`              | Chemin incorrect ou version d’API non prise en charge.                                                                       | Corrigez l’URL ; ne réessayez pas sans modification.                                                                            |
| `405 Method Not Allowed`     | Chemin correct mais mauvais verbe HTTP.                                                                                      | Utilisez la méthode documentée ici.                                                                                             |
| `415 Unsupported Media Type` | Le body de la requête n’a pas été envoyé en JSON.                                                                            | Envoyez `Content-Type: application/json`.                                                                                       |
| `500 Internal Server Error`  | Échec inattendu du traitement serveur/provider.                                                                              | Considérez le résultat financier comme inconnu et recherchez par `transRef` ; réessayez les appels non financiers avec backoff. |

{% hint style="info" %}
Les endpoints marchand ne renvoient normalement pas HTTP `201` ou `409`. Un `data.code` imbriqué égal à `201` pour une collecte signifie que le provider a accepté la requête et qu’elle est en attente ; il ne s’agit pas d’un statut HTTP.
{% endhint %}

## Structures de réponse de la plateforme

### Enveloppe d’échec métier

```json
{
  "data": null,
  "message": "Payment reference already exists",
  "success": false,
  "responseCode": "400"
}
```

### Réponse de validation ou d’exception

Certains échecs se produisent avant que le contrôleur ne crée l’enveloppe standard et ne contiennent que deux champs :

```json
{
  "responseCode": "400",
  "message": "The amount field is required"
}
```

Votre parseur d’erreurs doit accepter les deux formats et doit également tolérer un body d’erreur non JSON provenant de la couche de sécurité ou de la gateway.

## Référence des codes plateforme et transaction

| Code               | Emplacement                               | Signification                                                                                     | Action                                                                                         |
| ------------------ | ----------------------------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `00`               | Enveloppe externe                         | L’opération API a réussi.                                                                         | Continuez à inspecter le statut financier imbriqué.                                            |
| `400`              | Enveloppe externe/réponse d’erreur        | L’opération API a échoué pendant la validation ou le traitement métier.                           | Inspectez `message` ; corrigez ou rapprochez selon les indications ci-dessous.                 |
| `401`              | Réponse de connexion/d’erreur             | Identifiants invalides, compte inactif, incohérence d’intégrité ou contexte de sécurité invalide. | Renouvelez/corrigez les identifiants une seule fois ; ne bouclez pas.                          |
| `403`              | Réponse de connexion/sécurité             | Compte verrouillé, service indisponible ou IP source rejetée.                                     | Attendez ou corrigez la configuration marchand/service/IP.                                     |
| `500`              | Réponse d’erreur                          | Échec interne inattendu.                                                                          | Rapprochez les requêtes financières à l’aide de leur référence avant toute nouvelle tentative. |
| `201`              | `data.code` d’une collecte                | Le provider a accepté la requête et elle est en attente.                                          | Suivez les instructions de continuation et interrogez le statut.                               |
| `01`               | Code de réponse de transaction enregistré | Collecte en attente acceptée par un provider.                                                     | Interrogez le statut.                                                                          |
| `00` ou `0`        | `data.code` d’une collecte                | Le provider indique une réussite immédiate.                                                       | Rapprochez avec le statut/reporting.                                                           |
| `96`               | Code de transaction enregistré/provider   | Échec du traitement local ou de l’appel provider.                                                 | Vérifiez le statut de la transaction et l’annulation du wallet ; ne réessayez pas aveuglément. |
| Toute autre valeur | Code provider/transaction imbriqué        | Résultat spécifique au provider. L’ensemble des codes provider est ouvert.                        | Conservez le code/message exact et utilisez `status` comme autorité sur le cycle de vie.       |

{% hint style="info" %}
Comme les opérateurs peuvent renvoyer de nouveaux codes propres aux providers, aucun document marchand figé ne peut lister tous les codes provider imbriqués. Implémentez une gestion des codes inconnus : journalisez-les, ne les mappez pas à une réussite et interrogez le statut de la transaction.
{% endhint %}

## Erreurs déterministes d’entrée et de configuration

Ces erreurs peuvent être corrigées avant un nouvel envoi. Utilisez une nouvelle référence uniquement lorsque la requête précédente a été définitivement rejetée avant la création de la transaction ; vérifier le statut en premier reste l’approche la plus sûre.

| Message                                                                                    | Signification                                                                   | Action                                                                                             |
| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `The amount field is required`                                                             | `amount` est nul ou vide.                                                       | Envoyez une chaîne décimale.                                                                       |
| `Request amount is invalid` / `Deposit amount is invalid`                                  | Le montant ne peut pas être interprété pour un provider limité.                 | Supprimez les séparateurs/symboles et envoyez une chaîne décimale positive.                        |
| `Request/Deposit amount is below...` ou `exceeds...`                                       | Le minimum/maximum du provider n’a pas été respecté.                            | Ajustez le montant à la plage indiquée.                                                            |
| `The transaction reference field is required`                                              | `transRef` est manquant.                                                        | Générez et conservez une référence.                                                                |
| `Payment reference already exists`                                                         | La référence de collecte a déjà été utilisée.                                   | Interrogez le statut ; ne soumettez pas l’opération comme un nouveau paiement.                     |
| `Transaction exist with the specified transaction reference`                               | La référence de transfert/facture a déjà été utilisée.                          | Interrogez le statut ; ne soumettez pas l’opération comme un nouveau paiement.                     |
| `Account number or Msisdn is required`                                                     | Les deux identifiants de destination sont nuls.                                 | Envoyez l’identifiant exigé par `customerIdentificationType`.                                      |
| `Country code field is required`                                                           | `countryCode` est manquant.                                                     | Utilisez la valeur issue de la découverte.                                                         |
| `OperatorId is required` / `Operator Id is required`                                       | `operatorId` est manquant.                                                      | Utilisez la valeur issue de la découverte.                                                         |
| `No provider found` / `Operator not found`                                                 | L’opérateur n’est pas configuré pour le parcours demandé.                       | Rafraîchissez la découverte et corrigez la combinaison pays/opérateur.                             |
| `Currency code is required...`                                                             | La devise requise est absente.                                                  | Envoyez toujours la devise découverte.                                                             |
| `The specified currency is not supported for the selected country`                         | Le mapping pays/devise est invalide.                                            | Sélectionnez une devise retournée pour ce pays.                                                    |
| `Product code is required`                                                                 | Le provider sélectionné exige un code produit/banque.                           | Obtenez-le via la découverte des produits.                                                         |
| `Account number is required` / `Account name is required` / `Narration is required`        | Le provider de transfert sélectionné exige ces champs.                          | Effectuez la recherche de nom et envoyez les détails de destination validés ainsi que le motif.    |
| `Product configuration could not be resolved for this transaction`                         | Aucun produit ne correspond à l’opération/devise.                               | Arrêtez le parcours et demandez une vérification de la configuration.                              |
| `Fee configuration could not be resolved for this transaction`                             | La tarification du produit est absente ou invalide.                             | Arrêtez le parcours et demandez une vérification de la configuration.                              |
| `Transaction exceeds the configured single transaction limit`                              | La limite par transaction du produit est dépassée.                              | Réduisez le montant ou ne fractionnez que si les règles métier autorisent des paiements séparés.   |
| `Daily transaction count limit exceeded`                                                   | La fréquence quotidienne autorisée pour le produit est atteinte.                | Attendez le prochain jour UTC ou demandez une révision de la limite.                               |
| `Daily transaction amount limit exceeded`                                                  | La limite quotidienne de valeur du produit est atteinte.                        | Attendez le prochain jour UTC ou demandez une révision de la limite.                               |
| `Insufficient funds in merchant wallet`                                                    | Le wallet de débit ne peut pas couvrir la transaction et les frais applicables. | Approvisionnez le wallet correspondant à l’environnement et à la devise, puis vérifiez le solde.   |
| `No wallet is configured for this transaction currency. Please contact support`            | Aucun wallet ou chemin de conversion utilisable n’existe.                       | Arrêtez et demandez la configuration du wallet ; changer la référence ne résoudra pas le problème. |
| `No dedicated wallet is configured for this provider and currency. Please contact support` | L’opérateur exige un wallet dédié qui n’existe pas.                             | Arrêtez et demandez la configuration du wallet.                                                    |

## Erreurs transitoires ou d’intégrité

| Message                                              | Signification                                                                                      | Action                                                                                                           |
| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `Service not available`                              | Le service marchand requis n’est pas activé.                                                       | Demandez son activation ; ne réessayez pas continuellement.                                                      |
| `IP address not allowed`                             | La liste blanche d’IP du service a rejeté l’appelant.                                              | Utilisez une IP de sortie stable et enregistrée.                                                                 |
| `Merchant wallet provisioning is busy. Please retry` | Une autre requête est en train de créer le même wallet de collecte.                                | Réessayez avec un court backoff aléatoire, en conservant la même référence métier après rapprochement du statut. |
| `Transaction processing is busy. Please retry`       | Un autre processus détient le verrou de transaction/wallet.                                        | Interrogez le statut, puis ne réessayez que si la transaction n’est pas déjà en cours.                           |
| `Wallet checksum validation failed`                  | La validation d’intégrité du wallet a échoué.                                                      | Arrêtez les transactions sur ce wallet et escaladez ; ne réessayez pas.                                          |
| `Wallet environment validation failed`               | Les environnements du wallet et du marchand ne correspondent pas.                                  | Arrêtez et demandez une vérification de l’environnement/du wallet.                                               |
| `Provider invocation failed.`                        | Le provider a renvoyé un résultat non-2xx après le traitement local ; une annulation a été tentée. | Vérifiez le statut et l’historique du wallet avant toute nouvelle tentative.                                     |
| `Unable to confirm transaction status...`            | Le statut du provider n’a pas pu être obtenu.                                                      | Conservez la référence d’origine et continuez le polling avec backoff.                                           |
| `Transaction requires admin reversal review`         | Le résultat provider est incertain et une annulation automatique n’est pas sûre.                   | N’exécutez pas et ne réessayez pas le paiement ; surveillez le statut et escaladez via le support marchand.      |
| `Internal server error`                              | Erreur API non gérée.                                                                              | Considérez le résultat financier comme inconnu et rapprochez-le par référence.                                   |

## Exemple de pseudocode de gestion des erreurs

```
send(request)
  if HTTP 200:
    if outer responseCode != "00":
      handle platform failure
    else if financial request:
      inspect nested code/status
      persist transRef and providerReference
      poll when status is not final
  else if HTTP 401:
    refresh token once and retry only the authenticated API call
  else if HTTP 400:
    inspect message
    for financial requests, query status before resubmitting
  else if HTTP 403:
    stop; resolve lock, service access, or IP whitelist
  else if timeout or HTTP 500:
    mark financial outcome UNKNOWN
    query status using the original transRef
```
