Aller au contenu

Créer un bénéficiaire

Enregistrer une destination une fois : le canal qui détermine l'opérateur, un autre compte Wajub, et le nom sur un portefeuille.

POSThttps://api.wajub.com/beneficiaries
channelstringobligatoire
Le canal de l'opérateur qui dessert le numéro, comme cm.mtn ou ke.mpesa. Au Cameroun uniquement, cm.mobile laisse le numéro décider : voir ci-dessous.
namestringobligatoire
Le bénéficiaire, tel qu'il doit apparaître sur le payout. Également utilisé comme nom du titulaire du compte.
phonestringfacultatif
Le numéro qui reçoit les fonds. Obligatoire sauf si vous transmettez account_number. Le champ s'appelle phone, pas phone_number.
account_numberstringfacultatif
La destination lorsqu'il ne s'agit pas d'un numéro de téléphone. L'un des deux champs est obligatoire. phone renseigne celui-ci si vous l'omettez.
emailstringfacultatif
L'adresse de contact du bénéficiaire. Elle ne sert actuellement à aucun envoi.
country_codestringfacultatif
Deux lettres. Par défaut, les deux premières lettres du slug du canal. cm.mtn donne donc CM.
notestringfacultatif
Texte libre pour votre propre référence, limité à 1 000 caractères.
metadataobjectfacultatif
Vos propres paires clé-valeur, renvoyées sans modification à chaque lecture.

Envoyez la requête avec la clé secrète. La création d'un bénéficiaire possède une limite de requêtes plus stricte que le reste de l'API. Ajouter une destination représente en effet la moitié de ce dont un attaquant a besoin pour déplacer des fonds.

curl https://api.wajub.com/beneficiaries \
  -H "Authorization: sk.xxxxxxxxxxxxxxxx…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: beneficiary-amina" \
  -d '{
    "channel": "cm.mtn",
    "name": "Amina Traoré",
    "phone": "+237670000000"
  }'

La réponse est 201 Created. Chaque payout utilise le champ id, préfixé par ben_ en live et ben_test_ dans la sandbox. Les deux environnements ne peuvent donc jamais être confondus.

Réponse · 201 Created
{
"code": 201,
"status": "Created",
"message": "Beneficiary created successfully",
"beneficiary": {
"id": "ben_7Kq2mX9vL4tRb3nP8sZc",
"name": "Amina Traoré",
"phone": "+237670000000",
"country_code": "CM",
"note": "Retainer, paid on the 1st",
"metadata": [
],
"sandbox": false,
"is_active": true,
"type": "standard",
"verified": true,
"payment_method": {
"id": "pm_4Dw8kR2xN6vQ",
"type": "mobile_money",
"name": "MTN Mobile Money"
},
"created_at": "2026-09-11T14:00:00+00:00",
"updated_at": "2026-09-11T14:00:00+00:00"
}
}

La destination ne figure pas dans la réponse

payment_method contient un id, un type et un libellé, mais jamais le numéro qui reçoit les fonds. Aucun endpoint de l'API ne permet de relire la destination d'un bénéficiaire. Si vous devez montrer au bénéficiaire où ses fonds sont envoyés, conservez votre propre copie lors de la création. Les champs laissés vides sont retirés de la réponse au lieu d'être renvoyés avec null. Un objet metadata vide revient sous forme de [], et non {}. Typez-le donc comme une map pouvant aussi arriver sous forme de tableau vide.

En sandbox, des numéros de test seulement

Un bénéficiaire sandbox doit déjà porter un numéro de test à sa création : toute autre valeur répond 422 sur phone et account_number avec Invalid sandbox test number. Use a Mobile Money test number, e.g. +237670000000 (success), +237670000001 (insufficient funds), +237670000002 (failure), +237670000003 (timeout), +237670000004 (canceled). Chargez de vrais numéros en live seulement. Les numéros de test de chaque opérateur figurent dans Scénarios de test.

Le canal détermine l'opérateur

Indiquez le canal de l'opérateur : ke.mpesa, eg.vodafone, cm.mtn, cm.orange. Le Cameroun est la seule exception : quand vous avez un numéro camerounais sans son opérateur, transmettez cm.mobile, et l'opérateur, cm.mtn ou cm.orange, est déterminé à partir du numéro. En live, il vient du plan de numérotation du pays, comme pour un paiement ; en sandbox, des préfixes de test. Aucun autre pays n'a de canal générique : ke.mobile ou tout autre {country}.mobile est refusé comme un canal inconnu.

Cette résolution peut échouer. Elle renvoie alors une erreur claire au lieu de choisir un opérateur au hasard.

Réponse · 422 quand le numéro ne correspond à aucun opérateur
{
"code": 422,
"status": "Unprocessable Content",
"message": "Could not determine operator from phone number for cm.mobile. Use a valid number of that country or specify the channel explicitly (e.g. cm.mtn, cm.orange). (and 1 more error)",
"errors": {
"channel": [
"Could not determine operator from phone number for cm.mobile. Use a valid number of that country or specify the channel explicitly (e.g. cm.mtn, cm.orange)."
],
"phone": [
"Could not determine operator from this phone number for cm.mobile."
]
}
}

Si vous connaissez déjà l'opérateur, indiquez-le. cm.mobile sert lorsque vous n'avez qu'un numéro camerounais.

Payer un autre compte Wajub

Quand la personne que vous payez a déjà un compte Wajub, utilisez le canal wajub et son numéro de compte à 11 chiffres. L'argent ne quitte jamais Wajub : un solde est débité, l'autre crédité, sans réseau intermédiaire et sans attente.

Un bénéficiaire sur un autre compte Wajub
{
"name": "Boutique Ada",
"channel": "wajub",
"account_number": "12345678901"
}

Le compte doit exister, ne peut pas être le vôtre, et ne peut pas être un compte que Wajub a gelé : chaque cas est refusé avec 422 à la création du bénéficiaire, et un versement vers un compte gelé depuis échoue de lui-même. Le payer est un virement ordinaire, avec les mêmes plafonds et les mêmes statuts ; il réussit simplement tout de suite, et il est gratuit, car il n'y a aucun réseau à payer entre deux comptes Wajub. Sur un compte dont Wajub vérifie les bénéficiaires, le nom est comparé à la fiche de conformité du destinataire plutôt qu'aux données d'un opérateur.

En sandbox

Un versement sandbox sur ce canal réussit toujours : les scénarios de test ne s'y appliquent pas, et un échec sur ce canal ne s'observe qu'en live. Le solde sandbox du destinataire n'est jamais crédité. Seul le live déplace de l'argent entre comptes.

Vérifier le nom d'un portefeuille

POSThttps://api.wajub.com/beneficiaries/{id}/verify

L'appel ne prend aucun corps. Il demande à l'opérateur sous quel nom le portefeuille est enregistré et le compare au nom que vous avez déclaré. La comparaison ignore l'ordre des mots, les accents et la ponctuation, et tolère de petites différences d'orthographe.

Sur vos propres bénéficiaires, la réponse est une information. Le bénéficiaire reste payable quel que soit le résultat, l'appel répond 200, et registered_name porte le nom que détient l'opérateur quand il correspond : vous pouvez le montrer à la personne qui s'apprête à envoyer l'argent. En cas d'écart, il n'en porte que les initiales, P*** N*** : la vérification confirme un bénéficiaire, elle ne dit pas à qui appartient un numéro.

verificationCe qui s'est passéregistered_name
verifiedLe nom de l'opérateur correspond à celui que vous avez déclaréPrésent
name_mismatchL'opérateur détient ce numéro sous un autre nomSes initiales seulement, P*** N***
lookup_unavailableL'opérateur n'a pas pu être interrogé : il n'offre pas de recherche sur ce canal, il n'a pas répondu, ou il ne connaît pas le numéroAbsent
not_foundLe bénéficiaire n'a aucune destination de versement à vérifier. L'appel répond 422 avec This beneficiary has no payout destination to verify.Absent
Réponse · 200 quand l'opérateur détient un autre nom
{
"code": 200,
"status": "OK",
"message": "The operator holds this number under another name. The beneficiary can still be paid.",
"verification": "name_mismatch",
"registered_name": "P*** N***",
"beneficiary": {
"id": "ben_7Kq2mX9vL4tRb3nP8sZc",
"name": "Amina Traoré",
"verified": true,
"verification": "name_mismatch"
}
}

Les opérateurs qui répondent aujourd'hui sont MTN, Orange Money et Express Union au Cameroun, cm.mtn, cm.orange et cm.eu, ainsi qu'un compte Wajub, wajub. Tout autre canal renvoie lookup_unavailable.

Le bénéficiaire conserve le dernier résultat : verification le porte à chaque lecture, et il est absent tant qu'aucune vérification n'a eu lieu. verified est autre chose. Il indique si Wajub paiera le bénéficiaire en live, et ici un name_mismatch ne le change pas. Une exception : un bénéficiaire resté non vérifié, par exemple un vendeur que l'opérateur n'a pas pu confirmer quand votre compte était sur Relay, devient payable si les noms correspondent, et il est alors payé sous le nom que détient l'opérateur. Une différence de nom ou un opérateur injoignable le laisse impayable.

L'appel a son propre plafond, quel que soit votre plan : 10 vérifications par minute et 200 par jour et par compte en live, 10 par minute en sandbox. Au-delà, la réponse est 429. Il sert à vérifier vos propres bénéficiaires à mesure que vous les ajoutez, pas à interroger des numéros en masse.

Là où la vérification décide au lieu d'informer

Sur un compte Relay, et sur tout compte pour lequel Wajub l'exige, le même appel est une barrière. Un bénéficiaire déjà vérifié est renvoyé tel quel, tout résultat autre que verified répond 422, le bénéficiaire reste impayable, et registered_name n'est pas renvoyé. En sandbox, aucun opérateur ne peut être interrogé : un bénéficiaire y est créé vérifié sur un tel compte, et l'appel répond verified. Votre traitement d'un name_mismatch ne peut donc être éprouvé qu'en live. Un compte de versement ajouté dans le Dashboard n'est jamais vérifié par cet appel, sur aucun compte : vérifiez-le là-bas.

Que pensez-vous de ce contenu ?