Démarrage rapide
Alimentez un solde sandbox, envoyez votre premier payout, puis répétez l'opération en live.
Alimentez un solde sandbox, envoyez un premier payout et testez ses échecs, puis passez en live. Un payout dépense l'argent que vous détenez déjà : la première étape encaisse donc des fonds.
Un solde sandbox commence à zéro
Il n'existe aucun endpoint pour recharger un solde sandbox, aucun bouton dans la Konsole et aucun
crédit initial. Vous l'alimentez exactement comme un solde live, en encaissant un paiement. Si
vous ignorez l'étape 1, l'étape 3 renvoie 422 Insufficient sandbox balance to send 5000 XAF.
1. Alimenter le solde
Créez un paiement sandbox supérieur au montant que vous comptez envoyer, puis payez-le vous-même sur sa page de checkout. Accepter un paiement détaille correctement cet appel. Ici, il sert uniquement à alimenter le solde.
curl https://api.wajub.com/payments \
-H "Authorization: sk_test.xxxxxxxxxxxxxxxx…" \
-H "Content-Type: application/json" \
-d '{
"amount": 20000,
"currency": "XAF",
"email": "you@example.com",
"description": "Funding my sandbox balance"
}'Ouvrez l'authorization_url, choisissez Mobile Money et payez avec +237670000000. Ce numéro
réussit toujours dans la sandbox. Quelques secondes plus tard, le paiement est réglé et le montant
atteint votre solde, après déduction des frais de plateforme sandbox de 2 %. Un encaissement de
20 000 XAF laisse donc 19 600 XAF à envoyer.
2. Vérifier le montant disponible
Un seul appel, sans paramètre. Il renvoie le solde de l'environnement associé à votre clé. La même ligne de code lit donc le portefeuille sandbox aujourd'hui et le portefeuille réel demain.
https://api.wajub.com/balanceL'appel accepte un paramètre currency facultatif pour convertir le montant dans une autre devise.
Omettez-le pour obtenir la devise de votre compte.
curl https://api.wajub.com/balance \
-H "Authorization: sk_test.xxxxxxxxxxxxxxxx…"La réponse contient cinq montants.
available est le seul montant utilisable par un payout. Vérifiez environment si vous avez un
doute sur la clé utilisée.
3. Envoyer le payout
https://api.wajub.com/transfersTransmettez le destinataire inline. Wajub crée alors le bénéficiaire avec le payout, ce qui convient
à un premier essai. Le champ channel désigne l'opérateur du numéro. Le téléphone doit être un
numéro de test sandbox, sinon l'appel est refusé avant toute création.
Envoyez une valeur Idempotency-Key dès le premier appel. Elle ne coûte rien et constitue la seule
protection d'une nouvelle tentative, ici comme en production.
curl https://api.wajub.com/transfers \
-H "Authorization: sk_test.xxxxxxxxxxxxxxxx…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: first-payout-01" \
-d '{
"amount": 5000,
"currency": "XAF",
"description": "First test payout",
"beneficiary": {
"name": "Aminata Diallo",
"channel": "cm.mtn",
"phone": "+237670000000"
}
}'Wajub répond 201 Created et le payout possède déjà le statut processing. Aucune confirmation de
votre part n'est attendue.
Enregistrez transfer.id. C'est le seul identifiant unique : la reference que vous pouvez envoyer
revient telle quelle mais n'est jamais contrôlée pour son unicité, et aucun appel ne permet d'annuler
un payout existant.
Votre solde a subi deux mouvements. Les 5 000 XAF en sont sortis, avec 2 % de frais de payout sandbox ajoutés au montant plutôt que déduits. Le solde de 19 600 XAF passe donc à 14 500 XAF, tandis que le destinataire reçoit bien l'intégralité des 5 000 XAF.
4. Suivre son résultat
Environ deux secondes plus tard, le payout se termine. Le numéro du destinataire avait déterminé le résultat bien avant. Pour le connaître correctement, utilisez un webhook, pas une boucle.
| Événement | Déclencheur |
|---|---|
transfer.created | Le payout a été enregistré |
transfer.processing | Il a été transmis à l'opérateur |
transfer.succeeded | Les fonds sont arrivés. C'est l'événement sur lequel agir |
transfer.failed | Les fonds ne sont pas arrivés et failure_reason indique pourquoi |
Statuts et webhooks détaille l'enregistrement, les signatures et le contenu de chaque handler. Pendant vos premiers essais, récupérez plutôt le payout.
curl https://api.wajub.com/transfers/po_test_CSUGajfv9xh0XQ5wu2lx \
-H "Authorization: sk_test.xxxxxxxxxxxxxxxx…"status vaut maintenant succeeded et complete vaut true. Ces deux champs ne signifient pas la
même chose. complete indique la réussite, et non la fin de l'opération. Un payout échoué est donc
terminé alors que ce champ vaut toujours false.
POST /transfers
- Authorization
- sk_test.••••••••••••eU3i
- Content-Type
- application/json
- Idempotency-Key
- first-payout-01
- channel
- cm.mtn
- provider.selected
- MTN MoMo
- idempotency
- first-payout-01
Sent
{
"amount": 5000,
"currency": "XAF",
"beneficiary": {
"name": "Aminata Diallo",
"channel": "cm.mtn",
"phone": "+237670000000"
}
}Received, 201 from MTN MoMo
{
"code": 201,
"status": "Created",
"transfer": {
"id": "po_test_CSUGajfv9xh0XQ5wu2lx",
"status": "processing"
}
}5. Provoquer un échec
Un payout toujours réussi ne vous apprend rien sur le jour où un échec surviendra. La fin du numéro du destinataire détermine le résultat. Répétez donc le même appel avec chacune de ces valeurs avant de faire confiance à votre handler.
| Numéro | Résultat |
|---|---|
+237670000000 | succeeded |
+237670000001 | 422 à la création, error_code: insufficient_funds. Aucun payout et aucun webhook de transfert |
+237670000002 | failed, failure_reason: failure |
+237670000003 | failed, failure_reason: network_error |
+237670000004 | failed, failure_reason: invalid_recipient |
Seule la fin du numéro compte, pas l'opérateur. Ces cinq valeurs fonctionnent donc avec tous les préfixes connus de la sandbox. Un numéro qui ne correspond à aucune d'elles est immédiatement refusé.
Testez votre handler d'échec avec …0002, pas …0001
…0001 désigne un destinataire dont le portefeuille ne peut pas recevoir les fonds. La sandbox
refuse l'appel au lieu de créer un payout qui échoue. Comme aucun transfert ni événement de
transfert n'existe, le handler testé avec ce numéro n'est jamais appelé. Utilisez …0002.
Un payout refusé crée quand même son bénéficiaire en ligne
Le bénéficiaire passé sous forme d'objet est créé avant les contrôles. Un appel refusé, …0001
compris, le laisse donc sur votre compte, listé par GET /beneficiaries, et envoie
beneficiary.created comme tout nouveau bénéficiaire. Le même appel relancé avec le même canal et
le même numéro le réutilise au lieu d'en créer un second.
Passer ensuite en live
Remplacez sk_test. par sk.. Quatre éléments changent, mais aucun ne concerne votre code.
| Dans la sandbox | En live |
|---|---|
| Le solde est alimenté par des paiements de test et un payout coûte 2 % | Il est alimenté par de vrais encaissements et un payout coûte à partir de 1 %, selon le pays et le canal, réservé avec le principal à la création |
| Tous les numéros de test fonctionnent | Le numéro doit être réel et un chiffre incorrect paie une autre personne sans possibilité de récupérer les fonds |
| Le payout est exécuté immédiatement | Vos premiers payouts peuvent être retenus pour examen jusqu'à leur libération par Wajub |
| Les échecs proviennent de trois codes fixes | Ils proviennent de l'opérateur, avec son propre vocabulaire |
Vous devez surtout prévoir le troisième cas. Un payout retenu est créé avec le statut review, ses
fonds sont réservés et aucun appel de votre part ne peut le libérer. Envoyez votre premier payout
live à votre propre numéro, pour un petit montant et sous surveillance. N'en faites jamais la
première itération d'un lot. Transferts et payouts liste tous les contrôles d'un payout
live. Transferts décrit l'objet complet.
Pages associées
- TransfertsTous les champs, les quatre appels et les conditions d'exécution d'un payout.
- Prestataires et canauxTous les slugs de canaux, classés par pays et par opérateur.
- Statuts et webhooksLes cinq événements et le rôle de chaque handler.
- BénéficiairesEnregistrez une destination une fois, puis payez-la par son id.