Décimal, jamais flottant
Tous les montants sont des strings décimales côté API, jamais des floats. Pour éviter les erreurs d’arrondi IEEE-754 sur les montants financiers :
// ✅ Correct
{ "amountRequested": "100.50" }
{ "amount": "0.123456789012345678" }
// ❌ Faux — précision perdue
{ "amountRequested": 100.50 }
{ "amount": 0.1 + 0.2 } // = 0.30000000000000004
Le SDK Node accepte number | string mais vous devriez toujours passer une string pour les opérations financières : utilisez decimal.js ou bignumber.js côté votre code.
Précision par devise fiat
| Devise | Décimales |
|---|
| XOF, XAF | 0 (CFA, pas de subdivision) |
| USD, EUR, GBP | 2 (cents) |
| GHS, NGN, KES | 2 |
| TND | 3 (millime) |
| BHD, KWD, OMR | 3 |
L’API valide selon la devise : amountRequested: "100.50" en XOF → 422 (XOF n’a pas de centimes).
Précision par crypto
| Asset | Décimales blockchain | Décimales affichage widget |
|---|
| USDT.TRC20 | 6 | 2 |
| USDT.BEP20 | 18 | 2 |
| USDC.BEP20 | 18 | 2 |
| BTC | 8 | 8 |
| ETH | 18 | 6 |
| SOL | 9 | 4 |
Le widget arrondit toujours au plafond (ceilToDecimals) sur les décimales d’affichage pour que le montant affiché au client matche exactement ce que la blockchain attendra. Évite les faux positifs “underpaid” quand le client copie-colle le montant affiché.
Conversion fiat → crypto
À la création d’un PaymentIntent requestedCurrencyType: 'fiat', le montant fiat est saisi tel quel. La conversion en crypto est figée à la sélection de l’asset par le client et renvoyée sur l’intent (amountCryptoExpected).
Le montant crypto n’est pas verrouillé à la création. Il est calculé à la sélection de l’asset. Si vous voulez un montant stable au plus près du paiement, créez l’intent à la dernière seconde possible (idéalement au moment où le client clique “Payer”).
Frais
Les frais sont calculés côté serveur et renvoyés sur l’intent, en décimal (string). Le SDK ne fait aucune math côté client : amountCryptoExpected et feeAmount proviennent de l’API.
Affichage côté UI
Pour formater un montant à afficher au client :
import Decimal from 'decimal.js';
const amount = new Decimal(intent.amountCryptoExpected);
const display = amount.toFixed(intent.assetCode === 'BTC' ? 8 : 2);
// "0.12345678" ou "100.50"
Pour les fiat, utilisez Intl.NumberFormat :
new Intl.NumberFormat('fr-FR', {
style: 'currency',
currency: intent.currencyRequested,
}).format(new Decimal(intent.amountRequested).toNumber());
Pour la conversion vers Number à l’affichage uniquement, OK. Pour toute math arithmétique → restez en Decimal jusqu’au bout.