> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mercy-pay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Erreurs

> Le format des erreurs de l'API, chaque code et comment y répondre.

Toutes les erreurs de l'API ont la même forme : un statut HTTP et un objet `error`.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "error": {
    "type": "invalid_request_error",
    "code": "validation_failed",
    "message": "Le champ amount est obligatoire.",
    "param": "amount",
    "doc_url": "https://docs.mercy-pay.com/developers/errors#validation_failed",
    "request_id": "req_01jc8x4m2v7t9qk3n5w6y8z0ab",
    "errors": {
      "amount": [
        "Le champ amount est obligatoire."
      ]
    }
  }
}
```

| Champ | Contenu |
| - | - |
| `type` | La famille de l'erreur, voir plus bas |
| `code` | Un code stable : c'est lui que votre code doit tester |
| `message` | Une phrase en français pour un humain. Son texte peut changer : ne le comparez jamais |
| `param` | Le premier champ en cause, ou `null` |
| `doc_url` | Le lien vers l'explication de ce code sur cette page |
| `request_id` | L'identifiant de la requête, à nous donner si vous contactez le support |

Sur une erreur `422`, `errors` liste chaque champ refusé avec ses messages.

## Identifiant de requête

Chaque réponse, réussie ou non, porte un en-tête `Request-Id` (`req_…`), et chaque erreur le répète dans `error.request_id`. Gardez-le dans vos journaux : il désigne l'appel exact, et le support retrouve la requête avec lui.

## Types d'erreur

| `type` | Quand |
| - | - |
| `authentication_error` | Clé absente, invalide, compte suspendu ou KYC manquant |
| `invalid_request_error` | Requête ou données invalides, objet introuvable ou état incompatible |
| `idempotency_error` | Clé d'idempotence absente, en cours ou réutilisée |
| `payment_error` | Paiement refusé |
| `rate_limit_error` | Trop de requêtes |
| `api_error` | Erreur de notre côté |

## Codes

Cette liste peut s'enrichir, mais un code existant ne change jamais de nom. Traitez un code inconnu comme une erreur générique de son `type`.

### `api_key_missing`

`401` · `authentication_error`

Aucune clé n'accompagne la requête.

Ajoutez l'en-tête `Authorization: Bearer mp_sandbox_…` (ou `mp_live_…`). Voir [Authentification](https://docs.mercy-pay.com/developers/authentication.md).

### `api_key_invalid`

`401` · `authentication_error`

La clé est inconnue ou a été révoquée.

Copiez une clé active depuis la console développeurs. Vérifiez qu'elle n'a pas d'espace en trop.

### `merchant_suspended`

`403` · `authentication_error`

Le compte marchand est suspendu.

Contactez le support : aucune requête n'aboutit tant que le compte reste suspendu.

### `live_mode_requires_kyc`

`403` · `authentication_error`

Une clé live est utilisée avant l'approbation de votre vérification d'identité.

Terminez votre KYC. En attendant, travaillez avec une clé sandbox.

### `forbidden`

`403` · `authentication_error`

La clé ne permet pas cette action.

Vérifiez l'environnement de la clé et la ressource visée.

### `bad_request`

`400` · `invalid_request_error`

La requête est mal formée, par exemple un JSON invalide.

Envoyez un corps JSON valide avec `Content-Type: application/json`.

### `idempotency_key_missing`

`400` · `idempotency_error`

`Idempotency-Key` manque sur une opération qui l'exige (paiement direct, retrait).

Générez une clé unique par opération et envoyez-la dans l'en-tête. Voir [Idempotence](https://docs.mercy-pay.com/developers/idempotency.md).

### `resource_not_found`

`404` · `invalid_request_error`

L'objet n'existe pas, ou appartient à un autre marchand ou à l'autre environnement.

Vérifiez l'id et l'environnement de la clé : un objet sandbox n'est pas visible avec une clé live.

### `method_not_allowed`

`405` · `invalid_request_error`

La méthode HTTP n'est pas acceptée sur cette URL.

Consultez la référence de l'endpoint pour la bonne méthode.

### `conflict`

`409` · `invalid_request_error`

L'action contredit l'état de l'objet : un client avec cet e-mail existe déjà, une session est déjà payée…

Lisez `message` : il dit quoi faire. Pour un client en double, l'id existant est renvoyé dans `error.customer`.

### `idempotency_key_in_use`

`409` · `idempotency_error`

Une requête avec la même clé d'idempotence est encore en cours.

Attendez quelques secondes puis rejouez la même requête avec la même clé.

### `idempotency_key_reused`

`409` · `idempotency_error`

La clé d'idempotence a déjà servi pour une requête au contenu différent.

Utilisez une nouvelle clé pour une nouvelle opération.

### `validation_failed`

`422` · `invalid_request_error`

Un ou plusieurs champs sont invalides.

`error.param` nomme le premier champ en cause et `errors` détaille chacun.

### `insufficient_balance`

`422` · `invalid_request_error`

Votre solde disponible, retraits déjà réservés déduits, ne couvre pas le remboursement et ses frais.

Attendez de nouveaux encaissements, ou annulez un retrait en attente, puis réessayez.

### `refund_not_allowed`

`422` · `invalid_request_error`

Ce paiement ne peut pas être remboursé : il n'a pas abouti, il date de plus de 90 jours, ses fonds carte ne sont pas encore disponibles, ou l'opérateur du client refuse les remboursements pour le moment.

Le message dit laquelle de ces raisons s'applique.

### `payment_declined`

`422` · `payment_error`

Le paiement a été refusé dès sa création.

Proposez au payeur un autre numéro ou un autre moyen de paiement.

### `rate_limited`

`429` · `rate_limit_error`

Trop de requêtes sur une courte période.

Attendez le délai de l'en-tête `Retry-After`. Voir [Limites de débit](https://docs.mercy-pay.com/developers/rate-limits.md).

### `server_error`

`500` · `api_error`

Une erreur s'est produite de notre côté.

Réessayez avec la même `Idempotency-Key` : l'opération ne sera jamais faite deux fois. Si l'erreur persiste, donnez-nous le `request_id`.

## Motif d'échec d'un paiement ou d'un retrait

Un paiement ou un retrait échoué n'est pas une erreur de requête : il porte un `failure_code` et un `failure_reason` en français.

| `failure_code` | Signification |
| - | - |
| `insufficient_balance` | Le solde du payeur ne couvre pas le montant |
| `payment_not_approved` | Le payeur a refusé ou n'a pas validé la demande sur son téléphone |
| `payer_not_found` | Le numéro n'est pas associé à l'opérateur choisi |
| `payer_limit_reached` | Le payeur a atteint la limite fixée par son opérateur |
| `transaction_expired` | Le payeur n'a pas confirmé à temps |
| `customer_not_eligible` | Le payeur n'a pas accès à ce type de paiement |
| `invalid_phone_number` | Le numéro n'est pas valide pour l'opérateur |
| `amount_out_of_bounds` | Le montant sort des limites de l'opérateur |
| `provider_temporarily_unavailable` | L'opérateur est momentanément indisponible |
| `recipient_not_found` | Retrait : le numéro du bénéficiaire n'est pas reconnu |
| `payouts_not_allowed` | Retrait : les retraits ne sont pas activés vers cet opérateur |
| `unspecified_failure` | Refus sans motif précis |

## Erreurs métier fréquentes

| Message | Cause |
| - | - |
| `Solde disponible insuffisant pour ce montant.` | Le solde du pays et de l'opérateur ne couvre pas le retrait |
| `Opérateur Mobile Money invalide pour ce pays.` | Code opérateur incohérent avec le pays |
| `Cette devise ne figure pas dans la norme ISO 4217.` | Code devise inconnu |
| `Ce moyen de paiement n'est pas disponible pour le moment.` | Aucun taux de conversion disponible vers la devise de l'opérateur mobile money choisi |
| `Le montant minimum pour un paiement par carte est de 0.50 USD.` | Montant sous le minimum carte |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.