Montants et devises

Unité majeure, décimales admises, frais, et format du numéro.

amount est en unité majeure

amount s'exprime dans l'unité majeure de currencyCode. amount: 100 avec currencyCode: "XOF" vaut cent francs, pas un franc. Il n'y a jamais de conversion en centimes à faire de votre côté.

Le champ ne porte pas le suffixe Major : c'est une dénomination historique du contrat public, et la renommer casserait les intégrations existantes.

Décimales admises

Chaque devise a un nombre de décimales propre, exposé par GET /v1/corridors/available sous currencies[].decimalPlaces :

  • XOF, XAF : 0 décimale. amount: 100.5 est refusé.
  • USDC : 2 décimales. amount: 10.50 est accepté, 10.505 est refusé.

Un montant plus précis que la devise ne l'autorise est rejeté en 400 VALIDATION_ERROR, jamais arrondi en silence. Lisez decimalPlaces plutôt que de coder l'échelle en dur : la liste des devises servies évolue.

Bornes de montant

minAmountMajor et maxAmountMajor, également sur GET /v1/corridors/available, sont donnés par couple (opérateur, devise) — un même opérateur peut apparaître plusieurs fois s'il sert plusieurs devises, avec des bornes différentes. maxAmountMajor peut être null : pas de plafond.

Un montant hors bornes est rejeté en 400 AMOUNT_OUT_OF_RANGE.

Ces bornes sont celles du canal, pas nécessairement celles du corridor qui encaissera : le corridor payant n'est résolu qu'au pay-in, à partir du numéro et du montant. Le rejet fait autorité, pas l'affichage.

Frais

Sur un pay-in réussi, le payeur est débité de amount, et votre solde est crédité de amount moins les frais. Les frais ne sont donc pas ajoutés par-dessus : ils sont prélevés sur l'encaissement.

GET /v1/pay-in/preview calcule les frais et le montant qui serait crédité pour un numéro, un montant et une devise donnés, sans créer de transaction — accessible avec une clé d'API, contrairement à GET /v1/pay-out/fees qui exige un jeton de session. Si votre facturation a besoin du net réellement encaissé sur une transaction passée, prenez-le du tableau de bord ou de vos relevés : l'aperçu est une estimation au moment de l'appel, pas un engagement — le corridor dispatché à l'encaissement réel peut différer si le montant change entre les deux appels.

Aucune transaction n'est créée, mais sur un canal qui sert plusieurs PSP, un numéro jamais vu peut se voir assigner durablement un couple de providers dès ce seul appel (dispatch MSISDN sticky) — un POST /v1/pay-in réel sur ce numéro produirait de toute façon la même affectation.

phoneNumber

Format international E.164 strict, tel que publié dans le schéma : + suivi de l'indicatif pays, sans espace ni séparateur.

+2250700000000

Le pays et l'opérateur sont déduits de ce numéro. C'est aussi lui qui reçoit la sollicitation : un numéro valide mais faux déclenche un push chez quelqu'un d'autre.

Champs sans effet observable

  • customerId est stocké mais jamais restitué par l'API. Il ne sert pas de clé de recherche.
  • metadata n'existe pas. Un objet metadata envoyé dans le corps est ignoré. Pour corréler, utilisez orderId (le vôtre) ou transactionId (le nôtre) — voir Idempotence.

On this page