Transferts
Refus avant l'envoi, échec chez l'opérateur ou limitation dans une boucle de payouts.
Un transfert envoie vos fonds vers l'extérieur. Il est donc plus strictement contrôlé qu'un paiement : clé autorisée, fréquence des appels et solde disponible. La plupart des problèmes de transfert proviennent du fonctionnement normal de l'un de ces trois contrôles.
Erreur 406 Private Key Required pour une clé publique
Vous avez envoyé une clé publique. Les payouts, le solde, les remboursements, les litiges, les bénéficiaires et les connexions Sync acceptent uniquement une clé privée.
| Route | Clé publique | Clé privée |
|---|---|---|
/payments | Acceptée | Acceptée |
/transfers, /balance, /refunds, /disputes, /beneficiaries, /accounts | 406 | Acceptée |
Notez le code. Il s'agit de 406, pas de 403. Une branche qui attend 403 pour détecter une
mauvaise clé ne s'exécute jamais ici.
Erreur 403 This API key does not have permission to write transfer liée au scope
Vous avez envoyé une clé restreinte sans le scope nécessaire. Les payouts exigent transfer.write
et les routes de lecture exigent transfer.read. Les scopes sont figés à la création de la clé.
Pour les élargir, créez une nouvelle clé.
Le transfert a immédiatement échoué
Lisez failure_reason sur l'objet du transfert, pas reason : reason est le libellé que vous
avez fourni. Trois codes couvrent la plupart des cas.
failure_reason | Cause | Action |
|---|---|---|
invalid_recipient | Le bénéficiaire est absent ou n'a pas de canal de payout | Corrigez le bénéficiaire, puis créez un nouveau transfert |
no_provider | Aucun prestataire n'est éligible pour ce canal et ce montant en ce moment | Réessayez plus tard, ou payez sur un autre canal |
provider_rejected | Tous les prestataires éligibles ont refusé le payout | Lisez failure_message, corrigez, puis créez-en un nouveau |
Quand un prestataire refuse, vérifiez d'abord que le numéro appartient à l'opérateur du channel
indiqué. Au Cameroun, un numéro qui commence par +23767 appartient à MTN et +23769 à Orange.
Formats de numéros de téléphone contient le tableau des préfixes, et
Motifs d'échec les autres codes.
Un solde trop faible pour le payout ne donne pas un transfert en échec : POST /transfers répond
422 avec error_code: insufficient_balance et rien n'est créé. Son message vaut Insufficient available balance for this payout. (and 1 more error) : la phrase figure sur amount et sur
balance, et le suffixe compte la seconde. Le même suffixe termine un refus faute de prestataire et
le numéro sandbox de fonds insuffisants. Comparez error_code, ou lisez errors, jamais le message
entier. Le moment du
règlement en est souvent la cause. Un encaissement succeeded n'est pas encore utilisable. Il
devient disponible après le règlement. Votre solde contient une valeur available et une valeur
pending. Un payout utilise uniquement available.
Je ne peux pas annuler un transfert
Il n'existe aucun endpoint d'annulation. POST /transfers crée le transfert. GET /transfers et
GET /transfers/{id} le lisent. Une fois créé, le transfert passe à succeeded ou failed, ou à
cancelled s'il est annulé avant d'être envoyé (à partir de la version d'API 2026-10-12, les
versions antérieures le lisent failed). Un payout que l'opérateur annule de son côté finit failed.
Ce choix est volontaire. Un payout s'exécute sans intervention humaine. Une période d'annulation permettrait de reprendre les fonds après leur crédit au bénéficiaire. Validez avant d'envoyer.
Réponse 429 dans une boucle de payouts
Les payouts possèdent leur propre plafond en plus des quatre limites générales : 20 par minute, par
équipe et par environnement, quel que soit votre plan, partagé par les payouts, les lots, les payouts
Sync et la création de bénéficiaires. Une boucle sur une liste de bénéficiaires l'atteint bien avant
le quota de l'équipe. Un payout live qui a attendu plus de dix secondes derrière un autre payout du
compte répond aussi 429, avec error_code: payout_queue_busy et Retry-After : rien n'a été créé,
renvoyez-le.
La réponse 429 de ce plafond ne contient pas le champ type présent avec les limites générales.
Un handler qui lit toujours type échoue donc sur la réponse qu'il doit justement traiter.
Espacez les appels, respectez retry_after et exécutez les lots de payouts en dehors des périodes où
une personne peut en attendre un. Gestion des limites de requêtes
présente cette stratégie.
Payer plusieurs personnes à la fois
POST /transfers/batch envoie jusqu'à 500 payouts en un seul appel, et ne
compte qu'une fois dans le plafond de 20 par minute, quelle que soit sa taille. Il ne compte aussi
qu'une fois dans le nombre horaire d'appels de payout de la
vélocité, et un nouveau lot est refusé en entier
avec 422 quand l'heure n'a plus de place. Chaque ligne ajoute son montant au montant horaire et échoue
séparément : la réponse liste chaque ligne avec son status, et une ligne rejetée porte un
message.
Après un délai expiré ou un échec partiel, renvoyez le lot entier avec la même Idempotency-Key.
Seules les lignes qui ne sont pas passées partent, les autres reviennent telles qu'elles sont déjà,
même quand l'heure n'a plus de place : seules les lignes encore à envoyer sont alors rejetées, avec
le message de vélocité, et la même clé les enverra plus tard. Ne renvoyez jamais sous une nouvelle
clé un lot dont vous n'êtes pas sûr qu'il a échoué : chaque ligne serait payée une seconde fois.
Une ligne dont la reference a déjà servi pour un autre payout est rejetée au lieu d'être envoyée.
Le Dashboard ne propose pas de téléversement CSV.
Le bénéficiaire affirme n'avoir rien reçu
Avant de suspecter le transfert, vérifiez ses données.
curl https://api.wajub.com/transfers/po_9xh0XQ5wu2lxCSUGajfv \
-H "Authorization: sk.xxxxxxxxxxxxxxxx…" \
| jq '.transfer | { status, failure_reason, amount, currency, created_at }'succeeded signifie que l'opérateur a confirmé le crédit. Les fonds se trouvent alors chez le
bénéficiaire. La question doit lui être adressée ou transmise à son opérateur, pas à Wajub.
processing signifie que le transfert est toujours en cours. En Mobile Money, il dure généralement
moins de deux minutes, mais peut prendre plus de temps sur un réseau encombré.
Pages associées
- TransfertsLa création d'un payout et les champs nécessaires.
- Solde et règlementsLa différence entre available et pending, et le moment où un encaissement devient utilisable.
- Motifs d'échecTous les codes de motif d'un transfert échoué.
- Gestion des limites de requêtesLe plafond des payouts et la méthode pour le respecter.