tgpay cryptoAPI
crypto-payapitransferspayouts

Référence de l’API : transferts et chèques

7 min de lectureMis à jour le 2 nov. 2026

Cette page décrit les méthodes de paiement sortant. Un transfert envoie des fonds depuis le solde de votre application vers le portefeuille d’un utilisateur Telegram, ou les garde en attente jusqu’à l’arrivée d’un nouveau destinataire ; un chèque est un lien permettant de récupérer un montant que vous bloquez à l’avance. Les conventions (authentification, enveloppe, montants, spend_id) sont sur la page Référence de l’API marchand.

Les trois méthodes de paiement sortant respectent le mode de paiement sortant de l’application : une nouvelle application paie n’importe qui dès le départ ; si le propriétaire a restreint ce mode, seuls les destinataires de la liste peuvent être payés (403 recipient_not_allowed), ou plus personne du tout (403 payouts_disabled). Le propriétaire définit le mode dans la Mini App ; ce réglage ne peut pas être modifié via l’API. Les usages autorisés des paiements sortants sont définis dans les conditions d’utilisation de l’API marchand.

transfer

POST /pay/api/transfer — permission payouts, limite : 30 par minute. Un destinataire connu reçoit le paiement immédiatement. Un username inconnu crée un transfert pending : les fonds restent sous séquestre jusqu’à ce que le destinataire ouvre le bot avec ce nom d’utilisateur. Les fonds non récupérés sont rendus au solde de l’application après l’expiration du délai de 30 jours (expires_at). Vérifiez le retour au moyen du statut status: "returned" avant de comptabiliser ces fonds. Transmettez vous-même invite_url : le bot ne peut pas écrire à une personne qui ne l’a jamais lancé. Le statut final est completed ou returned. Suivez-le via getTransfers ou abonnez-vous aux webhooks transfer_completed et transfer_returned.

ParamètreTypeRequisSignification
user_idintegersoit user_id, soit usernamel’identifiant Telegram du destinataire, qui doit avoir ouvert TgPay Crypto au moins une fois
usernamestringsoit user_id, soit usernamenom d’utilisateur du destinataire, avec ou sans @ ; un nom inconnu crée un paiement en attente
assetstringouicode de l’actif
amountstringouichaîne décimale positive ; le maximum par transfert de la plateforme s’applique aussi, ainsi qu’un minimum s’il est défini (estimation de l’équivalent en dollars américains au taux courant)
spend_idstringouiclé d’idempotence, 1 à 64 caractères, unique par paiement
commentstringnonjusqu’à 1024 caractères, affiché au destinataire
disable_send_notificationbooleannontrue désactive la notification au destinataire lors d’un paiement immédiat ; la récupération d’un transfert en attente déclenche toujours une notification

Indiquez exactement un des deux paramètres : user_id ou username. Si les deux sont absents ou fournis ensemble, l’API renvoie une erreur de paramètres invalides.

Le résultat est l’objet transfert : transfer_id, hash, user_id, recipient_username, asset, amount, amount_minor, spend_id, comment, status (pending / completed / returned), created_at, completed_at, expires_at, invite_url. user_id peut valoir null tant que le nouveau destinataire n’a pas rejoint le bot ; completed_at vaut null tant que le transfert n’est pas completed et reste null si son statut est returned.

Erreurs : 403 payouts_disabled / 403 recipient_not_allowed (le mode de paiement sortant), 404 user_not_found (identifiant inconnu ou destinataire indisponible), 400 invalid_recipient (nom d’utilisateur du destinataire invalide), 400 amount_too_small / 400 amount_too_big (hors des bornes par transfert), 409 insufficient_funds, 400 unknown_asset, 400 invalid_amount, et la paire spend_id 409 idempotency_conflict / 409 idempotency_in_progress. Trop de destinataires inconnus en une minute font renvoyer 429 rate_limited pour n’importe quel destinataire (voir les limites de débit).

transferBatch

POST /pay/api/transferBatch — permission payouts, limite : 10 par minute. Une extension pour les paiements de masse : jusqu’à 100 transferts en un appel.

Un seul paramètre : items — un tableau JSON (envoyez la requête avec un corps JSON ; en form-urlencoded ou en paramètres d’URL, elle renvoie 400 invalid_request) où chaque élément est un jeu complet de paramètres de transfer (user_id ou username, asset, amount, spend_id, avec comment et disable_send_notification en option). Les spend_id doivent être uniques au sein du lot, sinon l’appel entier échoue avec 400 duplicate_spend_id avant l’exécution du premier élément. Une structure d’élément invalide, le mode de paiement sortant de l’application ou sa limite quotidienne peuvent aussi faire rejeter toute la requête avant le premier paiement. Si elle est acceptée, les résultats figurent dans result.items.

Les paiements sont traités indépendamment, dans l’ordre — un élément en échec n’annule jamais les autres. L’appel renvoie un HTTP 200 avec ok: true même quand certains éléments ont échoué : vérifiez donc toujours chaque élément :

  • succès : {"ok": true, "spend_id": "…", "result": <objet transfert>}
  • échec : {"ok": false, "spend_id": "…", "error": {"code": …, "name": "…"}} avec les mêmes noms d’erreur qu’un transfer simple.

Les éléments d’un lot partagent l’espace de noms d’idempotence avec les transferts simples : réessayer le lot entier — ou renvoyer un élément comme transfer simple avec le même spend_id — renvoie le résultat déjà enregistré sans payer une deuxième fois.

getTransfers

GET /pay/api/getTransfers — permission read. Filtres : asset, transfer_ids (séparés par des virgules), spend_id (correspondance exacte — retrouvez un paiement par votre propre clé), status (pending / completed / returned), plus offset / count. Renvoie {"items": [transfer, …]}, les plus récents d’abord.

createCheck

POST /pay/api/createCheck — permission checks, limite : 60 par minute. Crée par défaut un chèque à usage unique financé depuis le solde de votre application. Toute personne possédant le lien, ou uniquement le destinataire désigné, peut le récupérer. L’extension recipients crée une liste nominative avec un montant distinct pour chaque destinataire. Le total est bloqué à la création (il passe de available à onhold dans getBalance). La création de chèques suit les mêmes limites de montant et de paiements sortants quotidiens que les transferts.

ParamètreTypeRequisSignification
assetstringouicode de l’actif
amountstringsauf si recipients est définichaîne décimale positive ; avec recipients, le total est calculé à partir de la liste
pin_to_user_idintegernonseul l’utilisateur portant cet identifiant Telegram peut récupérer le chèque
pin_to_usernamestringnonseul l’utilisateur portant ce @username peut récupérer le chèque (le @ est facultatif ; ignoré quand pin_to_user_id est aussi défini). Le nom d’utilisateur doit appartenir à un utilisateur existant de l’app
spend_idstringnonclé d’idempotence (extension) — utilisez-en une
recipientsarraynonextension : 1 à 100 éléments, chacun contenant user_id ou username et un amount sous forme de chaîne décimale positive. Ne peut pas être combiné avec un destinataire désigné
passwordstringnonextension : mot de passe nécessaire pour récupérer le chèque, jusqu’à 64 caractères
expires_inintegernonextension : durée de validité en secondes ; omis ou 0 = sans expiration

Le résultat est l’objet chèque : check_id, hash, asset, amount, amount_minor, bot_check_url (le lien de récupération t.me), status (active / activated / expired — expired est une extension), pin_to_user_id, created_at, activated_at, expires_at et recipients (null pour un chèque ordinaire ; sinon, chaque entrée contient user_id, username, amount, amount_minor et claimed_at). Chaque récupération déclenche le webhook facultatif check_activated ; pour une liste nominative, il contient aussi activated_slot. À l’expiration, le montant non récupéré est rendu au solde de l’application ; l’expiration d’une liste nominative peut envoyer check_expired.

active signifie que le chèque peut encore être récupéré ; un chèque dont la durée de validité est écoulée indique expired, et son montant non récupéré est déjà revenu sur le solde de votre application. Un chèque sans expires_in n’expire jamais.

Erreurs : 403 payouts_disabled / 403 recipient_not_allowed (le mode de paiement sortant — en mode allowlist, chaque destinataire désigné ou membre de la liste nominative doit être autorisé), 400 unknown_asset, 400 invalid_amount, 404 user_not_found (le nom d’utilisateur désigné ne correspond à personne), 409 insufficient_funds, et la paire spend_id. Autres erreurs : 400 amount_too_small / 400 amount_too_big (hors des limites par transfert). Pour recipients (un tableau JSON dans un corps JSON) : 400 invalid_slots (plus de 100 éléments ; une liste vide renvoie 400 invalid_request), 400 invalid_recipient (élément sans user_id / username valide), 400 duplicate_recipient (destinataire en double), 400 self_claim (propriétaire de l’application dans la liste) et 400 invalid_pinned_user (recipients combiné à un utilisateur désigné).

deleteCheck

POST /pay/api/deleteCheck — permission checks. Un seul paramètre : check_id. Annule un chèque actif et rend le montant non récupéré au solde de votre application ; renvoie true. Erreurs : 404 check_not_found, 409 check_not_active (entièrement récupéré, expiré ou supprimé).

getChecks

GET /pay/api/getChecks — permission read. Filtres : asset, check_ids (séparés par des virgules), status (active / activated / expired), plus offset / count. Renvoie {"items": [check, …]}, les plus récents d’abord ; les chèques supprimés ne sont jamais renvoyés.