Documentation/Les erreurs
openapi.jsonOuvrir mon espace

Les erreurs

Un statut HTTP, et un corps stable — le même pour toutes les ressources. Le code est le contrat : votre programme s’y fie ; le message est pour un humain, en français ou en anglais selon Accept-Language.

Le corps

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "operator_required",
    "message": "Choisissez votre opérateur.",
    "details": {
      "operators": [
        {
          "code": "mtn",
          "name": "MTN"
        },
        {
          "code": "moov",
          "name": "Moov"
        }
      ]
    },
    "request_id": "req_01j9x3t8m2k4c7vd9qhs"
  }
}
typeREQUIS« authentication_error » · « invalid_request_error » · « rate_limit_error » · « api_error »La famille : qui doit corriger.
codeREQUIS« missing_api_key » · « invalid_api_key » · « insufficient_permissions » · « parameter_missing » · « parameter_invalid » · « resource_missing » · « payload_too_large » · « idempotency_key_reuse » · « rate_limited » · « merchant_inactive » · « live_mode_not_enabled » · « currency_unavailable » · « limit_exceeded » · « balance_insufficient » · « payment_closed » · « attempt_in_progress » · « phone_invalid » · « operator_required » · « operator_unavailable » · « country_unavailable » · « exchange_rate_unavailable » · « amount_out_of_range » · « idempotency_key_required » · « payment_declined » · « direct_not_enabled » · « too_many_attempts » · « payment_disputed » · « refund_amount_too_high » · « refund_reason_invalid » · « payment_not_refundable » · « recipient_not_ready » · « payout_unavailable » · « conflict » · « not_permitted » · « setting_missing » · « service_unavailable » · « internal_error »Le cas précis, stable, fait pour être testé. La liste : la page « Les erreurs ».
messageREQUIStexteUne phrase déjà écrite pour être montrée, en français ou en anglais selon Accept-Language.
paramtexteLe champ fautif, quand il y en a un.
detailsobjetCe qui aide à corriger, selon le code : par exemple « remaining » pour un remboursement trop gros.
request_idtexteL’identifiant de l’appel, aussi dans l’en-tête Request-Id : à citer quand vous nous écrivez.

Un code ne se retire jamais sans passer par les Changements. Citez request_id au support : il retrouve l’appel dans vos journaux.

Les codes

StatutcodeQuandQue faire
400parameter_missingUn champ requis manque ; « param » le nomme.Ajoutez le champ.
400parameter_invalidUn champ ne se lit pas ou sort de ses bornes ; « param » le nomme quand il y en a un.Corrigez la valeur d’après le message.
400currency_unavailableLa monnaie n’est pas ouverte, ou pas à cet espace.Choisissez une monnaie de votre espace.
400limit_exceededLe montant dépasse un plafond du palier, en réel.Un montant plus petit, ou un palier plus haut.
400balance_insufficientLe solde ne couvre pas le remboursement ou le retrait, frais compris.Attendez des encaissements, ou demandez moins.
400phone_invalidLe numéro du payeur ne se lit pas : trop court, trop long, ou d’un format inconnu.Envoyez-le au format international (+229…), ou précisez « country ».
400operator_requiredLe numéro peut appartenir à plusieurs opérateurs de son pays.Demandez au payeur son opérateur, et passez « operator » avec un des codes de « details.operators ».
400operator_unavailableAucun opérateur ouvert ne correspond à ce numéro, ou l’opérateur ne prend pas ce montant pour le moment.Proposez un autre numéro ; GET /v1/payment_methods dit ce qui est ouvert.
400country_unavailableLe pays du numéro, ou sa monnaie, n’est pas ouvert.Proposez un numéro d’un pays ouvert : GET /v1/payment_methods les liste.
400exchange_rate_unavailableLe payeur paie dans une autre monnaie que le paiement, et le taux du jour manque.Réessayez un peu plus tard, ou proposez un numéro du pays de votre monnaie.
400amount_out_of_rangeLe montant sort des bornes de l’opérateur, dans la monnaie du payeur.Lisez « details.min_amount » et « details.max_amount », dans « details.currency ».
400idempotency_key_requiredUn appel qui envoie une demande sur un téléphone, sans en-tête Idempotency-Key.Tirez la clé de votre commande (cmd-42) : un second clic donnera la même.
400refund_amount_too_highLe montant dépasse ce qui reste à rendre sur le paiement.Demandez au plus « details.remaining ».
400refund_reason_invalidLe motif n’est pas un de ceux que Payiz accepte.Prenez-le dans GET /v1/refund_reasons.
401missing_api_keyAucune clé dans l’en-tête Authorization.Envoyez « Authorization: Bearer sk_… ».
401invalid_api_keyClé inconnue, révoquée, expirée, d’un autre mode, ou appel depuis une adresse non autorisée.Vérifiez la clé et ses adresses autorisées dans votre espace.
402payment_declinedPayiz refuse cette demande. La raison n’est pas donnée.Ne relancez pas : proposez un autre moyen au payeur.
403insufficient_permissionsLa clé n’a pas le geste que l’appel demande.Donnez ce geste à la clé, ou servez-vous d’une autre.
403merchant_inactiveL’espace est suspendu ou fermé.Écrivez au support depuis votre espace.
403live_mode_not_enabledUne clé réelle, alors que le palier de l’espace n’ouvre pas le réel.Terminez la vérification du compte dans votre espace.
403direct_not_enabledUne demande lancée par l’API en réel, alors que le paiement direct n’est pas ouvert à l’espace.Envoyez « payment_url » au payeur, ou demandez l’ouverture du direct.
403not_permittedLe geste est refusé pour cet espace.Lisez le message ; écrivez au support si besoin.
404resource_missingL’objet n’existe pas, ou pas pour cette clé et ce mode.Vérifiez l’identifiant et le mode de la clé.
409idempotency_key_reuseLa même clé d’idempotence revient avec un autre corps, ou pendant que la première demande s’exécute.Une clé par demande ; rejouez la même demande à l’identique.
409payment_closedLe paiement est payé, annulé ou expiré.Lisez son état dans « details.status ».
409attempt_in_progressUne demande attend déjà la validation du payeur.Attendez son issue, par webhook.
409payment_disputedLe paiement est contesté : la somme est déjà retenue.Attendez l’issue du litige.
409payment_not_refundableLe paiement ne peut plus être remboursé (déjà rendu, ou en cours de remboursement).Lisez le paiement et ses remboursements.
409recipient_not_readyPar sécurité, un bénéficiaire neuf ne reçoit qu’après un délai.Réessayez après « details.usable_at ».
409conflictL’objet n’est pas dans un état qui permet ce geste.Relisez l’objet, puis décidez.
409setting_missingUn réglage de la plateforme manque : c’est à Payiz de le poser.Écrivez au support avec le « request_id ».
413payload_too_largeLe corps dépasse la taille permise.Allégez la demande.
429rate_limitedTrop d’appels pour cette clé dans la minute.Attendez le délai de l’en-tête Retry-After, puis reprenez.
429too_many_attemptsTrop de demandes vers ce numéro en peu de temps.Attendez avant de relancer : on ne harcèle pas un téléphone.
500internal_errorUne erreur chez Payiz.Réessayez avec la même clé d’idempotence ; citez le « request_id » au support.
503payout_unavailableAucune voie ne peut envoyer ce retrait pour le moment.Réessayez plus tard.
503service_unavailableUn service dont l’appel dépend ne répond pas.Réessayez avec la même clé d’idempotence.

Un paiement qui échoue chez le payeur n’est pas une erreur d’appel : la demande le dit, avec son failure_code. Voir Le paiement direct.

Où regarder

Chaque appel, sa réponse et sa durée s’inscrivent dans Développeurs › Journaux, gardés 30 jours : c’est là qu’on comprend une intégration qui coince.

© 2026 PayizUne question ? L’aide est dans le rond, en bas à droite.

Un statut HTTP, et un corps stable — le même pour toutes les ressources. Le code est le contrat : votre programme s’y fie ; le message est pour un humain, en français ou en anglais selon Accept-Language.

Le corps

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "operator_required",
    "message": "Choisissez votre opérateur.",
    "details": {
      "operators": [
        {
          "code": "mtn",
          "name": "MTN"
        },
        {
          "code": "moov",
          "name": "Moov"
        }
      ]
    },
    "request_id": "req_01j9x3t8m2k4c7vd9qhs"
  }
}
typeREQUIS« authentication_error » · « invalid_request_error » · « rate_limit_error » · « api_error »La famille : qui doit corriger.
codeREQUIS« missing_api_key » · « invalid_api_key » · « insufficient_permissions » · « parameter_missing » · « parameter_invalid » · « resource_missing » · « payload_too_large » · « idempotency_key_reuse » · « rate_limited » · « merchant_inactive » · « live_mode_not_enabled » · « currency_unavailable » · « limit_exceeded » · « balance_insufficient » · « payment_closed » · « attempt_in_progress » · « phone_invalid » · « operator_required » · « operator_unavailable » · « country_unavailable » · « exchange_rate_unavailable » · « amount_out_of_range » · « idempotency_key_required » · « payment_declined » · « direct_not_enabled » · « too_many_attempts » · « payment_disputed » · « refund_amount_too_high » · « refund_reason_invalid » · « payment_not_refundable » · « recipient_not_ready » · « payout_unavailable » · « conflict » · « not_permitted » · « setting_missing » · « service_unavailable » · « internal_error »Le cas précis, stable, fait pour être testé. La liste : la page « Les erreurs ».
messageREQUIStexteUne phrase déjà écrite pour être montrée, en français ou en anglais selon Accept-Language.
paramtexteLe champ fautif, quand il y en a un.
detailsobjetCe qui aide à corriger, selon le code : par exemple « remaining » pour un remboursement trop gros.
request_idtexteL’identifiant de l’appel, aussi dans l’en-tête Request-Id : à citer quand vous nous écrivez.

Un code ne se retire jamais sans passer par les Changements. Citez request_id au support : il retrouve l’appel dans vos journaux.

Les codes

StatutcodeQuandQue faire
400parameter_missingUn champ requis manque ; « param » le nomme.Ajoutez le champ.
400parameter_invalidUn champ ne se lit pas ou sort de ses bornes ; « param » le nomme quand il y en a un.Corrigez la valeur d’après le message.
400currency_unavailableLa monnaie n’est pas ouverte, ou pas à cet espace.Choisissez une monnaie de votre espace.
400limit_exceededLe montant dépasse un plafond du palier, en réel.Un montant plus petit, ou un palier plus haut.
400balance_insufficientLe solde ne couvre pas le remboursement ou le retrait, frais compris.Attendez des encaissements, ou demandez moins.
400phone_invalidLe numéro du payeur ne se lit pas : trop court, trop long, ou d’un format inconnu.Envoyez-le au format international (+229…), ou précisez « country ».
400operator_requiredLe numéro peut appartenir à plusieurs opérateurs de son pays.Demandez au payeur son opérateur, et passez « operator » avec un des codes de « details.operators ».
400operator_unavailableAucun opérateur ouvert ne correspond à ce numéro, ou l’opérateur ne prend pas ce montant pour le moment.Proposez un autre numéro ; GET /v1/payment_methods dit ce qui est ouvert.
400country_unavailableLe pays du numéro, ou sa monnaie, n’est pas ouvert.Proposez un numéro d’un pays ouvert : GET /v1/payment_methods les liste.
400exchange_rate_unavailableLe payeur paie dans une autre monnaie que le paiement, et le taux du jour manque.Réessayez un peu plus tard, ou proposez un numéro du pays de votre monnaie.
400amount_out_of_rangeLe montant sort des bornes de l’opérateur, dans la monnaie du payeur.Lisez « details.min_amount » et « details.max_amount », dans « details.currency ».
400idempotency_key_requiredUn appel qui envoie une demande sur un téléphone, sans en-tête Idempotency-Key.Tirez la clé de votre commande (cmd-42) : un second clic donnera la même.
400refund_amount_too_highLe montant dépasse ce qui reste à rendre sur le paiement.Demandez au plus « details.remaining ».
400refund_reason_invalidLe motif n’est pas un de ceux que Payiz accepte.Prenez-le dans GET /v1/refund_reasons.
401missing_api_keyAucune clé dans l’en-tête Authorization.Envoyez « Authorization: Bearer sk_… ».
401invalid_api_keyClé inconnue, révoquée, expirée, d’un autre mode, ou appel depuis une adresse non autorisée.Vérifiez la clé et ses adresses autorisées dans votre espace.
402payment_declinedPayiz refuse cette demande. La raison n’est pas donnée.Ne relancez pas : proposez un autre moyen au payeur.
403insufficient_permissionsLa clé n’a pas le geste que l’appel demande.Donnez ce geste à la clé, ou servez-vous d’une autre.
403merchant_inactiveL’espace est suspendu ou fermé.Écrivez au support depuis votre espace.
403live_mode_not_enabledUne clé réelle, alors que le palier de l’espace n’ouvre pas le réel.Terminez la vérification du compte dans votre espace.
403direct_not_enabledUne demande lancée par l’API en réel, alors que le paiement direct n’est pas ouvert à l’espace.Envoyez « payment_url » au payeur, ou demandez l’ouverture du direct.
403not_permittedLe geste est refusé pour cet espace.Lisez le message ; écrivez au support si besoin.
404resource_missingL’objet n’existe pas, ou pas pour cette clé et ce mode.Vérifiez l’identifiant et le mode de la clé.
409idempotency_key_reuseLa même clé d’idempotence revient avec un autre corps, ou pendant que la première demande s’exécute.Une clé par demande ; rejouez la même demande à l’identique.
409payment_closedLe paiement est payé, annulé ou expiré.Lisez son état dans « details.status ».
409attempt_in_progressUne demande attend déjà la validation du payeur.Attendez son issue, par webhook.
409payment_disputedLe paiement est contesté : la somme est déjà retenue.Attendez l’issue du litige.
409payment_not_refundableLe paiement ne peut plus être remboursé (déjà rendu, ou en cours de remboursement).Lisez le paiement et ses remboursements.
409recipient_not_readyPar sécurité, un bénéficiaire neuf ne reçoit qu’après un délai.Réessayez après « details.usable_at ».
409conflictL’objet n’est pas dans un état qui permet ce geste.Relisez l’objet, puis décidez.
409setting_missingUn réglage de la plateforme manque : c’est à Payiz de le poser.Écrivez au support avec le « request_id ».
413payload_too_largeLe corps dépasse la taille permise.Allégez la demande.
429rate_limitedTrop d’appels pour cette clé dans la minute.Attendez le délai de l’en-tête Retry-After, puis reprenez.
429too_many_attemptsTrop de demandes vers ce numéro en peu de temps.Attendez avant de relancer : on ne harcèle pas un téléphone.
500internal_errorUne erreur chez Payiz.Réessayez avec la même clé d’idempotence ; citez le « request_id » au support.
503payout_unavailableAucune voie ne peut envoyer ce retrait pour le moment.Réessayez plus tard.
503service_unavailableUn service dont l’appel dépend ne répond pas.Réessayez avec la même clé d’idempotence.

Un paiement qui échoue chez le payeur n’est pas une erreur d’appel : la demande le dit, avec son failure_code. Voir Le paiement direct.

Où regarder

Chaque appel, sa réponse et sa durée s’inscrivent dans Développeurs › Journaux, gardés 30 jours : c’est là qu’on comprend une intégration qui coince.