Skip to main content

Transferts (Pay-Outs)

L’API Transfert (Pay-Out API) est simple à intégrer, car elle n’implique aucune interaction avec les clients finaux.

Effectuer un transfert

HUB2 API reference - Create a transfer La création d’un transfert (pay-out) ne nécessite qu’un seul appel au point de terminaison dédié. Exemple de requête :
L’API répond 201 Created et renvoie le transfert, avec son ID : l’identifiant unique que HUB2 crée pour chaque demande de transfert.
Enregistrez l’ID du transfert dans votre base de données : les étapes suivantes en ont besoin.
Pour toute demande au support HUB2 concernant un transfert, indiquez l’ID du transfert, et non votre propre référence.

Restrictions

Pour les transferts mobile money vers le Togo (destination.country = TG), le champ reference ne doit contenir aucun caractère spécial. Une référence contenant des caractères spéciaux est rejetée avec une erreur 400 Bad Request (code forbidden_special_chars). Les caractères autorisés sont les lettres, les chiffres, le tiret, le tiret bas, l’espace et la barre verticale. Sous forme de classe de caractères d’expression régulière : [A-Za-z0-9\-_\s|].

Destination paiement instantané

Pour payer un bénéficiaire identifié par un alias sur le système de paiement instantané de la BCEAO, définissez destination.type à instant_payment et envoyez l’alias du bénéficiaire dans destination.payeeAlias, avec le destination.country. Ni provider ni msisdn ne sont envoyés, et la devise doit être XOF.
Le compte débité est votre propre compte de transfert. Le paiement instantané est activé par HUB2 pour chaque marchand. Consultez le guide du paiement instantané pour les règles sur les alias, les erreurs et les valeurs du sandbox.

Relancer un transfert en toute sécurité

Cette section décrit le comportement qui s’applique lorsque la protection contre les doublons est activée sur votre compte. Cette protection n’est pas activée par défaut : HUB2 l’active pour chaque marchand et chaque environnement (sandbox ou live). Contactez le support HUB2 pour l’activer. Tant qu’elle n’est pas activée, HUB2 n’agit pas sur les références, et envoyer un transfert deux fois crée deux transferts. HUB2 enregistre toutefois les références que vous envoyez : elles comptent donc dès l’activation. Si vous avez réutilisé des références, passez à des références uniques avant de demander l’activation, sinon une référence réutilisée renvoie le transfert précédent en rejeu (200 OK, ou 409 Conflict si les détails diffèrent) et ne crée rien.
Lorsqu’une requête expire ou échoue sur une erreur réseau, vous ne savez pas si HUB2 a créé le transfert. Avec la protection contre les doublons, vous pouvez renvoyer la même requête sans payer deux fois. Deux contrôles s’appliquent, sur les points de terminaison de transfert suivants :
  • POST /transfers
  • POST /delegated/transfers
  • POST /delegated/transfers/irt
  • POST /irt/transfer
  • POST /irt/transfer/verified-recipient
Les transferts vers une destination paiement instantané ne sont pas concernés.

Même référence

Une reference identifie un seul transfert pour votre compte et votre environnement, quel que soit le point de terminaison ci-dessus qui l’a créé. Les références sont comparées à l’identique : elles sont sensibles à la casse et les espaces comptent, donc REF et REF sont deux références différentes. Deux requêtes portent les mêmes informations de transfert lorsqu’elles ont le même type de destination, le même pays de destination, le même bénéficiaire (numéro de téléphone ou numéro de compte bancaire), le même opérateur (ou code banque), le même montant et la même devise. La description, le nom du bénéficiaire et les autres champs ne sont pas comparés. Lors d’un rejeu, le corps de la réponse est le transfert d’origine tel qu’il est maintenant, avec son statut actuel. La réponse ne diffère d’une création que par le statut 200 et l’en-tête X-Idempotent-Replay, envoyé uniquement lors d’un rejeu.
Une erreur duplicate_reference ressemble à ceci :
Pour relancer un transfert après un délai dépassé, renvoyez exactement la même requête avec la même référence. Pour payer à nouveau après l’échec d’un transfert, utilisez une nouvelle référence : la même référence renvoie toujours le transfert d’origine, quel que soit son statut.

Mêmes informations sous une autre référence

Un second contrôle vous évite de payer deux fois le même bénéficiaire sous deux références différentes. Un transfert est refusé lorsqu’un transfert avec les mêmes informations a été créé pour votre compte et votre environnement sous une autre référence il y a moins de 15 minutes, sur l’un des points de terminaison ci-dessus. Les informations comparées sont les mêmes que ci-dessus : type de destination, pays, bénéficiaire, opérateur (ou code banque), montant et devise. Un transfert échoué ou annulé est ignoré. Ce contrôle s’active séparément du premier, en complément. Demandez au support HUB2 d’activer les deux. Le transfert refusé n’est pas créé, et sa référence reste libre. L’API répond 409 Conflict avec le code possible_duplicate. Le corps de cette erreur contient deux champs de plus que le format d’erreur habituel :
Le message ci-dessus est abrégé.

Confirmer un doublon possible

Vérifiez d’abord le transfert précédent. S’il s’agit d’une erreur, ne faites rien. Si le second transfert est voulu, renvoyez-le pour le confirmer : même point de terminaison, même reference, mêmes informations de transfert, avec le rejection_id du refus dans un champ rejectionId du corps, avant expires_at.
  • Un rejectionId confirme un seul transfert, une seule fois. Si vous renvoyez à nouveau le transfert confirmé, vous obtenez le transfert d’origine en rejeu (200 OK avec l’en-tête X-Idempotent-Replay: true).
  • Si un autre transfert avec les mêmes informations a été créé depuis le refus, la confirmation est de nouveau refusée avec possible_duplicate et un nouveau rejection_id.
  • Un rejectionId qui ne peut pas confirmer le transfert est rejeté avec 422 Unprocessable Entity, code invalid_duplicate_confirmation. La même réponse couvre tous les cas : un identifiant inconnu ou expiré, un identifiant déjà utilisé, ou un transfert, une référence ou un point de terminaison différent de celui qui a été refusé. Rien n’est créé. Renvoyez le transfert sans rejectionId : il est créé s’il n’est plus un doublon possible, ou refusé avec un nouveau rejection_id.
  • Un rejectionId doit être ndr_ suivi de 21 caractères (lettres, chiffres, _ ou -). Toute autre valeur est rejetée avec une erreur 400 Bad Request.
  • Hormis son format, rejectionId est ignoré tant que les deux contrôles ne sont pas activés sur votre compte.
Consultez la gestion des erreurs pour les codes d’erreur.

Récupérer les détails d’un transfert

HUB2 API reference - Get transfer details Pour récupérer les détails d’un transfert, appelez le point de terminaison dédié avec l’ID obtenu lors de la création du transfert (voir l’étape précédente). Ce point de terminaison renvoie tous les détails d’un transfert. Il n’est pas conçu pour suivre les changements de statut. Pour suivre le statut d’un transfert, interrogez plutôt le point de terminaison de statut (GET /transfers/{id}/status). Ce point de terminaison, comme tous les points de terminaison de l’API HUB2, est soumis à une limite de flux : s’il est appelé trop souvent, l’API HUB2 répond HTTP 429 Too Many Requests. Les limites sont les suivantes :
  • GET /transfers/{id} : 1 requête par 5 secondes pour chaque transfert
  • GET /transfers/{id}/status : 5 requêtes par 5 secondes pour chaque transfert
  • GET /transfers (liste) : 1 requête par 30 secondes
La documentation sur les limites de flux se trouve à cette adresse.
Exemple de requête :
Une fois les webhooks configurés pour le cycle de vie des transferts, HUB2 envoie un webhook pour chaque événement souscrit du transfert. Les webhooks sont la méthode recommandée pour suivre les changements de statut d’un transfert. Certains transferts sont traités rapidement, d’autres plus lentement, pour des raisons imprévisibles. Récupérer un transfert dont le statut n’a pas changé est inutile.
La documentation sur les webhooks se trouve à cette adresse.

Récupérer le statut d’un transfert

Ce point de terminaison est disponible depuis le 4 février 2025.
Pour des raisons de performances, le point de terminaison précédent n’est pas destiné à récupérer le statut d’un transfert. Un point de terminaison dédié remplit ce rôle. HUB2 API reference - Retrieve a transfer status Ce point de terminaison est également soumis à une limite de flux, mais celle-ci est moins restrictive que celle du point de terminaison précédent. Exemple de requête :
Si vous ne pouvez pas mettre en place les webhooks, utilisez ce point de terminaison pour récupérer le statut d’un transfert.

Lister les transferts

HUB2 API reference - List transfers Pour récupérer une liste de transferts, utilisez le point de terminaison dédié. Plusieurs paramètres de requête (voir ci-dessous) permettent de filtrer les résultats. Exemple de requête :
Paramètres de requête utilisés dans cet exemple :
  • from : début de la plage de dates, ici 2023-01-01T00:00:00.000.
  • to : fin de la plage de dates, ici 2023-01-01T12:00:00.000.
  • page et perPage : navigation dans les pages de résultats. perPage vaut 10 par défaut et ne peut pas dépasser 100.
Par défaut, si aucun filtre n’est défini, ce point de terminaison renvoie les 10 transferts les plus récents, classés par date de création décroissante.
Lorsque le paramètre isDelegated est renseigné, from est obligatoire et la plage de dates doit être inférieure à un an, sinon l’API renvoie une erreur 400.
Pour un grand nombre de transferts, utilisez des requêtes paginées pour tous les récupérer.

Pagination

Ce point de terminaison est paginé. L’en-tête de réponse Content-Range indique la plage des résultats renvoyés, par exemple 0-99/999999. La valeur après la barre oblique n’est pas le nombre exact de transferts correspondants. Pour récupérer tous les transferts correspondant au filtre, demandez la page suivante jusqu’à obtenir une page contenant moins de résultats que perPage. Définissez des filtres de date dès la requête initiale, afin que le nombre de résultats reste stable pendant la pagination (sauf si to est dans le futur).