tgpay cryptoAPI
crypto-payapireferencetokens

Référence de l’API marchand

9 min de lectureMis à jour le 22 oct. 2026

Les conventions communes à toutes les méthodes, plus les méthodes de catalogue en lecture seule. Les pages méthode par méthode : factures et remboursements, transferts et chèques, abonnements, webhooks.

L’API suit les conventions de Crypto Bot pour les méthodes documentées ici. Changez l’URL de base et le token, puis testez sur le testnet les méthodes utilisées par votre intégration. Nos ajouts sont signalés par extension ci-dessous.

Une spécification OpenAPI 3.1 exploitable par les outils est également disponible : crypto-pay-openapi.yaml · crypto-pay-openapi.json. Donnez-la à vos générateurs de code, clients d’API ou outils d’IA, mais consultez aussi les pages des méthodes : le schéma peut ne pas encore couvrir les extensions les plus récentes.

URL de base et authentification

Toutes les méthodes sont accessibles à https://app.tgpaycrypto.com/pay/api/<methodName>. Sur le testnet, la base est https://testnet.tgpaycrypto.com/pay/api — applications et tokens distincts, cryptos de test sans valeur réelle.

Authentifiez chaque requête avec le token dans l’en-tête TgPayCrypto-API-Token (TgCryptoPay-API-Token, le nom d’avant le 2026-09-07, et Crypto-Pay-API-Token sont acceptés comme alias de compatibilité ; si plusieurs sont envoyés, l’en-tête principal prévaut). Un token absent, invalide ou révoqué — ainsi qu’un token restreint expiré, le token d’une application supprimée ou celui d’un propriétaire bloqué — renvoie 401 unauthorized.

Le token a la forme <app_id>:<secret> et n’est affiché qu’une fois, à la création ou au renouvellement ; le serveur n’en stocke que l’empreinte. Voir Démarrer en tant que développeur.

Tokens et permissions

Deux sortes d’identifiants s’authentifient de façon identique :

  • Le token principal — accès complet à toutes les méthodes, et la seule clé qui signe les webhooks.
  • Les tokens restreints (extension) — jusqu’à 10 tokens non révoqués par application, y compris les tokens expirés, créés dans Plus → API marchand : ouvrez l’application, puis Accès et tokens et Tokens restreints. Chacun a un libellé et un sous-ensemble de permissions. En révoquer un est instantané et ne touche pas les autres ; renouveler le token principal ne les touche pas non plus. Un token peut aussi avoir une date d’expiration après laquelle il ne permet plus de s’authentifier.
PermissionMéthodes qu’elle débloque
(tout token valide)getMe, getCurrencies, getExchangeRates
readgetBalance, getStats, getInvoices, getChecks, getTransfers, getSubscriptionPlans, getSubscriptions
invoicescreateInvoice, deleteInvoice
refundsrefundInvoice
payoutstransfer, transferBatch
checkscreateCheck, deleteCheck
subscriptionscreateSubscriptionPlan, archiveSubscriptionPlan, cancelSubscription
webhooksupdateApp

Les permissions s’additionnent et sont indépendantes — invoices n’implique pas read, donc un serveur qui ne fait que créer des factures peut utiliser un token sans accès aux soldes ni à l’historique des paiements. Appeler une méthode que le token ne couvre pas renvoie 403 scope_required. getMe rapporte les scopes du token courant (null pour le token principal) et son token_name, pour que vous puissiez identifier le token utilisé et ses permissions.

Mode de paiement sortant

Une permission définit les méthodes qu’un token peut appeler ; le mode de paiement sortant de l’application définit qui ses tokens peuvent payer, y compris le token principal. Par défaut, une nouvelle application peut payer tout utilisateur. Le propriétaire peut restreindre les destinataires en ouvrant son application dans Plus → API marchand, puis Paramètres des paiements → Paiements via l’API. Comme le plafond quotidien, cette restriction limite les actions possibles en cas de fuite du token. Pour l’assouplir, il doit confirmer avec son PIN ou la biométrie. L’API permet uniquement de consulter ce mode (getMe → payout_mode).

payout_modeCe que transfer, transferBatch et createCheck peuvent faire
anypayer n’importe quel utilisateur, mettre en attente un paiement vers un @username inconnu, créer des chèques au porteur — le comportement par défaut, et celui de Crypto Bot
allowlistpayer uniquement les utilisateurs Telegram autorisés. Chaque destinataire désigné ou membre d’une liste nominative de chèque doit être autorisé. Les autres destinataires, les @username inconnus et les chèques au porteur renvoient 403 recipient_not_allowed
offrien — chaque appel de paiement sortant renvoie 403 payouts_disabled ; les factures, les abonnements, les remboursements et les webhooks fonctionnent normalement

Si un paiement sortant est refusé, le propriétaire en est averti dans Telegram et peut changer le mode. Le plafond quotidien de paiements s’applique en plus du mode. Les usages autorisés des paiements sont définis dans les conditions d’utilisation de l’API marchand.

Requêtes et réponses

  • Les méthodes de lecture sont en GET avec des paramètres d’URL. Les méthodes qui déplacent des fonds sont uniquement en POST — paramètres en corps JSON, en form-urlencoded ou en paramètres d’URL (le corps l’emporte en cas de conflit) ; multipart/form-data est refusé.
  • Les réponses produites par les méthodes de l’API utilisent une enveloppe JSON : succès {"ok": true, "result": …}, erreur {"ok": false, "error": {"code": <statut HTTP>, "name": "<error_name>"}}. Traitez les erreurs selon error.name : c’est leur identifiant stable, exploitable par votre code.
  • Une valeur de paramètre d’URL invalide sur une méthode GET (par exemple offset=abc) peut être rejetée avant l’exécution de la méthode. Vérifiez le statut HTTP : toutes les erreurs ne suivent pas forcément l’enveloppe ci-dessus. Respectez les types attendus pour les paramètres d’URL.

Les montants

  • Les montants en crypto sont des chaînes décimales exprimées dans l’unité de l’actif ("10.5") — jamais des nombres JSON. Les réponses portent aussi amount_minor (extension) : la valeur entière en unités mineures sous forme de chaîne, car les grands entiers exprimés en wei peuvent dépasser la précision entière exacte d’un Number JavaScript.
  • Les decimals par actif viennent de getCurrencies — pilotez vos calculs de montants à partir de là plutôt que de les coder en dur.
  • Les montants en monnaie fiduciaire ont au plus 2 décimales.
  • Les taux sont des chaînes à virgule fixe, jamais des nombres.

La pagination

Les méthodes de liste (getInvoices, getChecks, getTransfers, getSubscriptions) prennent offset (défaut 0) et count (défaut 100, maximum 1000 ; getSubscriptions maximum 500) et renvoient {"items": […]}, les plus récents d’abord. Les filtres d’identifiants (invoice_ids, check_ids, transfer_ids) sont des listes d’entiers séparées par des virgules. Les horodatages sont partout des chaînes ISO 8601.

L’idempotence : spend_id

Les méthodes qui déplacent de l’argent prennent une clé spend_id générée par l’appelant (1 à 64 caractères) : requise sur transfer et sur chaque élément de transferBatch, facultative sur createCheck et refundInvoice (extension — utilisez-la quand même). Réessayer avec la même clé et les mêmes paramètres renvoie le résultat d’origine sans déplacer les fonds deux fois : vous pouvez donc réessayer une requête dont le délai de réponse a été dépassé. La même clé avec des paramètres différents renvoie 409 idempotency_conflict ; une nouvelle tentative pendant que la requête d’origine s’exécute encore renvoie 409 idempotency_in_progress.

Les limites de débit

Par application, partagées entre tous ses tokens ; un dépassement renvoie 429 rate_limited :

MéthodeLimite
createInvoice, createCheck60 par minute
refundInvoice30 par minute
transfer30 par minute
transferBatch10 par minute
updateApp10 par minute
createSubscriptionPlan20 par minute

D’autres limites de requêtes peuvent s’appliquer. En cas de 429 rate_limited, augmentez le délai avant de réessayer. Pendant une maintenance de la plateforme, les méthodes d’écriture renvoient 503 maintenance tandis que les lectures continuent de fonctionner.

Méthodes de catalogue et de compte

getMe

GET /pay/api/getMe — aucun paramètre. Renvoie l’identité de l’application : app_id, name, payment_processing_bot_username, webhook_url, webhook_events (les types de webhook étendus auxquels l’application s’est abonnée), les champs d’introspection du token scopes / token_name décrits plus haut, et payout_mode (off / allowlist / any), daily_payout_max_usd_cents (0 = aucune limite définie par le propriétaire) et daily_payout_spent_usd_cents (montant utilisé sur les 24 heures glissantes).

updateApp

POST /pay/api/updateApp — permission webhooks. Paramètres facultatifs : name (1 à 64 caractères), webhook_url (une URL HTTPS publique ; une chaîne vide la supprime) et webhook_events (tableau ou liste séparée par des virgules des noms d’événements supplémentaires pris en charge). Une liste vide ne conserve que invoice_paid. Renvoie les mêmes champs d’application que getMe.

getBalance

GET /pay/api/getBalance — aucun paramètre. Renvoie un tableau avec une ligne par actif pris en charge, même à zéro : currency_code, available (solde disponible), onhold (fonds des chèques non récupérés et paiements vers des @username en attente) et amount_minor.

getCurrencies

GET /pay/api/getCurrencies — aucun paramètre. La liste qui fait foi de ce que l’API prend en charge : les lignes crypto (is_blockchain: true) et les monnaies fiduciaires dans lesquelles les factures peuvent être libellées (is_fiat: true). Chaque ligne porte code, name, decimals et l’indicateur is_stablecoin.

getExchangeRates

GET /pay/api/getExchangeRates — aucun paramètre. Les cotations crypto-vers-fiat : source, target, rate (une chaîne à virgule fixe) et is_valid. Ces taux sont indicatifs. La valeur is_valid: true ne garantit pas qu’une cotation soit récente. Si les taux ne peuvent pas être obtenus, le résultat peut être un tableau vide. Pour rapprocher un paiement réel dans votre comptabilité, utilisez les montants et les taux enregistrés sur la facture.

getStats

GET /pay/api/getStats — start_at / end_at facultatifs (ISO 8601 ; la fenêtre par défaut est les dernières 24 heures). Renvoie volume (valeur en dollars des factures payées pendant cette période, estimée aux taux actuels ; les actifs sans cours disponible comptent pour zéro), conversion (payées/créées, en pourcentage), unique_users_count, created_invoice_count, paid_invoice_count, et les bornes effectives de la fenêtre. Une date illisible renvoie 400 invalid_date.

Erreurs que toute méthode peut renvoyer

HTTPerror.nameQuand
401unauthorizedtoken absent, invalide ou révoqué
403scope_requiredle token n’a pas la permission de la méthode
403payouts_disabledle mode de paiement sortant de l’application est off (méthodes de paiement sortant uniquement)
403recipient_not_allowedle destinataire n’est pas dans la liste de destinataires de l’application (méthodes de paiement sortant uniquement)
400invalid_requestparamètres illisibles ou invalides (POST)
403daily_cap_exceededla limite quotidienne de paiements sortants de l’application serait dépassée
403verification_requiredles opérations sortantes du propriétaire sont restreintes ; concerne les transferts, les chèques et les remboursements
503merchant_payouts_pausedles débits du solde de l’application sont temporairement suspendus
429rate_limitedlimite de débit dépassée
503maintenancemaintenance de la plateforme (méthodes d’écriture)
500internal_errorerreur serveur inattendue

Les erreurs propres à chaque méthode sont listées sur sa page.

Erreurs sans l’enveloppe JSON

Une erreur en texte brut ou en HTML ne permet pas, à elle seule, de savoir quelle couche l’a renvoyée. Vérifiez le statut HTTP, le corps et les en-têtes de la réponse.

Si Cloudflare renvoie error code: 1010, le client a été rejeté d’après la signature de son navigateur, avant que la requête n’atteigne l’API. Les permissions du jeton ne sont pas la cause de cette erreur Cloudflare. Un User-Agent absent ou non standard peut déclencher la protection réseau. Essayez un en-tête User-Agent qui identifie votre client, par exemple MyShop/1.0, puis réessayez la requête ; cela ne garantit pas la résolution du problème. Si l’erreur persiste, envoyez au support le statut HTTP, le corps et les en-têtes de la réponse, après avoir retiré les jetons et les cookies.