Démarrage
ZyndPay Référence API
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/v1Toutes les réponses sont encapsulées dans une enveloppe cohérente :
{
"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 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ètre | Type | Requis | Description |
|---|---|---|---|
zyp_live_sk_... | secret | requis | Clé secrète live — accès API complet. Ne jamais exposer côté client. |
zyp_live_pk_... | publishable | optionnel | Clé publiable live — accès lecture limité, sûre pour les navigateurs. |
zyp_test_sk_... | secret | optionnel | Clé secrète sandbox — identique au live mais sans transactions réelles. |
zyp_test_pk_... | publishable | optionnel | Clé publiable sandbox. |
zyp_rk_... | restricted | optionnel | Clé restreinte — limitée à des opérations spécifiques. |
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.
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.
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.
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).
/v1/payinCorps de la requête
| Paramètre | Type | Requis | Description |
|---|---|---|---|
amount | string | requis | Montant en USDT sous forme de chaîne décimale (ex. « 100.00 »). Minimum : « 20.00 ». |
externalRef | string | optionnel | Votre ID de commande ou référence (optionnel). Doit être unique par marchand si fourni. |
expiresInSeconds | integer | optionnel | Secondes avant l'expiration de l'adresse. Minimum : 900. Défaut : 3600. |
successUrl | string | optionnel | URL de redirection du client après un paiement réussi. |
cancelUrl | string | optionnel | URL de redirection du client si le paiement expire ou est annulé. |
metadata | object | optionnel | Paires clé-valeur arbitraires stockées avec le paiement et incluses dans les webhooks. |
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"
}'{
"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.
/v1/payin/:id{
"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
PENDING— En attente de paiementCONFIRMING— Fonds reçus, en attente de 20 confirmationsCONFIRMED— 20+ confirmations — solde créditéUNDERPAID— Montant reçu inférieur à l'attenduOVERPAID— Montant reçu supérieur à l'attenduEXPIRED— Adresse expirée sans paiementLister les Encaissements
Retourne une liste paginée d'encaissements, les plus récents en premier.
/v1/payin| Paramètre | Type | Requis | Description |
|---|---|---|---|
page | integer | optionnel | Numéro de page. Défaut : 1. |
limit | integer | optionnel | Résultats par page. Défaut : 20. Max : 100. |
status | string | optionnel | Filtrer par statut : PENDING, CONFIRMING, CONFIRMED, EXPIRED, UNDERPAID ou OVERPAID. |
currency | string | optionnel | Filtrer par devise (ex. USDT_TRC20). |
{
"success": true,
"data": [ ... ],
"meta": {
"page": 1,
"limit": 20,
"total": 134,
"totalPages": 7
}
}Liens de Paiement
Créer un Lien 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.
/v1/paylinksCorps de la requête
| Paramètre | Type | Requis | Description |
|---|---|---|---|
type | string | optionnel | Type de lien : FIXED (défaut), VARIABLE ou RECURRING. |
products | array | requis | Tableau de produits. Au moins un produit est requis. |
products[].name | string | requis | Nom du produit affiché au client. |
products[].price | string | requis | Prix en USDT sous forme de chaîne décimale. |
products[].productType | string | optionnel | PHYSICAL (défaut) ou DIGITAL. |
products[].digitalUrl | string | optionnel | URL externe pour la livraison du produit numérique (Google Drive, Mega, etc.). |
collectEmail | string | optionnel | Collecte d'email client : HIDDEN (défaut), OPTIONAL ou REQUIRED. |
collectName | string | optionnel | Collecte du nom client : HIDDEN, OPTIONAL ou REQUIRED. |
brandColor | string | optionnel | Couleur hexadécimale pour la page de checkout personnalisée (ex. #635BFF). |
successUrl | string | optionnel | URL de redirection du client après un paiement réussi. |
recurringInterval | string | optionnel | Intervalle de facturation pour les liens récurrents : WEEKLY, MONTHLY ou YEARLY. |
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"
}'{
"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érer un Lien de Paiement
Récupère un seul lien de paiement par son ID, y compris les produits, codes promo et nombre de commandes.
/v1/paylinks/:idLister les Liens de Paiement
Retourne une liste paginée de vos liens de paiement, les plus récents en premier.
/v1/paylinks| Paramètre | Type | Requis | Description |
|---|---|---|---|
page | integer | optionnel | Numéro de page. Défaut : 1. |
limit | integer | optionnel | Résultats par page. Défaut : 20. Max : 100. |
Paiement via Lien
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.
/v1/pay/link/:slug/checkout| Paramètre | Type | Requis | Description |
|---|---|---|---|
items | array | requis | Tableau d'IDs de produits et quantités à acheter. |
customerEmail | string | optionnel | Adresse email du client (requise pour RECURRING et produits numériques). |
customerName | string | optionnel | Nom du client (optionnel). |
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"
}'{
"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.
n'importe quelle adresse tierce (fournisseurs, clients, affiliés). Les retraits transfèrent des fonds vers vos propres adresses de portefeuille préenregistrées./v1/payoutIdempotency-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ètre | Type | Requis | Description |
|---|---|---|---|
amount | string | requis | Montant en USDT à envoyer (ex. « 50.00 »). Minimum : « 20.00 ». Les frais de traitement de 2 USDT sont facturés séparément. |
destinationAddress | string | requis | Adresse de portefeuille TRON (TRC20) du destinataire. Doit correspondre au format T suivi de 33 caractères base58. |
currency | string | optionnel | Devise à envoyer. Défaut : USDT_TRC20. |
chain | string | optionnel | Réseau blockchain. Défaut : TRON. |
externalRef | string | optionnel | Votre ID de référence interne pour ce paiement (ex. numéro de facture fournisseur). |
metadata | object | optionnel | Paires clé-valeur arbitraires stockées avec le paiement. |
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"
}'{
"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.
/v1/payout/:idStatuts des paiements sortants
PENDING— En attente d'approbation manuelle (montant > 50 K $)PROCESSING— Approuvé, préparation de la diffusionBROADCAST— Soumis au réseau TRONCONFIRMED— Confirmé on-chainFAILED— Diffusion échouée — solde rembourséCANCELLED— Annulé avant diffusionLister les Paiements Sortants
Retourne une liste paginée de paiements sortants, les plus récents en premier.
/v1/payout| Paramètre | Type | Requis | Description |
|---|---|---|---|
page | integer | optionnel | Numéro de page. Défaut : 1. |
limit | integer | optionnel | Résultats par page. Défaut : 20. Max : 100. |
{
"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.
addressId est omis, ZyndPay utilise l'adresse de retrait principale de votre compte./v1/withdrawalsIdempotency-Key unique (UUID recommandé) pour retenter des requêtes échouées en toute sécurité sans créer de doublons.| Paramètre | Type | Requis | Description |
|---|---|---|---|
amount | string | requis | Montant en USDT à retirer (ex. « 500.00 »). Les frais de 2 USDT sont déduits de ce montant. |
addressId | UUID | optionnel | ID de l'adresse de retrait enregistrée à utiliser. Utilise votre adresse principale si omis. |
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"
}'{
"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.
/v1/withdrawals/:idPENDING_REVIEW— En attente de validation adminAPPROVED— Approuvé, en file d'attente pour traitementBROADCAST— Soumis au réseau TRONCONFIRMED— Confirmé on-chainREJECTED— Rejeté par la validation adminFAILED— Diffusion échouée — solde rembourséCANCELLED— Annulé avant diffusionAnnuler 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.
/v1/withdrawals/:idWebhooks
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.
2xx dans les 10 secondes. Les livraisons échouées sont relancées avec un backoff exponentiel jusqu'à 5 fois sur ~2 heures.{
"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.
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 });
});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ètre | Type | Requis | Description |
|---|---|---|---|
payin.created | event | optionnel | Déclenché quand un nouvel encaissement est créé et une adresse de dépôt est générée. |
payin.confirming | event | optionnel | Déclenché quand des fonds sont reçus et en attente de 20 confirmations de blocs. |
payin.confirmed | event | optionnel | Déclenché quand un encaissement atteint 20 confirmations on-chain. Le solde marchand est crédité. |
payin.expired | event | optionnel | Déclenché quand une adresse d'encaissement expire sans recevoir le montant attendu. |
payin.underpaid | event | optionnel | Déclenché quand un encaissement reçoit moins que le montant demandé. |
payin.overpaid | event | optionnel | Déclenché quand un encaissement reçoit plus que le montant demandé. |
withdrawal.requested | event | optionnel | Déclenché quand un nouveau retrait est demandé et mis en file d'attente pour validation. |
withdrawal.confirmed | event | optionnel | Déclenché quand un retrait est confirmé on-chain. |
withdrawal.failed | event | optionnel | Dé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 install @zyndpay/sdkconst { 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 install zyndpayfrom 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.Téléchargez le ZIP du plugin depuis le dépôt GitHub ZyndPay.
- 2.Dans l'administration WordPress, allez dans Extensions → Ajouter → Téléverser une extension.
- 3.Téléversez le ZIP et cliquez sur Activer.
- 4.Naviguez vers WooCommerce → Réglages → Paiements → ZyndPay.
- 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.
/v1/sandbox/payin/:id/simulatecurl -X POST \
https://api.zyndpay.io/v1/sandbox/payin/{id}/simulate \
-H "X-Api-Key: zyp_test_sk_..."{
"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.
{
"success": false,
"error": "AMOUNT_TOO_LOW",
"message": "Minimum payin amount is 20 USDT",
"statusCode": 400,
"requestId": "req_abc123"
}| Paramètre | Type | Requis | Description |
|---|---|---|---|
UNAUTHORIZED | 401 | optionnel | Clé API manquante ou invalide. |
FORBIDDEN | 403 | optionnel | La clé API n'a pas le scope requis. |
NOT_FOUND | 404 | optionnel | La ressource demandée n'existe pas. |
AMOUNT_TOO_LOW | 400 | optionnel | Le montant d'encaissement est inférieur au minimum de 20 USDT. |
EXTERNAL_REF_TAKEN | 409 | optionnel | Un encaissement avec cet externalRef existe déjà pour votre compte. |
INSUFFICIENT_BALANCE | 402 | optionnel | Votre solde est insuffisant pour le montant de retrait demandé. |
ADDRESS_NOT_FOUND | 404 | optionnel | L'addressId ne correspond à aucune adresse de retrait enregistrée sur votre compte. |
IDEMPOTENCY_CONFLICT | 409 | optionnel | Clé d'idempotence réutilisée avec des paramètres de requête différents. |
RATE_LIMITED | 429 | optionnel | Trop de requêtes. Réessayez après la valeur de l'en-tête Retry-After. |
INTERNAL_ERROR | 500 | optionnel | Erreur 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ètre | Type | Requis | Description |
|---|---|---|---|
Default | 100 req / 60s | optionnel | S'applique à tous les endpoints par clé API. |
POST /v1/payin | 60 req / 60s | optionnel | La création d'encaissement a une limite supplémentaire. |
POST /v1/payout | 20 req / 60s | optionnel | La création de paiement a une limite plus stricte. |
[email protected].© 2026 ZyndPay. Tous droits réservés.