Sign in
Conversions/Convert API

Convert API

Convertissez entre cryptomonnaies directement depuis le solde de votre commerce — obtenez une cotation en direct et exécutez au prix du marché.

La Convert API vous permet d'échanger entre les devises détenues dans le solde de votre commerce au prix de marché actuel — le même moteur qui alimente l'onglet Swap du tableau de bord commerçant, désormais accessible depuis votre backend.

Les endpoints Convert sont signés avec votre clé API habituelle — la même que celle utilisée pour les requêtes Payment API, pas la clé Payout API. Exécuter une conversion débite et crédite immédiatement le solde de votre commerce ; traitez donc cette clé avec la même prudence que tout identifiant qui déplace de l'argent.

Obtenir une cotation de conversion

Renvoie une cotation indicative pour une conversion au prix de marché actuel — le taux effectif et les montants résultants. Rien n'est débité ni réservé ; appelez-la autant de fois que nécessaire avant d'exécuter.

POST/v1/convert/price

Paramètres de la requête

ChampTypeRequisDescriptionValeur
from_currencystringouiDevise source
to_currencystringouiDevise cible. Doit différer de from_currency
amountdecimalouiMontant à convertir, supérieur à 0
amount_typestringouiÀ quel côté amount fait référence

amount_type=from dépense exactement amount de from_currency. amount_type=to reçoit exactement amount de to_currency.

🟢 200 OK · application/json

JSON
{
  "state": 0,
  "result": {
    "success": true,
    "from_currency": "BTC",
    "to_currency": "USDT",
    "amount_type": "from",
    "from_amount": "0.01000000",
    "to_amount": "947.86690000",
    "effective_rate": "94786.69000000",
    "from_amount_usd": "947.87",
    "to_amount_usd": "947.87"
  }
}

Champs de la réponse

ChampTypeDescription
successbooleanIndique si la cotation a été calculée avec succès
from_currencystringDevise source
to_currencystringDevise cible
amount_typestringReprend le amount_type de la requête
from_amountstringMontant qui serait débité en from_currency
to_amountstringMontant qui serait crédité en to_currency
effective_ratestringTaux appliqué à cette cotation — 1 unité de from_currency en to_currency (inclut déjà la tarification de la plateforme)
from_amount_usdstring | nullÉquivalent en USD de from_amount
to_amount_usdstring | nullÉquivalent en USD de to_amount
  • La cotation est purement indicative — le prix du marché peut évoluer entre la cotation et l'appel d'exécution.
  • Cet appel ne débite ni ne réserve aucun solde.
Credentials
RequestPOST/v1/convert/price
curl -X POST https://api.2328.io/api/v1/convert/price \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyShop/1.0 (+https://myshop.example)" \
  -H "project: YOUR_PROJECT_UUID" \
  -H "sign: YOUR_HMAC_SIGNATURE"
Response
Click Try it to see the response here.

Exécuter une conversion

Exécute une conversion au prix de marché actuel et met à jour le solde de votre commerce. Il n'y a pas d'étape distincte pour "valider une cotation" — appelez directement avec le montant que vous souhaitez convertir.

POST/v1/convert

Idempotence. Répéter exactement la même requête (mêmes from_currency, to_currency, amount, amount_type) dans la minute suivant le premier appel renvoie la conversion existante au lieu d'en créer une seconde. Passé ce délai, une requête identique est traitée comme une nouvelle conversion — ne réessayez pas aveuglément après un timeout sans avoir d'abord vérifié le résultat précédent.

Cet endpoint est limité à 10 requêtes par minute par appelant — plus strict que la limite générale de l'API — car chaque appel déplace un solde réel.

Paramètres de la requête

ChampTypeRequisDescriptionValeur
from_currencystringouiDevise source
to_currencystringouiDevise cible. Doit différer de from_currency
amountdecimalouiMontant à convertir, supérieur à 0
amount_typestringouiÀ quel côté amount fait référence

🟢 200 OK · application/json

JSON
{
  "state": 0,
  "result": {
    "id": 12345,
    "type": "manual",
    "status": "completed",
    "from_currency": "BTC",
    "to_currency": "USDT",
    "from_amount": "0.01000000",
    "requested_from_amount": "0.01000000",
    "refund_amount": null,
    "to_amount": "947.86690000",
    "exchange_rate": "94786.69000000",
    "fee_amount": "0.00000000",
    "from_amount_usd": "947.87",
    "to_amount_usd": "947.87",
    "processed_at": "2026-01-20T15:30:24Z",
    "created_at": "2026-01-20T15:30:22Z"
  }
}

Champs de la réponse

ChampTypeDescription
idintID de l'ordre de conversion attribué par le système
typestringToujours manual pour cette API
statusstringStatut actuel (voir « Statuts de conversion » ci-dessous)
from_currencystringDevise source
to_currencystringDevise cible
from_amountstringMontant débité en from_currency
requested_from_amountstring | nullVotre montant source initialement demandé lorsque amount_type = from. null lorsque amount_type = to
refund_amountstring | nullPartie du montant prédébité qui vous a été remboursée après une exécution partielle. null si l'ordre a été entièrement exécuté
to_amountstringMontant crédité en to_currency
exchange_ratestringTaux réellement appliqué à cette conversion — 1 unité de from_currency en to_currency (inclut déjà la tarification de la plateforme)
fee_amountstringFrais de plateforme prélevés sur cette conversion, exprimés en from_currency ou to_currency selon le sens de l'opération. Déjà reflétés dans exchange_rate — affichés à titre de transparence
from_amount_usdstring | nullÉquivalent en USD de from_amount
to_amount_usdstring | nullÉquivalent en USD de to_amount
processed_atstring (ISO 8601) | nullMoment où la conversion a terminé de s'exécuter. null tant qu'elle est en cours
created_atstring (ISO 8601)Moment où l'ordre de conversion a été créé

Statuts de conversion

StatutDescription
pendingCréé, pas encore envoyé au marché
processingSolde verrouillé et ordre placé sur le marché
completedEntièrement exécuté — to_amount a été crédité sur votre solde
failedImpossible à exécuter — tout montant prédébité a été remboursé automatiquement
partially_completedUniquement pour les paires de devises sans marché direct (routées via une devise intermédiaire) : la première étape a réussi mais la seconde a échoué. Vous êtes crédité de la devise intermédiaire au lieu de to_currency — reconvertissez depuis celle-ci pour atteindre votre objectif initial
RequestPOST/v1/convert
curl -X POST https://api.2328.io/api/v1/convert \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyShop/1.0 (+https://myshop.example)" \
  -H "project: YOUR_PROJECT_UUID" \
  -H "sign: YOUR_HMAC_SIGNATURE"
Response
Click Try it to see the response here.

Erreurs

En cas d'échec, la réponse a state: 1 et un error_code — commun à /v1/convert/price et /v1/convert :

🔴 422 / 400 · application/json

JSON
{
  "state": 1,
  "error_code": "amount_too_small",
  "errors": {
    "amount": "Amount is too small for this conversion. Please increase the amount and try again."
  }
}
error_codeStatut HTTPDescription
validation_failed422Paramètres invalides ou manquants, ou rejet lié à une règle métier (p. ex. solde insuffisant) — voir le champ errors pour les détails
amount_too_small422amount est inférieur à la taille minimale négociable pour cette paire de devises
convert_unavailable400La conversion n'a pas pu être exécutée pour le moment (données de marché indisponibles ou aucune route entre les deux devises) — réessayez sous peu
internal_error400Erreur serveur interne inattendue lors du traitement de la requête

Conversion automatique des paiements entrants

La conversion automatique est un paramètre de projet pour les factures entrantes et les crédits de portefeuille statique. Il est configuré dans le tableau de bord du commerçant, et non pas en ajoutant des champs à /v1/payment. Chaque règle sélectionne une ou plusieurs devises sources et une devise cible.

Une fois la conversion terminée, les informations de paiement et les webhooks du commerçant peuvent inclure :

JSON
{
  "payment_amount": "0.14800000",
  "merchant_amount": "0.146520000000000000",
  "payer_currency": "XMR",
  "convert": {
    "to_currency": "USDT",
    "commission": "0.09000000",
    "rate": "323.21000000",
    "amount": "47.262015740000000000"
  }
}

Les domaines des montants sont intentionnellement séparés :

  • payment_amount — ce qui a été détecté sur la blockchain dans la devise de paiement source ;
  • merchant_amount — le montant net source attribuable au commerçant avant conversion ;
  • convert.amount — le montant crédité dans convert.to_currency ;
  • convert.rate et convert.commission — le résultat de conversion exécuté, pas un prix que vous devriez recalculer localement.

L'absence de convert est significative : la conversion peut ne pas avoir été terminée, peut ne pas être configurée pour cette source, ou peut être revenue au crédit en devise source. Ne jamais inventer un montant cible à partir de /exchange-rates ou d'un prix de marché public.

Échec de la conversion automatique et retour en

La conversion est en aval de la réception du paiement blockchain. La disponibilité sur le marché, les tailles minimales de commande, les limites de précision, les délais d'échange et la liquidité exécutable insuffisante peuvent retarder ou empêcher la conversion.

  • Les dépôts inférieurs au minimum global/projet contournent le pipeline de conversion et créditent la devise source.
  • Les échecs transitoires peuvent être réessayés de manière asynchrone.
  • Les dépôts importants ou non négociables peuvent revenir à un crédit en devise source après épuisement de la politique de réessai.
  • Un paiement peut donc être valide même lorsque la conversion en devise cible souhaitée n'a pas eu lieu.

Votre intégration doit d'abord enregistrer le paiement vérifié, puis rapprocher la devise réellement créditée à partir des informations de paiement, du bloc optionnel convert et des soldes marchands. Ne bloquez pas la confirmation du webhook de paiement en attendant vos propres systèmes d'analyse ou de notification.

Tests d'acceptation de conversion automatique

Testez au moins : conversion directe réussie, conversion via un pont/multi-saut, poussière sous le minimum, nouvelle tentative transitoire, retour à la monnaie source, sous-paiement, trop-payé, webhook en double, convert manquant, et réconciliation après un timeout ambigu.

Cas limites de conversion manuelle

  • /v1/convert/price est un aperçu indicatif ; le mouvement du marché peut changer le résultat de l'exécution.
  • amount_type: from corrige la demande côté source, tandis que amount_type: to demande un montant côté cible. Ne changez pas le sens lors de la présentation de l'interface de confirmation.
  • Une paire sans marché direct peut être acheminée via une devise intermédiaire. Si une seule étape se termine, partially_completed rapporte le crédit intermédiaire.
  • Si un appel d'exécution expire, réconciliez avant de réessayer. Un ordre au marché peut s'exécuter même lorsque sa réponse HTTP est perdue.
  • Traitez failed comme un état à réconcilier, et non comme une permission d'appliquer une écriture locale de solde compensatoire ; la plateforme possède la comptabilité des débits/remboursements.