Introduction

Démarrage

ZyndPay Référence API

API v1 · USDT TRC20 sur TRON

L'API ZyndPay est une passerelle de paiement RESTful pour accepter des USDT sur la blockchain TRON. Des URLs orientées ressources, des corps JSON et une enveloppe de réponse cohérente facilitent l'intégration dans n'importe quel environnement.

Tous les montants sont en USDT (TRC20). Le montant minimum d'encaissement est de 20 USDT. Un plancher de frais minimum de 2 USDT et des frais fixes de 2 USDT par retrait s'appliquent à toutes les transactions.

URL de Base

https://api.zyndpay.io/v1

Toutes les réponses sont encapsulées dans une enveloppe cohérente :

JSON — response envelope
{
  "success": true,
  "data": { ... },
  "message": "optional string",
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 100,
    "totalPages": 5
  }
}

Démarrage

Authentification

Incluez votre clé API dans l'en-tête X-Api-Key à chaque requête. Vous pouvez aussi la passer comme jeton Bearer dans l'en-tête Authorization.

cURL
curl https://api.zyndpay.io/v1/payin \
  -H "X-Api-Key: zyp_live_sk_..."

Les préfixes de clés API vous permettent d'identifier le type de clé d'un coup d'œil :

ParamètreTypeRequisDescription
zyp_live_sk_...secretrequisClé secrète live — accès API complet. Ne jamais exposer côté client.
zyp_live_pk_...publishableoptionnelClé publiable live — accès lecture limité, sûre pour les navigateurs.
zyp_test_sk_...secretoptionnelClé secrète sandbox — identique au live mais sans transactions réelles.
zyp_test_pk_...publishableoptionnelClé publiable sandbox.
zyp_rk_...restrictedoptionnelClé restreinte — limitée à des opérations spécifiques.
Attention:N'intégrez jamais zyp_live_sk_ ou zyp_test_sk_ dans du code côté client, des applications mobiles ou des dépôts publics.

Démarrage

Démarrage Rapide

Créez votre premier paiement en trois étapes — aucun SDK requis, juste une seule requête HTTP.

1

Obtenez votre clé API

Inscrivez-vous sur dashboard.zyndpay.io, complétez la vérification KYB et copiez votre clé secrète live ou sandbox.

2

Créez un encaissement

POST /v1/payin avec votre montant et un externalRef (votre ID de commande). Vous recevez une adresse de dépôt TRON.

3

Recevez le webhook

Quand votre client envoie des USDT à l'adresse, ZyndPay déclenche un webhook payin.confirmed et crédite votre solde.

Encaissements

Créer un Encaissement

Génère une adresse de portefeuille TRON unique pour que votre client y envoie des USDT. L'adresse expire après expiresInSeconds secondes (par défaut 1 heure).

POST/v1/payin

Corps de la requête

ParamètreTypeRequisDescription
amountstringrequisMontant en USDT sous forme de chaîne décimale (ex. « 100.00 »). Minimum : « 20.00 ».
externalRefstringoptionnelVotre ID de commande ou référence (optionnel). Doit être unique par marchand si fourni.
expiresInSecondsintegeroptionnelSecondes avant l'expiration de l'adresse. Minimum : 900. Défaut : 3600.
successUrlstringoptionnelURL de redirection du client après un paiement réussi.
cancelUrlstringoptionnelURL de redirection du client si le paiement expire ou est annulé.
metadataobjectoptionnelPaires clé-valeur arbitraires stockées avec le paiement et incluses dans les webhooks.
cURL
curl -X POST https://api.zyndpay.io/v1/payin \
  -H "X-Api-Key: zyp_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "100.00",
    "externalRef": "order_123",
    "expiresInSeconds": 3600,
    "successUrl": "https://yoursite.com/payment/success",
    "cancelUrl": "https://yoursite.com/payment/cancel"
  }'
JSON — response
{
  "success": true,
  "data": {
    "id": "cma1xyz8f0001yx5k9abc1234",
    "depositAddress": "TRXabc123def456ghi789jkl",
    "amount": "100.00",
    "status": "PENDING",
    "externalRef": "order_123",
    "expiresAt": "2026-03-06T12:00:00.000Z",
    "createdAt": "2026-03-06T11:00:00.000Z"
  }
}

Récupérer un Encaissement

Récupère un seul encaissement par son ID.

GET/v1/payin/:id
JSON — response
{
  "success": true,
  "data": {
    "id": "cma1xyz8f0001yx5k9abc1234",
    "depositAddress": "TRXabc123def456ghi789jkl",
    "amount": "100.00",
    "amountReceived": "100.00",
    "fee": "3.00",
    "netAmount": "97.00",
    "status": "CONFIRMED",
    "txHash": "abc123def456...",
    "externalRef": "order_123",
    "confirmedAt": "2026-03-06T11:01:02.000Z",
    "createdAt": "2026-03-06T11:00:00.000Z"
  }
}

Statuts de paiement

PENDINGEn attente de paiement
CONFIRMINGFonds reçus, en attente de 20 confirmations
CONFIRMED20+ confirmations — solde crédité
UNDERPAIDMontant reçu inférieur à l'attendu
OVERPAIDMontant reçu supérieur à l'attendu
EXPIREDAdresse expirée sans paiement

Lister les Encaissements

Retourne une liste paginée d'encaissements, les plus récents en premier.

GET/v1/payin
ParamètreTypeRequisDescription
pageintegeroptionnelNuméro de page. Défaut : 1.
limitintegeroptionnelRésultats par page. Défaut : 20. Max : 100.
statusstringoptionnelFiltrer par statut : PENDING, CONFIRMING, CONFIRMED, EXPIRED, UNDERPAID ou OVERPAID.
currencystringoptionnelFiltrer par devise (ex. USDT_TRC20).
JSON — response
{
  "success": true,
  "data": [ ... ],
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 134,
    "totalPages": 7
  }
}

Liens de Paiement

Crée un lien de paiement partageable avec un ou plusieurs produits. Partagez le paymentUrl retourné avec vos clients. Supporte les types à prix fixe, variable et facturation récurrente.

POST/v1/paylinks

Corps de la requête

ParamètreTypeRequisDescription
typestringoptionnelType de lien : FIXED (défaut), VARIABLE ou RECURRING.
productsarrayrequisTableau de produits. Au moins un produit est requis.
products[].namestringrequisNom du produit affiché au client.
products[].pricestringrequisPrix en USDT sous forme de chaîne décimale.
products[].productTypestringoptionnelPHYSICAL (défaut) ou DIGITAL.
products[].digitalUrlstringoptionnelURL externe pour la livraison du produit numérique (Google Drive, Mega, etc.).
collectEmailstringoptionnelCollecte d'email client : HIDDEN (défaut), OPTIONAL ou REQUIRED.
collectNamestringoptionnelCollecte du nom client : HIDDEN, OPTIONAL ou REQUIRED.
brandColorstringoptionnelCouleur hexadécimale pour la page de checkout personnalisée (ex. #635BFF).
successUrlstringoptionnelURL de redirection du client après un paiement réussi.
recurringIntervalstringoptionnelIntervalle de facturation pour les liens récurrents : WEEKLY, MONTHLY ou YEARLY.
cURL
curl -X POST https://api.zyndpay.io/v1/paylinks \
  -H "X-Api-Key: zyp_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "type": "FIXED",
    "products": [
      {
        "name": "Premium Course",
        "price": "49.99",
        "productType": "DIGITAL",
        "digitalUrl": "https://drive.google.com/file/d/abc123"
      }
    ],
    "collectEmail": "REQUIRED",
    "brandColor": "#635BFF"
  }'
JSON — response
{
  "success": true,
  "data": {
    "id": "pl_cma1xyz8f0001yx5k",
    "slug": "aB3dE6fG7hI9",
    "type": "FIXED",
    "status": "ACTIVE",
    "paymentUrl": "https://dashboard.zyndpay.io/pay/link/aB3dE6fG7hI9",
    "products": [
      {
        "id": "prod_abc123",
        "name": "Premium Course",
        "price": "49.990000000000000000",
        "productType": "DIGITAL",
        "digitalUrl": "https://drive.google.com/file/d/abc123"
      }
    ],
    "createdAt": "2026-03-08T10:00:00.000Z"
  }
}

Récupère un seul lien de paiement par son ID, y compris les produits, codes promo et nombre de commandes.

GET/v1/paylinks/:id

Retourne une liste paginée de vos liens de paiement, les plus récents en premier.

GET/v1/paylinks
ParamètreTypeRequisDescription
pageintegeroptionnelNuméro de page. Défaut : 1.
limitintegeroptionnelRésultats par page. Défaut : 20. Max : 100.

Endpoint public (pas d'auth requise). Crée une commande et un encaissement à partir d'un lien de paiement. Le client reçoit une adresse TRON pour envoyer les USDT.

POST/v1/pay/link/:slug/checkout
ParamètreTypeRequisDescription
itemsarrayrequisTableau d'IDs de produits et quantités à acheter.
customerEmailstringoptionnelAdresse email du client (requise pour RECURRING et produits numériques).
customerNamestringoptionnelNom du client (optionnel).
cURL
curl -X POST https://api.zyndpay.io/v1/pay/link/aB3dE6fG7hI9/checkout \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "productId": "prod_abc123", "quantity": 1 }
    ],
    "customerEmail": "[email protected]",
    "customerName": "John Doe"
  }'
JSON — response
{
  "success": true,
  "data": {
    "orderId": "ord_xyz789",
    "transactionId": "cma2abc9g0002yz6l0def",
    "depositAddress": "TRXabc123def456ghi789jkl",
    "amount": "49.99",
    "expiresAt": "2026-03-08T11:00:00.000Z"
  }
}

Paiements Sortants

Créer un Paiement Sortant

Les paiements sortants vous permettent d'envoyer des USDT depuis votre solde ZyndPay vers n'importe quelle adresse TRON — payez des fournisseurs, remboursez des clients ou distribuez des commissions d'affiliation. Des frais fixes de 2 USDT sont déduits de votre solde en plus du montant du paiement.

Note:Paiements sortants vs Retraits : Les paiements sortants envoient des fonds vers n'importe quelle adresse tierce (fournisseurs, clients, affiliés). Les retraits transfèrent des fonds vers vos propres adresses de portefeuille préenregistrées.
POST/v1/payout
Conseil:Les paiements sortants sont idempotents. Passez un en-tête Idempotency-Key unique (UUID recommandé) pour retenter des requêtes échouées en toute sécurité sans créer de doublons.

Corps de la requête

ParamètreTypeRequisDescription
amountstringrequisMontant en USDT à envoyer (ex. « 50.00 »). Minimum : « 20.00 ». Les frais de traitement de 2 USDT sont facturés séparément.
destinationAddressstringrequisAdresse de portefeuille TRON (TRC20) du destinataire. Doit correspondre au format T suivi de 33 caractères base58.
currencystringoptionnelDevise à envoyer. Défaut : USDT_TRC20.
chainstringoptionnelRéseau blockchain. Défaut : TRON.
externalRefstringoptionnelVotre ID de référence interne pour ce paiement (ex. numéro de facture fournisseur).
metadataobjectoptionnelPaires clé-valeur arbitraires stockées avec le paiement.
cURL
curl -X POST https://api.zyndpay.io/v1/payout \
  -H "X-Api-Key: zyp_live_sk_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -d '{
    "amount": "50.00",
    "destinationAddress": "TXYZabc123def456ghi789jkl012mno345",
    "externalRef": "payout_vendor_456"
  }'
JSON — response
{
  "success": true,
  "data": {
    "transactionId": "cma2abc9g0002yz6l0def5678",
    "status": "PROCESSING",
    "processingFee": "2.00",
    "requiresManualApproval": false,
    "currentPayinFee": "3.0%",
    "currentTier": "STARTER"
  }
}

Récupérer un Paiement Sortant

Récupère un seul paiement sortant par son ID, y compris son statut actuel et les détails de la transaction.

GET/v1/payout/:id

Statuts des paiements sortants

PENDINGEn attente d'approbation manuelle (montant > 50 K $)
PROCESSINGApprouvé, préparation de la diffusion
BROADCASTSoumis au réseau TRON
CONFIRMEDConfirmé on-chain
FAILEDDiffusion échouée — solde remboursé
CANCELLEDAnnulé avant diffusion

Lister les Paiements Sortants

Retourne une liste paginée de paiements sortants, les plus récents en premier.

GET/v1/payout
ParamètreTypeRequisDescription
pageintegeroptionnelNuméro de page. Défaut : 1.
limitintegeroptionnelRésultats par page. Défaut : 20. Max : 100.
JSON — response
{
  "success": true,
  "data": {
    "items": [ ... ],
    "total": 42
  }
}

Retraits

Demander un Retrait

Les retraits permettent aux marchands de transférer leur solde USDT réglé depuis ZyndPay vers l'une de leurs adresses de portefeuille préenregistrées. Des frais fixes de 2 USDT sont déduits du montant.

Note:Les adresses de destination doivent être enregistrées dans votre tableau de bord avant de pouvoir effectuer un retrait. Si addressId est omis, ZyndPay utilise l'adresse de retrait principale de votre compte.
POST/v1/withdrawals
Conseil:Les retraits sont idempotents. Passez un en-tête Idempotency-Key unique (UUID recommandé) pour retenter des requêtes échouées en toute sécurité sans créer de doublons.
ParamètreTypeRequisDescription
amountstringrequisMontant en USDT à retirer (ex. « 500.00 »). Les frais de 2 USDT sont déduits de ce montant.
addressIdUUIDoptionnelID de l'adresse de retrait enregistrée à utiliser. Utilise votre adresse principale si omis.
cURL
curl -X POST https://api.zyndpay.io/v1/withdrawals \
  -H "X-Api-Key: zyp_live_sk_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -d '{
    "amount": "500.00",
    "addressId": "addr_cma1xyz8f0001yx5k"
  }'
JSON — response
{
  "success": true,
  "data": {
    "id": "wdr_cma1xyz8f0001yx5k",
    "amount": "500.00",
    "fee": "2.00",
    "netAmount": "498.00",
    "destinationAddress": "TRXabc123def456ghi789jkl",
    "status": "PENDING",
    "createdAt": "2026-03-06T11:00:00.000Z"
  }
}

Récupérer un Retrait

Récupère une seule demande de retrait par son ID.

GET/v1/withdrawals/:id
PENDING_REVIEWEn attente de validation admin
APPROVEDApprouvé, en file d'attente pour traitement
BROADCASTSoumis au réseau TRON
CONFIRMEDConfirmé on-chain
REJECTEDRejeté par la validation admin
FAILEDDiffusion échouée — solde remboursé
CANCELLEDAnnulé avant diffusion

Annuler un Retrait

Annule une demande de retrait encore au statut PENDING_REVIEW (avant son approbation et sa diffusion sur le réseau TRON). Le montant est immédiatement retourné à votre solde.

DELETE/v1/withdrawals/:id

Webhooks

Vue d'ensemble

ZyndPay envoie des requêtes HTTP POST à vos URLs d'endpoints enregistrés lorsque des événements de paiement se produisent. Enregistrez des endpoints depuis la page Webhooks de votre tableau de bord marchand.

Conseil:Votre endpoint doit retourner un statut 2xx dans les 10 secondes. Les livraisons échouées sont relancées avec un backoff exponentiel jusqu'à 5 fois sur ~2 heures.
JSON — example payload
{
  "id": "wh_cma1xyz8f0001yx5k",
  "type": "payin.confirmed",
  "data": {
    "id": "cma1xyz8f0001yx5k9abc1234",
    "amount": "100.00",
    "fee": "3.00",
    "netAmount": "97.00",
    "status": "CONFIRMED",
    "externalRef": "order_123",
    "txHash": "abc123def456...",
    "confirmedAt": "2026-03-06T11:01:02.000Z"
  },
  "createdAt": "2026-03-06T11:01:03.000Z"
}

Vérification de Signature

Chaque livraison de webhook inclut un en-tête X-ZyndPay-Signature. Vérifiez-le toujours avant de traiter l'événement.

X-ZyndPay-Signature: t=1741258862,v1=abc123def456...

La signature est HMAC-SHA256(timestamp + "." + raw_body, webhook_secret). Utilisez toujours le corps brut de la requête — analyser le JSON d'abord causera des échecs de vérification.

Node.js
const crypto = require('crypto');

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-zyndpay-signature'];
  const [tPart, v1Part] = sig.split(',');
  const timestamp = tPart.split('=')[1];
  const received  = v1Part.split('=')[1];

  // Reject events older than 5 minutes
  const age = Math.abs(Date.now() / 1000 - parseInt(timestamp));
  if (age > 300) return res.status(400).send('Webhook too old');

  const expected = crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(`${timestamp}.${req.body}`)
    .digest('hex');

  // Use timing-safe comparison to prevent timing attacks
  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) {
    return res.status(400).send('Invalid signature');
  }

  const event = JSON.parse(req.body);
  // Handle event...
  res.json({ received: true });
});
Python
import hmac, hashlib, time

def verify_webhook(payload: bytes, sig_header: str, secret: str) -> bool:
    parts = dict(p.split("=", 1) for p in sig_header.split(","))
    timestamp = parts["t"]
    received  = parts["v1"]

    # Reject events older than 5 minutes
    if abs(time.time() - int(timestamp)) > 300:
        return False

    expected = hmac.new(
        secret.encode(),
        f"{timestamp}.{payload.decode()}".encode(),
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(expected, received)

Événements

ParamètreTypeRequisDescription
payin.createdeventoptionnelDéclenché quand un nouvel encaissement est créé et une adresse de dépôt est générée.
payin.confirmingeventoptionnelDéclenché quand des fonds sont reçus et en attente de 20 confirmations de blocs.
payin.confirmedeventoptionnelDéclenché quand un encaissement atteint 20 confirmations on-chain. Le solde marchand est crédité.
payin.expiredeventoptionnelDéclenché quand une adresse d'encaissement expire sans recevoir le montant attendu.
payin.underpaideventoptionnelDéclenché quand un encaissement reçoit moins que le montant demandé.
payin.overpaideventoptionnelDéclenché quand un encaissement reçoit plus que le montant demandé.
withdrawal.requestedeventoptionnelDéclenché quand un nouveau retrait est demandé et mis en file d'attente pour validation.
withdrawal.confirmedeventoptionnelDéclenché quand un retrait est confirmé on-chain.
withdrawal.failedeventoptionnelDéclenché quand la diffusion d'un retrait échoue. Le montant est remboursé au solde.

SDKs & Plugins

SDK Node.js

Le SDK TypeScript officiel avec typage complet et vérification de webhook intégrée.

npm
npm install @zyndpay/sdk
TypeScript / Node.js
const { ZyndPay } = require('@zyndpay/sdk');

const client = new ZyndPay({
  apiKey: 'zyp_live_sk_...',
  webhookSecret: process.env.ZYNDPAY_WEBHOOK_SECRET,
});

// Create a payment
const payment = await client.payins.create({
  amount: '100.00',
  externalRef: 'order_123',
});
console.log(payment.depositAddress);

// Verify a webhook (uses raw body, not parsed JSON)
const event = client.webhooks.verify(
  rawBody,
  req.headers['x-zyndpay-signature']
);

SDK Python

Le SDK Python officiel basé sur httpx avec support synchrone et asynchrone.

pip
pip install zyndpay
Python
from zyndpay import ZyndPay

client = ZyndPay(
    api_key="zyp_live_sk_...",
    webhook_secret=os.environ.get("ZYNDPAY_WEBHOOK_SECRET"),
)

payment = client.payins.create(
    amount="100.00",
    external_ref="order_123"
)
print(payment["depositAddress"])

Plugin WooCommerce

Acceptez des paiements USDT dans votre boutique WordPress / WooCommerce sans écrire une seule ligne de code. Le plugin génère des adresses de dépôt, surveille le statut de confirmation et exécute automatiquement les commandes.

Installation

  1. 1.Téléchargez le ZIP du plugin depuis le dépôt GitHub ZyndPay.
  2. 2.Dans l'administration WordPress, allez dans Extensions → Ajouter → Téléverser une extension.
  3. 3.Téléversez le ZIP et cliquez sur Activer.
  4. 4.Naviguez vers WooCommerce → Réglages → Paiements → ZyndPay.
  5. 5.Entrez votre clé API et votre secret webhook, puis sauvegardez.

Sandbox

Vue d'ensemble

Le sandbox vous permet de tester toute votre intégration sans toucher à de vrais fonds ni au réseau TRON. Utilisez votre clé zyp_test_sk_... — l'API est identique à la production.

Solde isolé

Les fonds sandbox sont complètement séparés de votre solde live.

API identique

Mêmes endpoints, mêmes formats de réponse, mêmes événements webhook.

Confirmation instantanée

Simulez la confirmation de paiement en un seul appel API — sans attente.

Gratuit pour toujours

Disponible pour tous les marchands dès le premier jour, sans approbation nécessaire.

Simuler un Paiement

Confirme instantanément un encaissement sandbox, déclenche le webhook payin.confirmed et crédite le solde sandbox — exactement comme une vraie confirmation on-chain.

POST/v1/sandbox/payin/:id/simulate
cURL
curl -X POST \
  https://api.zyndpay.io/v1/sandbox/payin/{id}/simulate \
  -H "X-Api-Key: zyp_test_sk_..."
JSON — response
{
  "success": true,
  "data": {
    "id": "cma1xyz8f0001yx5k9abc1234",
    "status": "CONFIRMED",
    "amountReceived": "100.00",
    "txHash": "sandbox_tx_abc123",
    "confirmedAt": "2026-03-06T11:00:01.000Z"
  }
}

Référence

Codes d'Erreur

Toutes les erreurs retournent la même enveloppe JSON. Utilisez le champ error pour gérer les erreurs par programmation — le champ message est lisible par l'humain et peut changer.

JSON — error response
{
  "success": false,
  "error": "AMOUNT_TOO_LOW",
  "message": "Minimum payin amount is 20 USDT",
  "statusCode": 400,
  "requestId": "req_abc123"
}
ParamètreTypeRequisDescription
UNAUTHORIZED401optionnelClé API manquante ou invalide.
FORBIDDEN403optionnelLa clé API n'a pas le scope requis.
NOT_FOUND404optionnelLa ressource demandée n'existe pas.
AMOUNT_TOO_LOW400optionnelLe montant d'encaissement est inférieur au minimum de 20 USDT.
EXTERNAL_REF_TAKEN409optionnelUn encaissement avec cet externalRef existe déjà pour votre compte.
INSUFFICIENT_BALANCE402optionnelVotre solde est insuffisant pour le montant de retrait demandé.
ADDRESS_NOT_FOUND404optionnelL'addressId ne correspond à aucune adresse de retrait enregistrée sur votre compte.
IDEMPOTENCY_CONFLICT409optionnelClé d'idempotence réutilisée avec des paramètres de requête différents.
RATE_LIMITED429optionnelTrop de requêtes. Réessayez après la valeur de l'en-tête Retry-After.
INTERNAL_ERROR500optionnelErreur serveur inattendue. Contactez le support si elle persiste.

Limites de Taux

Les limites sont appliquées par clé API. Les requêtes dépassant les limites reçoivent une réponse 429 avec un en-tête Retry-After.

ParamètreTypeRequisDescription
Default100 req / 60soptionnelS'applique à tous les endpoints par clé API.
POST /v1/payin60 req / 60soptionnelLa création d'encaissement a une limite supplémentaire.
POST /v1/payout20 req / 60soptionnelLa création de paiement a une limite plus stricte.
Conseil:Les marchands Enterprise peuvent demander des limites plus élevées — contactez [email protected].

© 2026 ZyndPay. Tous droits réservés.