Aller au contenu

Transferts et payouts

Envoyez de l'argent, comprenez d'où il vient et les conditions à remplir au préalable.

Toutes les autres sections de cette documentation parlent d'argent qui entre. Celle-ci traite de l'argent qui part vers un fournisseur, un livreur, un vendeur de votre marketplace ou votre propre compte.

Un payout n'est pas le miroir d'un paiement. Un paiement réussit ou ne vous coûte rien. Un payout dépense des fonds que vous détenez déjà. C'est pourquoi il passe plus de contrôles que toute autre opération de l'API.

POST /transfersdouze contrôlestous validésben_3Vt8pQ…ben_7Kq2mX…reçu 10 000available1 250 000 XAFpending75 000 XAFreserved0 XAF10 100 XAF
  1. 1Seul available peut sortir

    Pending est encaissé mais pas réglé, reserved est déjà engagé. Un payout ne puise dans aucun des deux.

  2. 2Douze contrôles d'abord

    Chacun répond avec son propre 422. Rien n'est réservé tant qu'ils ne sont pas tous passés, un refus ne laisse donc aucune trace.

  3. 3Les frais sont aussi retenus

    Envoyer 10 000 XAF en réserve 10 100. Le 1 % est prélevé à la fin, mais il est retenu dès le départ.

Un payout prélève un solde que vous détenez déjà. Une série de contrôles est d'abord exécutée. Ce n'est qu'après leur réussite que le montant et ses frais quittent le solde disponible pour passer dans le solde réservé. Le bénéficiaire reçoit le montant, et les frais restent acquis au circuit.

Fonctionnalités disponibles aujourd'hui

BesoinSolution
Payer une personne ou une entrepriseTransferts
Conserver une liste des personnes que vous payez souventBénéficiaires
Connaître le montant disponible et celui déjà régléSolde et règlements
Payer plusieurs personnes à la foisPOST /transfers/batch, jusqu'à 500 lignes par appel
Payer la même personne selon un calendrierSettings, Transfers, Automation, à partir du plan Growth

Un lot accepte jusqu'à 500 payouts en un seul appel, sur tous les plans. Son en-tête Idempotency-Key est obligatoire, et chaque ligne porte une reference unique dans le lot. Chaque ligne passe les mêmes contrôles qu'un payout seul, bornes de la devise comprises, et désigne son bénéficiaire par son id seulement : un numéro de téléphone ou un e-mail est refusé avec beneficiary_not_found. Chaque ligne réussit ou échoue indépendamment : un vendeur sans destination vérifiée ne bloque pas les autres. Renvoyer le même lot avec la même clé n'envoie que les lignes qui ne sont pas passées. Le Dashboard ne propose pas d'import CSV de payouts.

Deux choses refusent un lot entier, avant qu'aucune ligne ne parte. Une ligne mal formée, par exemple un champ manquant, une currency qui ne fait pas trois lettres ou une reference répétée dans le lot, répond 422 pour tout l'appel, avec la ligne fautive nommée dans errors (transfers.3.amount). L'autre est un en-tête Idempotency-Key absent ou vide. Limitez cette clé aux lettres, chiffres et . _ : -.

Pour le plafond horaire de vélocité, un lot est un seul appel de payout quel que soit son nombre de lignes, et chaque ligne ajoute son montant au montant horaire.

Un transfert récurrent paie à un bénéficiaire un montant fixe chaque heure, jour, semaine ou mois. Chaque exécution crée un payout ordinaire, soumis à tous les contrôles ci-dessous, et un calendrier mis en pause peut reprendre.

Origine des fonds

Wajub conserve un solde par devise pour votre compte. Les encaissements l'alimentent, les payouts y puisent, et aucun destinataire ne reçoit de fonds qui n'ont pas d'abord été couverts par le solde.

GEThttps://api.wajub.com/balance

Un appel renvoie le solde de l'environnement associé à votre clé. Il répartit l'argent entre cinq montants qui n'ont pas la même signification.

Réponse · 200 OK
{
"code": 200,
"status": "OK",
"message": "Balance retrieved",
"balance": {
"total": 1325000,
"available": 1250000,
"pending": 75000,
"reserved": 0,
"credit": 0,
"currency": "XAF",
"environment": "live"
}
}

available est le seul montant utilisable pour un payout. pending correspond aux fonds encaissés mais pas encore réglés en votre faveur. reserved correspond aux fonds déjà engagés dans des payouts en cours. Ajoutez ?currency= pour consulter le même solde converti dans une autre devise.

Coût d'un payout

Sur le circuit Wajub, un payout est facturé 1 % fixe par défaut. Votre plan peut définir un taux différent par canal. Un payout vers un autre compte Wajub (wajub) est gratuit, et un virement bancaire (wire) porte des frais fixes au lieu d'un taux, voir Frais et tarification. Les frais sont débités à la fin du transfert, mais ils sont réservés avec le principal dès sa création. Envoyer 10 000 XAF réserve donc 10 100 XAF, et non 10 000 XAF.

Le routage vers votre propre compte prestataire change ce fonctionnement. Un payout qui passe par un prestataire que vous avez apporté n'est pas financé par votre solde Wajub. Il n'entraîne donc aucuns frais Wajub et ne réserve rien. Le prestataire vous facture directement selon ses propres conditions.

Conditions d'exécution d'un payout

Cette partie mérite d'être lue avant votre premier transfert live. La création exécute une série de contrôles. Chacun renvoie une réponse 422 avec son propre message et son propre error_code plutôt qu'un échec générique. Aiguillez votre code sur ce code ; la liste complète figure dans Erreurs.

ContrôleÉlément vérifiéerror_code
Plafonds du montantLe minimum et le maximum configurés pour cette deviseamount_out_of_range
BénéficiaireSa résolution sur votre compte, son activation et la présence d'un moyen de paiementbeneficiary_not_found, beneficiary_inactive, beneficiary_missing_payment_method
CanalUn canal de payout : Mobile Money, un portefeuille Djamo ou un autre compte Wajub par l'API, et un compte bancaire via un compte de versementchannel_not_supported
Payouts suspendus sur toute la plateformeLa suspension des payouts sur tout Wajub, pour tous les comptespayouts_suspended
Restrictions du compteUne restriction transfers active sur votre comptemerchant_restricted
Solde négatifAucun payout ne part tant que available est sous zéro, quelle que soit la devisenegative_balance
Réserve Sync LiteLe payout d'un marchand Lite ne peut pas entamer la part retenue pour les remboursementsreserve_held
Vérification de la destinationLa vérification du moyen de paiementbeneficiary_not_verified
Délai de carence de la destinationUne destination ajoutée ou modifiée à l'instant ne peut être payée qu'après son payout_allowed_afterbeneficiary_cooling_off
Votre propre plafond quotidienLe nombre et le montant définis dans Transfer security settings. Les payouts du jour dans toutes les devises sont convertis en XAF avant la comparaison du montant. Ils comptent qu'ils soient pending, retenus en review, processing ou succeeded ; les payouts échoués ou annulés ne comptent pasdaily_count_limit_exceeded, daily_amount_limit_exceeded
Plafond de la plateformeUne limite stricte selon le palier KYC, que vous ne pouvez pas augmenter vous-mêmesingle_payout_limit_exceeded, daily_payout_limit_exceeded, monthly_payout_limit_exceeded, payouts_not_enabled
VélocitéLes plafonds horaires sur les appels de payout acceptés et sur le montant versétoo_many_payouts, hourly_payout_amount_exceeded
Plafond du canalLa limite par transfert de cet opérateuramount_above_channel_limit
Disponibilité du prestataireL'existence d'une route de payout pour ce canal et cette deviseno_provider
FondsSur une route Wajub, available couvre le montant et les fraisinsufficient_balance

L'ordre importe moins que le principe : rien n'est réservé avant la réussite de tous les contrôles, et un transfert qui échoue à l'un d'eux n'a jamais existé. Une chose survit pourtant au refus : un bénéficiaire passé en ligne, sous forme d'objet, est créé avant les contrôles. Il reste sur votre compte et dans GET /beneficiaries, sans webhook. Une nouvelle tentative avec le même canal et le même numéro paie ce même bénéficiaire, sous le nom de sa création, au lieu d'en créer un second.

Les deux seuils qui vous appartiennent se trouvent sous Settings, Transfers : la confirmation manuelle, avec un montant facultatif en dessous duquel elle ne s'applique pas, dans l'onglet General, et le montant d'examen ainsi que les plafonds quotidiens en nombre et en montant dans l'onglet Security. Une retenue qu'ils déclenchent reste levée par Wajub, pas depuis votre propre Dashboard, pour qu'une session détournée ne puisse pas la lever.

Le même onglet Security porte deux interrupteurs qui s'appliquent aux payouts lancés depuis le Dashboard, sur tous les plans. Pour protéger les payouts faits par l'API, utilisez des clés restreintes et une liste d'IP autorisées pour l'API. Require 2FA refuse un payout tant que le membre n'a pas saisi de code de vérification de sécurité et validé son second facteur dans les 30 dernières minutes. IP whitelist refuse tous les payouts tant que l'équipe n'a pas de liste d'IP pour le Dashboard : la liste elle-même se règle dans la sécurité de l'équipe, cet interrupteur vérifie seulement qu'elle existe. Les deux réglages se modifient en mode live, par le propriétaire ou un membre qui a manage_settings.

Créer un transfert

POSThttps://api.wajub.com/transfers

Un transfert nécessite un montant, une devise et un destinataire. Le destinataire peut être un bénéficiaire déjà enregistré, transmis par son id, ou ses coordonnées complètes. Dans ce dernier cas, le bénéficiaire est créé pendant l'appel.

curl https://api.wajub.com/transfers \
  -H "Authorization: sk.xxxxxxxxxxxxxxxx…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: payout-892" \
  -d '{
    "beneficiary": "ben_7Kq2mX9vL4tRb3nP8sZc",
    "amount": 10000,
    "currency": "XAF",
    "description": "Supplier payment #892"
  }'

La réponse est 201 Created et le transfert revient avec le statut processing, alors qu'il est déjà en cours d'acheminement. Les deux environnements se comportent de la même façon. Un transfert dans la sandbox puise dans votre solde sandbox, puis se règle tout seul quelques secondes plus tard. Le résultat dépend du numéro de test du destinataire.

Aucune annulation possible

L'API permet de créer, lister et récupérer des transferts. Elle ne permet pas de les annuler. Une fois créé, un transfert évolue vers succeeded ou failed. Seul un examen peut le suspendre, et vous ne contrôlez pas cet examen. Considérez POST /transfers comme irréversible et effectuez vos contrôles avant l'appel, pas après.

Ressources

MéthodeEndpointUsage
POST GET/transfersCréer, lister et récupérer un payout
POST GET PUT DELETE/beneficiariesConserver les personnes que vous payez
GET/balanceConnaître le montant disponible
POST/transfers/batchPayer jusqu'à 500 personnes en un appel
POST/beneficiaries/{id}/verifyVérifier qu'un portefeuille appartient bien à la personne attendue

/identity/resolve répond 501 en live : il ne fonctionne qu'en sandbox et ne peut donc garantir aucun destinataire réel. Le contrôle de nom qui compte est POST /beneficiaries/{id}/verify : il interroge l'opérateur en live et renvoie le nom qu'il détient, à titre d'information. Vérifier le nom d'un portefeuille

Toutes ces ressources nécessitent la clé secrète. Une clé publique est refusée, tout comme un navigateur. Les routes de payout sont les plus strictement protégées de l'API. Si vous effectuez un payout pour le compte d'un compte connecté, l'en-tête X-Sync permet de le sélectionner. La page Sync détaille ce fonctionnement.

Que pensez-vous de ce contenu ?