Passer au contenu principal
En bref
L’API de Retrait de Blockradar vous permet d’envoyer des stablecoins depuis vos portefeuilles vers des adresses blockchain externes. Elle prend en charge les retraits individuels, les retraits par lots vers plusieurs destinataires et fournit une estimation des frais avant l’exécution.
Interface de Retrait Blockradar

Prérequis

Avant d’utiliser l’API de Retrait, assurez-vous d’avoir :
1

Clé API

Obtenez votre clé API depuis le Tableau de bord Blockradar. Naviguez vers Paramètres → Clés API pour en générer une.
2

Portefeuille Créé

Créez un portefeuille via l’API Créer Portefeuille ou le tableau de bord. Vous aurez besoin du walletId pour les opérations de retrait.
3

ID de l'Actif

Obtenez l’assetId du token que vous souhaitez retirer depuis Actifs dans le tableau de bord ou via l’API Obtenir Actifs.
4

Solde Suffisant

Assurez-vous que votre portefeuille dispose d’un solde suffisant de l’actif à retirer, plus de la monnaie native (ETH, BNB, MATIC, etc.) pour couvrir les frais de réseau.

Comment ça Fonctionne

L’API de Retrait envoie des stablecoins depuis votre portefeuille Blockradar vers n’importe quelle adresse blockchain externe :

Retrait Individuel

Envoyez des actifs à une adresse de destinataire avec un seul appel API.

Retrait par Lots

Envoyez des actifs à plusieurs destinataires en un seul appel API, réduisant les frais généraux et simplifiant les paiements en masse.

Estimation des Frais

Calculez les frais de réseau avant l’exécution pour garantir un solde suffisant et afficher les coûts aux utilisateurs.

Mode Signature Seule

Signez les transactions sans les diffuser pour des cas d’utilisation avancés comme la signature hors ligne ou la soumission personnalisée.

Portefeuille Principal vs Adresse Enfant

L’API de Retrait est disponible à deux niveaux :

Portefeuille Principal

Retirez directement depuis votre portefeuille principal. Idéal pour les opérations de trésorerie et la gestion centralisée des fonds.

Adresse Enfant

Retirez depuis des adresses enfants individuelles. Parfait pour les opérations spécifiques aux utilisateurs et la gestion séparée des fonds.

Endpoints

OpérationPortefeuille PrincipalAdresse Enfant
RetirerPOST /v1/wallets/{walletId}/withdrawPOST /v1/wallets/{walletId}/addresses/{addressId}/withdraw
Frais de RéseauPOST /v1/wallets/{walletId}/withdraw/network-feePOST /v1/wallets/{walletId}/addresses/{addressId}/withdraw/network-fee
Signature SeulePOST /v1/wallets/{walletId}/withdraw/signPOST /v1/wallets/{walletId}/addresses/{addressId}/withdraw/sign

Retrait Individuel

Envoyez des actifs à une seule adresse de destinataire.

Paramètres de la Requête

ParamètreTypeRequisDescription
assetIdstringOui*L’UUID de l’actif à retirer. Requis si le tableau assets n’est pas fourni.
addressstringOui*L’adresse du portefeuille de destination. Requis si le tableau assets n’est pas fourni.
amountstringOui*Le montant du retrait. Doit être supérieur à 0. Requis si le tableau assets n’est pas fourni.
referencestringNonVotre ID de suivi interne pour le retrait.
notestringNonUn court message ou une remarque interne. Non visible sur la blockchain.
metadataobjectNonPaires clé-valeur personnalisées pour des détails de transaction supplémentaires.
Les paramètres marqués avec * sont requis pour les retraits individuels mais ne sont pas nécessaires si vous utilisez le tableau assets pour les retraits par lots.

Exemple de Retrait Individuel

curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/withdraw \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assetId": "asset-uuid-ici",
    "address": "0xAdresseDestinataire...",
    "amount": "100",
    "reference": "paiement-12345",
    "note": "Paiement mensuel",
    "metadata": {
      "userId": "user_abc123",
      "payoutType": "salaire"
    }
  }'

Réponse de Retrait Individuel

{
  "message": "Retrait initié avec succès",
  "statusCode": 200,
  "data": {
    "id": "tx-uuid-123",
    "hash": "0xabc123...",
    "status": "PENDING",
    "amount": "100",
    "recipientAddress": "0xAdresseDestinataire...",
    "reference": "paiement-12345",
    "note": "Paiement mensuel",
    "metadata": {
      "userId": "user_abc123",
      "payoutType": "salaire"
    },
    "createdAt": "2024-01-15T10:30:00Z"
  }
}

Retraits par Lots

Envoyez des actifs à plusieurs destinataires en un seul appel API. Les retraits par lots sont exécutés séquentiellement, et chaque retrait est traité comme une transaction blockchain séparée.

Quand Utiliser les Retraits par Lots

  • Paiements en masse : Payez plusieurs employés, fournisseurs ou partenaires à la fois
  • Distributions : Envoyez des actifs à plusieurs adresses
  • Transferts multi-destinataires : Envoyez différents montants à différentes adresses
  • Efficacité opérationnelle : Réduisez les appels API et simplifiez la logique de paiement

Paramètres de Requête par Lots

Pour les retraits par lots, utilisez le tableau assets au lieu des paramètres individuels :
ParamètreTypeRequisDescription
assetsarrayOuiTableau d’objets de retrait (max 20 par lot)
Chaque élément du tableau assets :
ChampTypeRequisDescription
idstringOuiL’UUID de l’actif à retirer
addressstringOuiL’adresse du portefeuille de destination
amountstringOuiLe montant du retrait. Doit être supérieur à 0.
referencestringNonNote de référence optionnelle pour ce retrait
notestringNonUn court message ou une remarque interne. Non visible sur la blockchain.
metadataobjectNonPaires clé-valeur personnalisées pour des détails de transaction supplémentaires.

Exemple de Retrait par Lots

curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/withdraw \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assets": [
      {
        "id": "asset-uuid-usdc",
        "address": "0xDestinataire1...",
        "amount": "100",
        "reference": "paiement-001",
        "note": "Salaire janvier"
      },
      {
        "id": "asset-uuid-usdc",
        "address": "0xDestinataire2...",
        "amount": "150",
        "reference": "paiement-002",
        "note": "Salaire janvier"
      },
      {
        "id": "asset-uuid-usdt",
        "address": "0xDestinataire3...",
        "amount": "200",
        "reference": "paiement-003",
        "note": "Paiement fournisseur"
      }
    ]
  }'

Réponse de Retrait par Lots

{
  "message": "Retrait par lots initié avec succès",
  "statusCode": 200,
  "data": {
    "success": [
      {
        "index": 0,
        "id": "tx-uuid-1",
        "hash": "0xabc...",
        "status": "PENDING",
        "amount": "100",
        "recipientAddress": "0xDestinataire1...",
        "reference": "paiement-001"
      },
      {
        "index": 1,
        "id": "tx-uuid-2",
        "hash": "0xdef...",
        "status": "PENDING",
        "amount": "150",
        "recipientAddress": "0xDestinataire2...",
        "reference": "paiement-002"
      },
      {
        "index": 2,
        "id": "tx-uuid-3",
        "hash": "0xghi...",
        "status": "PENDING",
        "amount": "200",
        "recipientAddress": "0xDestinataire3...",
        "reference": "paiement-003"
      }
    ],
    "errors": []
  }
}

Gestion des Échecs Partiels

Les retraits par lots supportent le succès partiel. Si certains retraits échouent, les autres seront quand même exécutés :
const result = await batchWithdrawal.json();

// Traiter les retraits réussis
result.data.success.forEach(tx => {
  console.log(`✓ ${tx.reference}: ${tx.hash}`);
});

// Gérer les retraits échoués
result.data.errors.forEach(error => {
  console.error(`✗ Index ${error.index}: ${error.error}`);
  // Logique de réessai ou rapport d'erreurs ici
});

Règles de Retrait par Lots

RègleValeur
Taille maximale du lot20 retraits par requête
Taille minimale du lot1 retrait
Ordre d’exécutionSéquentiel
Gestion des erreursSuccès partiel (les échecs n’arrêtent pas les retraits suivants)

Estimation des Frais de Réseau

Estimez toujours les frais avant d’exécuter des retraits pour garantir un solde suffisant en monnaie native et afficher des coûts précis aux utilisateurs.

Estimation de Frais Individuelle

curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/withdraw/network-fee \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assetId": "asset-uuid-ici",
    "address": "0xAdresseDestinataire...",
    "amount": "100"
  }'

Réponse de Frais Individuelle

{
  "message": "Frais de réseau récupérés avec succès",
  "statusCode": 200,
  "data": {
    "networkFee": "0.00001247904",
    "networkFeeInUSD": "0.01",
    "transactionFee": "0",
    "nativeBalance": "0.5",
    "nativeBalanceInUSD": "450.00",
    "estimatedArrivalTime": 30
  }
}

Estimation de Frais par Lots

Estimez les frais pour plusieurs retraits à la fois :
curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/withdraw/network-fee \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assets": [
      {
        "id": "asset-uuid-1",
        "address": "0xDestinataire1...",
        "amount": "100"
      },
      {
        "id": "asset-uuid-2",
        "address": "0xDestinataire2...",
        "amount": "50"
      }
    ]
  }'

Réponse de Frais par Lots

{
  "message": "Frais de réseau récupérés avec succès",
  "statusCode": 200,
  "data": {
    "fees": [
      {
        "index": 0,
        "assetId": "asset-uuid-1",
        "address": "0xDestinataire1...",
        "amount": "100",
        "networkFee": "0.00001247904",
        "transactionFee": "0",
        "estimatedArrivalTime": 30
      },
      {
        "index": 1,
        "assetId": "asset-uuid-2",
        "address": "0xDestinataire2...",
        "amount": "50",
        "networkFee": "0.00000504",
        "transactionFee": "0",
        "estimatedArrivalTime": 30
      }
    ],
    "totalNetworkFee": "0.00001751904",
    "totalNetworkFeeInUSD": "0.02",
    "totalTransactionFee": "0",
    "nativeBalance": "0.073690520542044578",
    "nativeBalanceInUSD": "66.54",
    "estimatedArrivalTime": 60,
    "errors": []
  }
}

Champs de Réponse des Frais

ChampDescription
networkFeeFrais de gas en unités de token natif (retrait individuel)
networkFeeInUSDFrais de gas convertis en USD (retrait individuel)
feesTableau des estimations de frais individuelles (retrait par lots)
totalNetworkFeeSomme de tous les frais de réseau (retrait par lots)
totalNetworkFeeInUSDFrais de réseau total en USD (retrait par lots)
transactionFeeFrais de transaction de la plateforme (si applicable)
nativeBalanceSolde actuel en token natif
nativeBalanceInUSDSolde en token natif en USD
estimatedArrivalTimeTemps de confirmation attendu en secondes
errorsTableau des estimations échouées (retrait par lots)

Mode Signature Seule

Signez les transactions sans les diffuser sur la blockchain. Utile pour :
  • Signature hors ligne : Préparez les transactions pour une soumission ultérieure
  • Flux multi-signatures : Collectez les signatures avant la soumission
  • Inspection des transactions : Examinez les détails de la transaction avant la diffusion

Exemple de Signature Seule

curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/withdraw/sign \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assetId": "asset-uuid-ici",
    "address": "0xAdresseDestinataire...",
    "amount": "100"
  }'

Réponse de Signature Seule

{
  "message": "Transaction signée avec succès",
  "statusCode": 200,
  "data": {
    "id": "tx-uuid-123",
    "signedTransaction": "0xf86c...",
    "status": "SIGNED",
    "amount": "100",
    "recipientAddress": "0xAdresseDestinataire...",
    "createdAt": "2024-01-15T10:30:00Z"
  }
}

Retraits depuis Adresse Enfant

Retirez depuis des adresses enfants individuelles au lieu du portefeuille principal :
curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/addresses/{addressId}/withdraw \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assetId": "asset-uuid-ici",
    "address": "0xAdresseDestinataire...",
    "amount": "50",
    "reference": "retrait-utilisateur-123"
  }'
Les retraits depuis adresse enfant supportent également les opérations par lots en utilisant le tableau assets, suivant le même format que les retraits par lots du portefeuille principal.

Événements Webhook

Surveillez l’achèvement des retraits via les webhooks :
ÉvénementDescription
withdraw.successRetrait terminé et confirmé sur la blockchain
withdraw.failedLe retrait a échoué à l’exécution
withdraw.cancelledLe retrait a été annulé avant l’achèvement

Payload du Webhook

{
  "event": "withdraw.success",
  "data": {
    "id": "081d6315-159f-4c38-b02a-c4708836c5bd",
    "reference": "paiement-12345",
    "senderAddress": "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a",
    "recipientAddress": "0x2455eC6700092991Ce0782365A89d5Cd89c8Fa22",
    "amount": "100",
    "amountPaid": "100",
    "fee": null,
    "currency": "USD",
    "blockNumber": 6928833,
    "hash": "0x5fcb7dd11cbb5a6d64da08cf7e0d63c1a1e7b9d1b89e3e8d1c6a5f4b3a2c1d0e",
    "status": "SUCCESS",
    "type": "WITHDRAW",
    "note": "Paiement mensuel",
    "asset": {
      "id": "asset-uuid",
      "name": "USD Coin",
      "symbol": "USDC",
      "decimals": 6
    },
    "wallet": {
      "id": "wallet-uuid",
      "name": "Trésorerie Principale"
    },
    "blockchain": {
      "id": "blockchain-uuid",
      "name": "ethereum",
      "network": "mainnet"
    },
    "metadata": {
      "userId": "user_abc123",
      "payoutType": "salaire"
    },
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-15T10:31:00Z"
  }
}

Exemple de Flux Complet

Voici une implémentation complète montrant le flux estimation des frais → confirmation utilisateur → retrait :
async function processWithdrawal(walletId, assetId, recipientAddress, amount) {
  const apiKey = process.env.BLOCKRADAR_API_KEY;
  const baseUrl = 'https://api.blockradar.co/v1';

  // Étape 1: Estimer les frais de réseau
  const feeResponse = await fetch(
    `${baseUrl}/wallets/${walletId}/withdraw/network-fee`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        assetId,
        address: recipientAddress,
        amount
      })
    }
  ).then(r => r.json());

  // Étape 2: Vérifier si nous avons assez de solde natif pour le gas
  const fee = feeResponse.data;
  if (parseFloat(fee.nativeBalance) < parseFloat(fee.networkFee)) {
    throw new Error(`Gas insuffisant: nécessaire ${fee.networkFee}, disponible ${fee.nativeBalance}`);
  }

  // Étape 3: Afficher les frais à l'utilisateur (dans votre UI)
  console.log(`Frais de réseau: ${fee.networkFee} (≈$${fee.networkFeeInUSD})`);
  console.log(`Temps estimé: ${fee.estimatedArrivalTime}s`);

  // Étape 4: Exécuter le retrait (après confirmation de l'utilisateur)
  const withdrawal = await fetch(
    `${baseUrl}/wallets/${walletId}/withdraw`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        assetId,
        address: recipientAddress,
        amount,
        reference: `retrait-${Date.now()}`
      })
    }
  ).then(r => r.json());

  console.log('Retrait initié:', withdrawal.data.id);
  console.log('Hash de transaction:', withdrawal.data.hash);

  // Étape 5: Écouter le webhook pour confirmer l'achèvement
  return withdrawal.data;
}

// Utilisation
processWithdrawal(
  'wallet-uuid',
  'asset-uuid-usdc',
  '0xAdresseDestinataire...',
  '100'
);

Réponses d’Erreur

{
  "message": "Solde insuffisant pour le retrait",
  "statusCode": 400,
  "error": "INSUFFICIENT_BALANCE",
  "data": {
    "required": "100",
    "available": "50.25",
    "asset": "USDC"
  }
}
{
  "message": "Solde insuffisant en token natif pour le gas",
  "statusCode": 400,
  "error": "INSUFFICIENT_GAS",
  "data": {
    "required": "0.005",
    "available": "0.001",
    "token": "ETH"
  }
}
{
  "message": "Adresse de destinataire invalide",
  "statusCode": 400,
  "error": "INVALID_ADDRESS",
  "data": {
    "address": "adresse_invalide_ici"
  }
}
{
  "message": "Actif non trouvé",
  "statusCode": 404,
  "error": "ASSET_NOT_FOUND",
  "data": {
    "assetId": "asset-uuid-invalide"
  }
}
{
  "message": "Le montant doit être supérieur à 0",
  "statusCode": 400,
  "error": "INVALID_AMOUNT",
  "data": {
    "amount": "0"
  }
}
{
  "message": "La taille du lot dépasse la limite maximale",
  "statusCode": 400,
  "error": "BATCH_SIZE_EXCEEDED",
  "data": {
    "maximum": 20,
    "provided": 25
  }
}

Meilleures Pratiques

Sécurité

  • Validez les adresses : Vérifiez toujours les adresses des destinataires avant d’initier des retraits
  • Utilisez des références : Suivez les retraits avec des IDs de référence uniques pour la réconciliation
  • Implémentez les webhooks : Écoutez les événements withdraw.success et withdraw.failed pour confirmer le statut
  • Vérifiez AML : Blockradar examine automatiquement les adresses—examinez les transactions signalées

Gestion des Frais

  • Estimez avant d’exécuter : Appelez toujours l’endpoint network-fee avant les retraits
  • Surveillez le solde natif : Assurez-vous d’avoir suffisamment d’ETH/BNB/MATIC pour les frais de gas
  • Utilisez les lots pour l’efficacité : Regroupez plusieurs retraits pour réduire les appels API et les frais généraux opérationnels

Gestion des Erreurs

  • Gérez les échecs partiels : Dans les retraits par lots, vérifiez les tableaux success et errors
  • Implémentez les réessais : Utilisez le backoff exponentiel pour les échecs transitoires
  • Enregistrez toutes les transactions : Stockez les IDs de transaction et les hashes pour le débogage et la réconciliation

Performance

  • Utilisez des tailles de lot appropriées : Les lots plus grands réduisent les appels API mais augmentent le temps de requête individuelle
  • Mettez en cache les IDs d’actifs : Stockez les IDs d’actifs localement pour éviter les recherches répétées
  • Implémentez la limitation de débit : Respectez les limites de débit de l’API pour éviter le throttling

Référence API

Endpoints du Portefeuille Principal

EndpointDescription
RetirerExécuter un retrait individuel ou par lots
Frais de RéseauEstimer les frais de retrait
Signature SeuleSigner sans diffuser

Endpoints de l’Adresse Enfant

EndpointDescription
RetirerExécuter un retrait individuel ou par lots
Frais de RéseauEstimer les frais de retrait
Signature SeuleSigner sans diffuser

Support

L’API de Retrait fournit une interface flexible pour envoyer des stablecoins vers des adresses externes. Commencez par des retraits individuels et l’estimation des frais, puis intégrez les opérations par lots pour les paiements en masse à mesure que vos besoins augmentent.