API Reference
Documentation API
Encaissez Bitcoin, Ethereum, USDT, USDC, Solana, BNB, XRP et Monero. Checkout hébergé ou API directe. Le client paie en crypto ; le net est versé sur le wallet que vous contrôlez. Pas de solde de dépôt chez SYLI Payments.
Démarrage rapide — votre premier paiement en 5 minutes#
Un seul appel. Remplacez la clé factice, affichez l’adresse au client, puis livrez sur le webhook confirmed.
REQUEST
curl -X POST https://api.sylipayments.com/v1/payment \
-H "x-api-key: syli_live_xxxxxxxx" \
-H "content-type: application/json" \
-d '{
"price_amount": 20,
"price_currency": "usdt",
"pay_currency": "usdttrc20",
"order_id": "CMD-4821",
"order_description": "Abonnement mensuel"
}'Response
200 OK{
"payment_id": "a2483de0-2a84-4298-a9c8-a8e353311697",
"payment_status": "waiting",
"pay_address": "TXYZxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"payin_extra_id": null,
"price_amount": 20,
"price_currency": "usdt",
"pay_amount": 20,
"actually_paid": 0,
"actually_paid_usd": 0,
"pay_currency": "usdttrc20",
"order_id": "CMD-4821",
"order_description": "Abonnement mensuel",
"invoice_id": null,
"invoice_url": "https://sylipayments.com/pay/a2483de0-2a84-4298-a9c8-a8e353311697",
"outcome_amount": 0,
"outcome_currency": "usdttrc20",
"payout_address": "TYourMerchantWallet…",
"payout_amount": null,
"payout_status": null,
"payout_hash": null,
"payin_hash": null,
"livemode": true,
"created_at": "2026-09-07T12:00:00.000Z",
"updated_at": "2026-09-07T12:00:00.000Z",
"expiration_estimate_date": null,
"rate_locked_at": "2026-09-07T12:00:00.000Z"
}Et maintenant, écoutez le webhook sur confirmed
- Affichez pay_address (et le QR) au client — c’est l’adresse d’encaissement de cette commande.
- Recevez le POST JSON signé (en-tête x-syli-sig) à chaque changement de statut.
- Livrez uniquement si payment_status vaut confirmed. Le virement vers votre wallet peut suivre plus tard.
Introduction#
Le client paie en crypto (payin). Une fois le montant attendu confirmé on-chain, le net est versé sur le wallet que vous avez validé pour ce réseau (payout). Deux intégrations. Checkout hébergé : POST /invoice, redirection vers invoice_url — SYLI Payments affiche le QR, le réseau et l’échéance. API directe : POST /payment, vous affichez pay_address (et payin_extra_id s’il est présent). L’API est active dès l’inscription. Sans KYC la commission est de 2 % ; après KYC, 1,7 % puis moins selon le volume. Il faut au moins un wallet validé dans Réception. Le KYB est optionnel : il passe le compte en Pro.
Utilisez le checkout si une boutique, un plugin ou une app doit seulement ouvrir une page de paiement. N’utilisez l’API directe que si vous construisez l’UI vous-même : appelez alors GET /currencies pour le sélecteur, affichez le destination tag XRP / payment ID Monero, et suivez le statut par webhook ou GET /payment/:id. Un mauvais réseau ou un extra ID manquant peut faire perdre le payin.
Livrez dès que payment_status vaut confirmed : le client a payé. Ne bloquez pas la commande sur payout_status — le virement wallet peut suivre avec un délai. Voir Cycle de vie pour le détail du mapping des statuts.
Pour envoyer des requêtes depuis le navigateur, ouvrez le laboratoire API.
Base URL
https://api.sylipayments.com/v1
Tous les exemples ci-dessous utilisent cette URL.
Pour Cursor, Claude, ChatGPT
Prompt d’intégration API
Fichier Markdown à coller dans un agent de code. Il décrit l’API SYLI Payments, le checkout, les webhooks HMAC et les critères de recette pour une intégration complète.
REQUEST
curl https://api.sylipayments.com/v1/status
Response
200 OK{
"message": "OK"
}Header x-api-key
Toutes les routes /api/v1/* sauf /status, /estimate et /min-amount exigent la clé secrète (Configuration → Clés API). En-tête recommandé : x-api-key. Alternatives toujours acceptées : x-syli-api-key, Authorization: Bearer.
GET /currencies est authentifié volontairement : la liste n’est pas le catalogue public SYLI Payments, c’est votre sélecteur (wallets validés dans Réception). Afficher une autre crypto ferait échouer POST /payment.
Format : syli_live_… ou syli_test_…. Une régénération invalide seulement la clé du même mode. Compte désactivé : 403 (account_disabled). Par défaut, clé absente ou invalide → HTTP 503 (inchangé). Opt-in : envoyez x-syli-api-version: 2026-10 pour recevoir HTTP 401 et le code invalid_api_key. La dépréciation du 503 d’auth prend effet le 2027-04-02.
REQUEST
x-api-key: syli_live_xxxxxxxx # alternatives : # x-syli-api-key: syli_live_xxxxxxxx # Authorization: Bearer syli_live_xxxxxxxx # opt-in 401 : x-syli-api-version: 2026-10
Sandbox (clés test)#
Générez une clé syli_test_ dans Configuration → Clés API. Même /api/v1, aucun fonds réel : adresses TEST-…, pas d’appel processeur. Les réponses et webhooks portent livemode: false. GET isole test et live (404 en travers). Simulez un payin : POST /payment/{id}/simulate { "outcome": "paid" | "partially_paid" | "expired" }. Le laboratoire /docs/lab peut utiliser une clé test ; avec une clé live, les paiements restent réels.
REQUEST
curl -X POST https://api.sylipayments.com/v1/payment/{payment_id}/simulate \
-H "x-api-key: syli_test_xxxxxxxx" \
-H "content-type: application/json" \
-d '{"outcome":"paid"}'Response
200 OK{
"payment_id": "…",
"payment_status": "confirmed",
"livemode": false,
"pay_address": "TEST-usdttrc20-…"
}Node.js ≥ 18
SDK JavaScript#
Client officiel pour créer un checkout, un paiement API, et vérifier les webhooks x-syli-sig. Serveur uniquement : la clé syli_live_… ne doit jamais partir dans le navigateur.
Source : github.com/Nimba-Algo-Trading/syli-sdk — npm : syli-sdk
- Installez le paquet, puis créez un client avec votre clé (Configuration → API paiement).
- Checkout hébergé :
createInvoicepuis redirigez versinvoice_url. - API directe :
createPaymentet affichezpay_address(etpayin_extra_idsi présent). - Sur votre URL HTTPS, appelez
constructEventet répondez 2xx.
Méthodes
| Méthode | Signification |
|---|---|
| createInvoice | Facture checkout — renvoie invoice_url |
| getInvoice | Même objet que getPayment (statut, actually_paid, actually_paid_usd) |
| createPayment | Adresse de paiement unique + QR |
| getPayment | Statut resynchronisé (UUID paiement ou facture) |
| constructEvent | Parse et vérifie un webhook HMAC |
| getCurrencies | Cryptos du compte (wallet validé, clé requise) |
SDK
npm install syli-sdk # source : https://github.com/Nimba-Algo-Trading/syli-sdk
Response
INVOICE{
"id": "2d6f88d7-5b40-4d9e-b0a4-0793953d2707",
"order_id": "CMD-9001",
"price_amount": 49.9,
"price_currency": "usdt",
"invoice_url": "https://sylipayments.com/pay/2d6f88d7-5b40-4d9e-b0a4-0793953d2707"
}Dart ≥ 3 · Flutter
SDK Flutter / Dart#
Paquet pur Dart pour créer un checkout, un paiement API, et vérifier les webhooks x-syli-sig. La clé syli_live_… reste sur le serveur : l’app Flutter ouvre invoice_url.
Source : github.com/Nimba-Algo-Trading/SYLI-AGREGATEUR-CRYPTO — sdk/dart. Pas encore publié sur pub.dev : installez depuis le ZIP ou un path git. ZIP syli-dart-sdk.zip.
- Ajoutez
syli_sdken path danspubspec.yaml. - Checkout hébergé :
createInvoicepuis ouvrezinvoiceUrl. - API directe :
createPaymentet affichezpayAddress. - Sur votre URL HTTPS, appelez
constructEventet répondez 2xx.
Méthodes
| Méthode | Signification |
|---|---|
| createInvoice | Facture checkout — renvoie invoiceUrl |
| getInvoice | Même objet que getPayment (statut, actually_paid, actually_paid_usd) |
| createPayment | Adresse de paiement unique + QR |
| getPayment | Statut resynchronisé (UUID paiement ou facture) |
| constructEvent | Parse et vérifie un webhook HMAC |
| getCurrencies | Cryptos du compte (wallet validé, clé requise) |
SDK
dependencies:
syli_sdk:
git:
url: https://github.com/Nimba-Algo-Trading/SYLI-AGREGATEUR-CRYPTO.git
path: sdk/dart
# ZIP : /downloads/syli-dart-sdk.zip
# path local : path: sdk/dartResponse
INVOICE{
"id": "2d6f88d7-5b40-4d9e-b0a4-0793953d2707",
"order_id": "CMD-9001",
"price_amount": 49.9,
"price_currency": "usdt",
"invoice_url": "https://sylipayments.com/pay/2d6f88d7-5b40-4d9e-b0a4-0793953d2707"
}Cursor · Claude · ChatGPT
Serveur MCP#
Un serveur Model Context Protocol expose l’API SYLI Payments comme outils pour l’IA. Cursor et Claude Desktop lancent le processus en local (stdio). La clé reste dans la config MCP, pas dans le chat.
Outils : syli_status, syli_list_currencies, syli_estimate, syli_min_amount, syli_create_invoice, syli_get_invoice, syli_create_payment, syli_get_payment, syli_verify_webhook. syli_get_invoice et syli_get_payment renvoient le même objet statut. Prompt : syli_integrate_checkout.
Dans env : la clé API, l’URL de l’API, le secret HMAC (SYLI_IPN_SECRET) et l’URL HTTPS de votre webhook (SYLI_IPN_CALLBACK_URL). Invoice et paiement l’envoient comme ipn_callback_url si l’outil ne la passe pas.
Sources : github.com/Nimba-Algo-Trading/SYLI-AGREGATEUR-CRYPTO — sdk/mcp. npm : npx -y syli-mcp@1
MCP
{
"mcpServers": {
"syli": {
"command": "npx",
"args": ["-y", "syli-mcp@1"],
"env": {
"SYLI_API_KEY": "syli_live_xxxxxxxx",
"SYLI_API_URL": "https://api.sylipayments.com/v1",
"SYLI_IPN_SECRET": "xxxxxxxx",
"SYLI_IPN_CALLBACK_URL": "https://boutique.example/webhooks/syli"
}
}
}
}Plugins téléchargeables#
ZIP prêts à installer depuis la page Plugins. WooCommerce et PrestaShop s’installent comme un module. Wix se colle dans Velo. Shopify se déploie comme une app Node.
/api/v1/currencies
Avec la clé, la liste n’est pas le catalogue mondial : uniquement les cryptos du compte qui ont une adresse validée dans Dashboard → Réception. C’est le contrat du sélecteur pour une UI maison. Une crypto hors liste est refusée au POST /payment.
currencies = codes. accepted et available sont la même liste enrichie (label, ticker, réseau) — available existe pour la rétrocompatibilité.
Le prix facturé est en USDT (price_currency: "usdt"). usd est accepté et stocké / renvoyé comme usdt. Alias : usdtbep20 → usdtbsc, usdc → usdcerc20, bnb → bnbbsc.
pay_currency
| Attribut | Type | Description |
|---|---|---|
| btc | string | Bitcoin — taux gelé jusqu’à expiration_estimate_date |
| eth | string | Ethereum — taux gelé jusqu’à expiration_estimate_date |
| usdterc20 | string | USDT Ethereum — 1:1, pas de gel de taux |
| usdttrc20 | string | USDT Tron — 1:1, pas de gel de taux |
| usdtbsc | string | USDT BNB Smart Chain — 1:1, pas de gel de taux |
| usdcerc20 | string | USDC Ethereum — 1:1, pas de gel de taux |
| sol | string | Solana — taux gelé jusqu’à expiration_estimate_date |
| bnbbsc | string | BNB Smart Chain — taux gelé jusqu’à expiration_estimate_date |
| xrp | string | XRP — taux gelé ; payin_extra_id = destination tag |
| xmr | string | Monero — taux gelé ; payin_extra_id = payment ID si présent |
REQUEST
curl https://api.sylipayments.com/v1/currencies \ -H "x-api-key: syli_live_xxxxxxxx"
Response
200 OK{
"currencies": ["usdttrc20"],
"accepted": [
{
"code": "usdttrc20",
"label": "Tether USDT (TRC-20)",
"ticker": "USDT",
"network": "Tron"
}
],
"available": [
{
"code": "usdttrc20",
"label": "Tether USDT (TRC-20)",
"ticker": "USDT",
"network": "Tron"
}
]
}/api/v1/payment
Génère une adresse unique pour cette commande. Affichez pay_address, le QR, le montant pay_amount (dans la crypto choisie).
pay_currency doit figurer dans GET /currencies. Stables (USDT / USDC) : montant 1:1, pas de gel de taux. BTC, ETH, SOL, BNB, XRP, XMR : taux gelé jusqu’à expiration_estimate_date.
ipn_callback_url surcharge l’URL webhook du dashboard si elle est fournie. Sinon SYLI Payments utilise celle enregistrée sur le compte. outcome_amount vaut le reçu on-chain (actually_paid), pas le net payout. actually_paid_usd est le montant réellement reçu en dollars (1:1 pour USDT/USDC, sinon prorata price_amount × actually_paid / pay_amount). 0 tant qu’aucun payin n’est vu.
Body
| Attribut | Type | Description |
|---|---|---|
| price_amount* | number | Montant facturé en USDT (> 0), ≥ minimum SYLI Payments |
| price_currency* | string | usdt (usd accepté, renvoyé usdt) |
| pay_currency* | string | Code de GET /currencies (wallet validé) |
| order_id | string | Votre référence. Réutilisée = même paiement tant qu’il est actif |
| order_description | string | Libellé visible |
| ipn_callback_url | string | HTTPS — surcharge l’URL webhook du compte |
REQUEST
curl -X POST https://api.sylipayments.com/v1/payment \
-H "x-api-key: syli_live_xxxxxxxx" \
-H "content-type: application/json" \
-d '{
"price_amount": 20,
"price_currency": "usdt",
"pay_currency": "usdttrc20",
"order_id": "CMD-4821",
"order_description": "Abonnement mensuel"
}'Response
200 OK{
"payment_id": "a2483de0-2a84-4298-a9c8-a8e353311697",
"payment_status": "waiting",
"pay_address": "TXYZxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"payin_extra_id": null,
"price_amount": 20,
"price_currency": "usdt",
"pay_amount": 20,
"actually_paid": 0,
"actually_paid_usd": 0,
"pay_currency": "usdttrc20",
"order_id": "CMD-4821",
"order_description": "Abonnement mensuel",
"invoice_id": null,
"invoice_url": "https://sylipayments.com/pay/a2483de0-2a84-4298-a9c8-a8e353311697",
"outcome_amount": 0,
"outcome_currency": "usdttrc20",
"payout_address": "TYourMerchantWallet…",
"payout_amount": null,
"payout_status": null,
"payout_hash": null,
"payin_hash": null,
"livemode": true,
"created_at": "2026-09-07T12:00:00.000Z",
"updated_at": "2026-09-07T12:00:00.000Z",
"expiration_estimate_date": null,
"rate_locked_at": "2026-09-07T12:00:00.000Z"
}/api/v1/payment/:id
Resynchronise le payin avec la chaîne avant de répondre. Si le processeur est injoignable, le dernier snapshot local est renvoyé plutôt qu’une erreur. Même objet que POST /payment et que GET /invoice/:id.
Champs à suivre : payment_status (payin — livrer sur confirmed), actually_paid (crypto), actually_paid_usd (dollars), payin_hash, puis payout_status / payout_hash pour le virement vers votre wallet. L’id peut être celui du paiement ou de la facture checkout : même objet.
REQUEST
curl https://api.sylipayments.com/v1/payment/a2483de0-2a84-4298-a9c8-a8e353311697 \ -H "x-api-key: syli_live_xxxxxxxx" # même objet avec l’id de facture : # curl https://api.sylipayments.com/v1/payment/2d6f88d7-5b40-4d9e-b0a4-0793953d2707
Response
200{
"payment_id": "a2483de0-2a84-4298-a9c8-a8e353311697",
"payment_status": "confirmed",
"pay_address": "TXYZxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"payin_extra_id": null,
"price_amount": 20,
"price_currency": "usdt",
"pay_amount": 20,
"actually_paid": 20,
"actually_paid_usd": 20,
"pay_currency": "usdttrc20",
"order_id": "CMD-4821",
"order_description": "Abonnement mensuel",
"invoice_id": null,
"invoice_url": "https://sylipayments.com/pay/a2483de0-2a84-4298-a9c8-a8e353311697",
"outcome_amount": 20,
"outcome_currency": "usdttrc20",
"payout_address": "TYourMerchantWallet…",
"payout_amount": 19.7,
"payout_status": "finished",
"payout_hash": "0xabc…",
"payin_hash": "abc123…",
"created_at": "2026-09-07T12:00:00.000Z",
"updated_at": "2026-09-07T12:04:00.000Z",
"expiration_estimate_date": null,
"rate_locked_at": "2026-09-07T12:00:00.000Z"
}/api/v1/invoice
Crée une session checkout, pas encore un paiement. Le client ouvre invoice_url (https://sylipayments.com/pay/…). L’adresse on-chain n’existe qu’après choix de la crypto sur la page SYLI Payments (ou si vous figez pay_currency).
Si pay_currency est omis, le client choisit parmi vos wallets validés. Au moins une crypto configurée est requise. success_url / cancel_url doivent être des URL HTTPS valides. GET /invoice/:id renvoie le même objet que GET /payment/:id (statut, actually_paid, actually_paid_usd). Tant que le client n’a pas choisi la crypto, payment_id est null et le statut reste waiting. POST /invoice reste la création du checkout (plugins, lien de paiement).
Recréer un paiement sur un checkout déjà clos (expired, failed, refunded) : HTTP 410.
Body
| Attribut | Type | Description |
|---|---|---|
| price_amount* | number | Montant en USDT (≥ minimum SYLI Payments) |
| price_currency* | string | usdt |
| pay_currency | string | Optionnel — sinon le client choisit sur /pay |
| order_id | string | Référence boutique |
| order_description | string | Libellé visible |
| success_url | string | Redirection HTTPS après paiement |
| cancel_url | string | Redirection HTTPS si abandon |
| ipn_callback_url | string | Surcharge l’URL webhook du compte |
REQUEST
curl -X POST https://api.sylipayments.com/v1/invoice \
-H "x-api-key: syli_live_xxxxxxxx" \
-H "content-type: application/json" \
-d '{
"price_amount": 49.9,
"price_currency": "usdt",
"order_id": "CMD-9001",
"success_url": "https://boutique.example/ok",
"cancel_url": "https://boutique.example/annuler"
}'Response
200 OK{
"id": "2d6f88d7-5b40-4d9e-b0a4-0793953d2707",
"order_id": "CMD-9001",
"order_description": "Commande boutique",
"price_amount": 49.9,
"price_currency": "usdt",
"pay_currency": null,
"ipn_callback_url": "https://boutique.example/webhooks/syli",
"success_url": "https://boutique.example/ok",
"cancel_url": "https://boutique.example/annuler",
"created_at": "2026-09-07T12:00:00.000Z",
"invoice_url": "https://sylipayments.com/pay/2d6f88d7-5b40-4d9e-b0a4-0793953d2707"
}/api/v1/invoice/:id
Statut du payin, identique à GET /payment/:id (payment_status, actually_paid, actually_paid_usd, invoice_url). Ce n’est pas le JSON de POST /invoice (id + invoice_url). Vous pouvez aussi passer l’id facture à GET /payment/:id.
Tant que le client n’a pas choisi la crypto, payment_id est null et le statut reste waiting. Après le choix, l’objet est celui du paiement (adresse, montants, hashes).
REQUEST
curl https://api.sylipayments.com/v1/invoice/2d6f88d7-5b40-4d9e-b0a4-0793953d2707 \ -H "x-api-key: syli_live_xxxxxxxx"
Response
WAITING{
"payment_id": null,
"payment_status": "waiting",
"pay_address": null,
"payin_extra_id": null,
"price_amount": 49.9,
"price_currency": "usdt",
"pay_amount": 0,
"actually_paid": 0,
"actually_paid_usd": 0,
"pay_currency": null,
"order_id": "CMD-9001",
"order_description": "Commande boutique",
"invoice_id": "2d6f88d7-5b40-4d9e-b0a4-0793953d2707",
"invoice_url": "https://sylipayments.com/pay/2d6f88d7-5b40-4d9e-b0a4-0793953d2707",
"outcome_amount": 0,
"outcome_currency": null,
"payout_address": null,
"payout_amount": null,
"payout_status": null,
"payout_hash": null,
"payin_hash": null,
"livemode": true,
"created_at": "2026-09-07T12:00:00.000Z",
"updated_at": "2026-09-07T12:00:00.000Z",
"expiration_estimate_date": null,
"rate_locked_at": null
}Votre URL HTTPS
POST JSON à chaque changement de statut utile (payin ou payout). En-têtes x-syli-sig-v2, x-syli-timestamp, x-syli-event-id (stable entre retries de la même livraison) et x-syli-sig (v1, conservé). Secret IPN : Dashboard → Configuration → Clés API. Répondez 2xx sinon relance automatique (jusqu’à 8 tentatives : 1 min, 5 min, 15 min, 1 h, 3 h, 6 h, 12 h, 24 h). Le timestamp v2 est recalculé à chaque tentative pour rester dans la fenêtre de 5 minutes.
Livrez si payment_status vaut confirmed. Ne livrez pas sur payout_status : le client a déjà payé, le virement wallet peut arriver après. Voir Cycle de vie pour le détail du mapping des statuts.
Payload plat : payment_id, invoice_id, payment_status, pay_address, price_amount, price_currency, pay_amount, actually_paid, actually_paid_usd, pay_currency, order_id, order_description, outcome_amount, received_amount (alias additif de outcome_amount : reçu on-chain, pas le net), outcome_currency, payout_amount, payout_hash, payin_hash, payout_status. Pas de payin_extra_id dans le webhook.
VERIFY
import crypto from "node:crypto";
import express from "express";
const app = express();
app.use(express.raw({ type: "application/json" }));
app.post("/webhooks/syli", (req, res) => {
const raw = req.body.toString("utf8");
const ts = String(req.headers["x-syli-timestamp"] || "");
const sig = String(req.headers["x-syli-sig-v2"] || "");
const expected = crypto.createHmac("sha256", process.env.SYLI_IPN_SECRET)
.update(`${ts}.${raw}`).digest("hex");
const a = Buffer.from(expected, "utf8");
const b = Buffer.from(sig.toLowerCase(), "utf8");
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return res.sendStatus(401);
}
const event = JSON.parse(raw);
// dédoublonner event.payment_id ; livrer à la 1re transition confirmed
res.sendStatus(200);
});Response
EVENT{
"payment_id": "a2483de0-2a84-4298-a9c8-a8e353311697",
"invoice_id": null,
"payment_status": "confirmed",
"pay_address": "TXYZxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"price_amount": 20,
"price_currency": "usdt",
"pay_amount": 20,
"actually_paid": 20,
"actually_paid_usd": 20,
"pay_currency": "usdttrc20",
"order_id": "CMD-4821",
"order_description": "Abonnement mensuel",
"outcome_amount": 20,
"received_amount": 20,
"outcome_currency": "usdttrc20",
"payout_amount": 19.7,
"payout_hash": "0xabc…",
"payin_hash": "abc123…",
"payout_status": "finished"
}/api/v1/estimate
GET /api/v1/status — santé du service, sans auth. Pinge aussi le processeur de paiement : s’il est down, attendez-vous à un 503.
GET /api/v1/estimate donne un montant crypto indicatif (pas le taux gelé du paiement). Le gel n’existe que sur un POST /payment en crypto volatile, jusqu’à expiration_estimate_date.
GET /min-amount : minimum marchand = max(1 USDT, 4 × frais réseau estimés) pour toutes les cryptos, y compris USDT TRC-20. rule est vide (plancher marchand) ou processor. processor_min_amount est informatif : le processeur peut créer une charge plus haute en interne, le checkout affiche toujours le montant marchand. Un payin à ≥ 99,5 % du pay_amount est traité comme couvert (confirmed), pas comme un partiel.
REQUEST
curl "https://api.sylipayments.com/v1/estimate?amount=20¤cy_from=usdt¤cy_to=btc"
Response
200 OK{
"currency_from": "usdt",
"amount_from": 20,
"currency_to": "btc",
"estimated_amount": 0.00018
}Erreurs#
Corps : { "status": false, "message": "…", "error": "…", "code": "…" } — message et error portent le même texte. code est un identifiant machine stable (snake_case), additif.
HTTP
| Code HTTP | Signification |
|---|---|
| 400 | Corps invalide, crypto absente du compte, wallet manquant, montant sous le minimum |
| 401 | Clé absente / invalide — uniquement si x-syli-api-version: 2026-10 |
| 403 | Compte marchand désactivé |
| 404 | Paiement ou facture introuvable (ou d’un autre compte) |
| 410 | Checkout clos : expired / failed / refunded |
| 429 | Trop de requêtes — limite par marchand (défaut 20/s). Réessayez (Retry-After: 1) |
| 502 | Le processeur n’a pas renvoyé d’adresse de paiement |
| 503 | Processeur indisponible. Sans le header de version : aussi clé absente / invalide (déprécié, 2027-04-02) |
code
| code | Signification |
|---|---|
| invalid_body | JSON / champs requis invalides |
| amount_below_minimum | price_amount sous le minimum SYLI |
| currency_not_enabled | pay_currency hors du sélecteur du compte |
| wallet_missing | Aucun wallet de réception validé |
| payout_address_missing | Adresse de payout manquante (interne payout) |
| account_disabled | Compte marchand désactivé (403) |
| not_found | Paiement ou facture introuvable |
| checkout_closed | Checkout expired / failed / refunded (410) |
| rate_limited | Limite de débit dépassée (429) |
| processor_unavailable | Processeur down, ou (sans opt-in) clé invalide mappée en 503 |
| invalid_api_key | Clé absente / invalide — seulement avec x-syli-api-version: 2026-10 (401) |
| request_failed | Erreur 4xx non classée |
Les routes authentifiées /api/v1 (paiement, facture, devises, lecture de statut) sont limitées par marchand : 20 requêtes par seconde, réglable dans le back-office. Au-delà : HTTP 429, en-tête Retry-After: 1, corps retry_after. GET /status, /estimate et /min-amount (sans clé) ne sont pas concernés.
Response
429{
"status": false,
"message": "Trop de requêtes. Limite : 20 par seconde. Réessayez dans 1 s.",
"error": "Trop de requêtes. Limite : 20 par seconde. Réessayez dans 1 s.",
"code": "rate_limited",
"retry_after": 1
}Cycle de vie#
payment_status décrit le payin client. En base, sending / finished existent pour le versement interne ; l’API et les webhooks ne les exposent pas : ils deviennent confirmed. Livrez sur confirmed. Un reçu à ≥ 99,5 % du montant attendu est confirmé (tolérance poussière). Le versement vers votre wallet = payout_status et payout_hash.
payment_status (API / webhook)
| Statut | Signification |
|---|---|
| waiting | En attente du virement client |
| confirming | Vu on-chain, confirmations en cours |
| confirmed | Montant attendu reçu — livrer / activer. Inclut l’ancien sending/finished interne |
| partially_paid | Reçu < 99,5 % du pay_amount marchand |
| expired | Le processeur a marqué la session expirée (checkout clos : 410 si réutilisé) |
| failed / refunded | Échec ou remboursement — checkout clos (410 si réutilisé) |
payout_status (API / webhook)
| Statut | Signification |
|---|---|
| null | Pas encore de versement wallet |
| sending | Versement en cours, ou échec interne masqué (l’API ne publie pas failed) |
| finished | Net crédité sur votre wallet |
Cas limites (payin, expiration, payout)#
Comportements lus dans le code de production. Ce qui n’est pas implémenté n’est pas inventé ici.
partially_paid. Un reçu < 99,5 % du pay_amount marchand reste partially_paid. Un complément on-chain est pris en compte si le processeur le notifie : dès que le seuil 99,5 % est atteint, le statut devient confirmed et le payout peut démarrer. Si le montant reste insuffisant quand le processeur passe expired (ou que expires_at est dépassé), SYLI déclenche quand même un payout sur ce qui a atterri (actually_paid > 0). Il n’y a pas d’API marchand de remboursement ; un statut refunded n’apparaît que si le processeur le signale.
Sur-paiement. credited = actually_paid s’il est > 0. L’excédent entre donc dans le net payout (moins commission et frais réseau). Il n’y a pas de remboursement automatique de l’excédent.
Paiement après expired. SYLI n’a pas de filtre qui ignore un IPN processeur tardif. Si un payin est encore notifié après expired, le snapshot est mis à jour et un payout peut partir. Recréer un paiement sur le même checkout clos reste HTTP 410. Le comportement on-chain de l’adresse après expiration n’est pas défini dans le code SYLI (il dépend du processeur).
Expiration. expiration_estimate_date = expires_at copié du processeur. SYLI ne pose pas de TTL propre. Cryptos volatiles : taux gelé jusqu’à cette date. Stables (USDT/USDC) : pas de gel (rateLockBounds retourne null) ; expiration_estimate_date est souvent null. Dans ce cas la durée d’expiration n’est pas définie côté SYLI.
payout_status (contrat public). Seulement null, sending, finished. Les valeurs internes creating, waiting_verify, processing, failed, rejected, expired ne sont pas exposées : un échec de payout reste sending côté API. Le marchand n’a pas d’action API documentée ; les retries sont internes (desk / jobs). En cas de blocage durable, contactez le support — ne bloquez pas la livraison client, le payin est déjà confirmed.
Frais et net. Le client paie les frais réseau de son virement vers pay_address (hors code SYLI). Le marchand supporte la commission SYLI et les frais réseau du payout. Formule : payout_amount = round6( credited × (1 − fee_bps / 10000) − network_fee ) avec credited = actually_paid s’il est > 0, sinon pay_amount. fee_bps : 200 (2 %) sans KYC, 170 (1,7 %) après KYC, puis barème volume. network_fee vient de l’estimation processeur au moment du payout.
outcome_amount / received_amount. outcome_amount = actually_paid (reçu on-chain), pas le net. Alias additif received_amount : même valeur. Le net est payout_amount.
Changelog#
L’API publique actuelle est la v1. Base canonique : https://api.sylipayments.com/v1 — https://sylipayments.com/api/v1 reste un alias.
Les breaking changes seront introduits sous un nouveau préfixe de version (ex. /api/v2), avec un préavis d’au moins 6 mois. Les ajouts rétrocompatibles (nouveaux champs optionnels, nouveaux codes crypto) peuvent arriver en v1 sans changer de préfixe.
Versions
| Date | Signification |
|---|---|
| 2026-10 — additif | Webhooks v2 (x-syli-sig-v2, x-syli-timestamp, x-syli-event-id) ; champ code sur les erreurs ; alias received_amount ; champ additif livemode ; clés syli_test_ (processeur simulé, POST /payment/:id/simulate) ; 401 opt-in via x-syli-api-version: 2026-10 (le 503 d’auth par défaut est déprécié, retrait le 2027-04-02). |
| v1 — en service | Checkout hébergé (POST /invoice), API directe (POST /payment), webhooks HMAC, GET /currencies, estimate et min-amount. |
