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.
/v1/convert/priceParamètres de la requête
| Champ | Type | Requis | Description | Valeur |
|---|---|---|---|---|
from_currency | string | oui | Devise source | |
to_currency | string | oui | Devise cible. Doit différer de from_currency | |
amount | decimal | oui | Montant à convertir, supérieur à 0 | |
amount_type | string | oui | À 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
{
"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
| Champ | Type | Description |
|---|---|---|
success | boolean | Indique si la cotation a été calculée avec succès |
from_currency | string | Devise source |
to_currency | string | Devise cible |
amount_type | string | Reprend le amount_type de la requête |
from_amount | string | Montant qui serait débité en from_currency |
to_amount | string | Montant qui serait crédité en to_currency |
effective_rate | string | Taux appliqué à cette cotation — 1 unité de from_currency en to_currency (inclut déjà la tarification de la plateforme) |
from_amount_usd | string | null | Équivalent en USD de from_amount |
to_amount_usd | string | 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.
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"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.
/v1/convertIdempotence. 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
| Champ | Type | Requis | Description | Valeur |
|---|---|---|---|---|
from_currency | string | oui | Devise source | |
to_currency | string | oui | Devise cible. Doit différer de from_currency | |
amount | decimal | oui | Montant à convertir, supérieur à 0 | |
amount_type | string | oui | À quel côté amount fait référence |
🟢 200 OK · application/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
| Champ | Type | Description |
|---|---|---|
id | int | ID de l'ordre de conversion attribué par le système |
type | string | Toujours manual pour cette API |
status | string | Statut actuel (voir « Statuts de conversion » ci-dessous) |
from_currency | string | Devise source |
to_currency | string | Devise cible |
from_amount | string | Montant débité en from_currency |
requested_from_amount | string | null | Votre montant source initialement demandé lorsque amount_type = from. null lorsque amount_type = to |
refund_amount | string | null | Partie 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_amount | string | Montant crédité en to_currency |
exchange_rate | string | Taux réellement appliqué à cette conversion — 1 unité de from_currency en to_currency (inclut déjà la tarification de la plateforme) |
fee_amount | string | Frais 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_usd | string | null | Équivalent en USD de from_amount |
to_amount_usd | string | null | Équivalent en USD de to_amount |
processed_at | string (ISO 8601) | null | Moment où la conversion a terminé de s'exécuter. null tant qu'elle est en cours |
created_at | string (ISO 8601) | Moment où l'ordre de conversion a été créé |
Statuts de conversion
| Statut | Description |
|---|---|
pending | Créé, pas encore envoyé au marché |
processing | Solde verrouillé et ordre placé sur le marché |
completed | Entièrement exécuté — to_amount a été crédité sur votre solde |
failed | Impossible à exécuter — tout montant prédébité a été remboursé automatiquement |
partially_completed | Uniquement 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 |
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"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
{
"state": 1,
"error_code": "amount_too_small",
"errors": {
"amount": "Amount is too small for this conversion. Please increase the amount and try again."
}
}error_code | Statut HTTP | Description |
|---|---|---|
validation_failed | 422 | Paramè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_small | 422 | amount est inférieur à la taille minimale négociable pour cette paire de devises |
convert_unavailable | 400 | La 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_error | 400 | Erreur 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 :
{
"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é dansconvert.to_currency;convert.rateetconvert.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/priceest un aperçu indicatif ; le mouvement du marché peut changer le résultat de l'exécution.amount_type: fromcorrige la demande côté source, tandis queamount_type: todemande 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_completedrapporte 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
failedcomme 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.