Referência da API para comerciantes
As convenções que todos os métodos compartilham, mais os métodos de catálogo somente leitura. Páginas método a método: faturas e reembolsos, transferências e cheques, assinaturas, webhooks.
A API segue as convenções do Crypto Bot nos métodos documentados aqui. Altere a URL base e o token, depois teste na testnet os métodos usados pela sua integração. Nossas adições estão marcadas como extensão abaixo.
Uma especificação OpenAPI 3.1 legível por máquina também está disponível: crypto-pay-openapi.yaml · crypto-pay-openapi.json. Use com geradores de código, clientes de API ou suas ferramentas de IA, mas consulte também as páginas dos métodos: o esquema pode ainda não incluir extensões mais recentes.
URL base e autenticação
Todos os métodos ficam em https://app.tgpaycrypto.com/pay/api/<methodName>.
Na testnet, a base é
https://testnet.tgpaycrypto.com/pay/api — apps e tokens separados, fundos de teste
sem valor real.
Autentique cada requisição com o token no cabeçalho TgPayCrypto-API-Token
(TgCryptoPay-API-Token, o nome usado antes de 07/09/2026, e
Crypto-Pay-API-Token são aceitos como aliases de compatibilidade; se vários
forem enviados, vale o canônico). Um token ausente, inválido ou revogado, um token restrito expirado, um token de um app excluído ou cujo proprietário esteja bloqueado retorna 401 unauthorized.
O token tem o formato <app_id>:<secret> e é mostrado uma vez, na criação ou na
rotação; o servidor guarda só o hash dele. Veja
primeiros passos para desenvolvedores.
Tokens e escopos
Dois tipos de credencial autenticam do mesmo jeito:
- O token principal — acesso total a todos os métodos, e a única chave que assina webhooks.
- Os tokens restritos (extensão) — até 10 tokens não revogados por app, incluindo os expirados. Abra Mais → API para comerciantes, escolha o app e abra Acesso e tokens. Crie os tokens em Tokens restritos, cada um com uma etiqueta e um subconjunto de escopos. Revogar um é instantâneo e não mexe nos outros; rotacionar o token principal também não mexe neles. Um token também pode ter uma data de expiração, após a qual deixa de autenticar requisições.
| Escopo | Métodos que ele libera |
|---|---|
| (qualquer token válido) | getMe, getCurrencies, getExchangeRates |
read | getBalance, getStats, getInvoices, getChecks, getTransfers, getSubscriptionPlans, getSubscriptions |
invoices | createInvoice, deleteInvoice |
refunds | refundInvoice |
payouts | transfer, transferBatch |
checks | createCheck, deleteCheck |
subscriptions | createSubscriptionPlan, archiveSubscriptionPlan, cancelSubscription |
webhooks | updateApp |
Os escopos são cumulativos e independentes — invoices não implica read, então
um servidor que só cria faturas pode usar um token sem acesso aos saldos ou ao histórico de pagamentos. Chamar um
método que o token não cobre devolve 403 scope_required. O getMe informa os
scopes do token atual (null para o token principal) e o token_name, então
você sempre consegue conferir o que tem em mãos.
Modo de pagamentos
Um escopo diz quais métodos um token pode chamar; o modo de pagamentos do
app diz para quem qualquer token dele — inclusive o principal — pode pagar. Um
app novo paga qualquer pessoa desde o primeiro minuto; o dono pode restringir
isso em Mais → API para comerciantes, abrindo o app e depois
Configurações de pagamentos → Pagamentos pela API. Assim como o limite diário,
essa opção limita o que alguém pode fazer com um token vazado. Para reduzir a
restrição, é preciso o PIN ou a biometria; a API só consegue ler o modo (getMe →
payout_mode).
payout_mode | O que transfer, transferBatch e createCheck podem fazer |
|---|---|
any | pagar qualquer usuário, deixar em escrow um pagamento para um @username desconhecido, criar cheques ao portador — o padrão, e o comportamento do Crypto Bot |
allowlist | pagar apenas usuários do Telegram autorizados na lista do app. Todo destinatário definido individualmente ou na lista de um cheque precisa estar autorizado. Outros destinatários, @usernames desconhecidos e cheques ao portador recebem 403 recipient_not_allowed |
off | nada — toda chamada de pagamento devolve 403 payouts_disabled; faturas, assinaturas, reembolsos e webhooks funcionam normalmente |
Se um pagamento é rejeitado, o dono recebe um aviso no Telegram e pode mudar o modo. O limite diário de pagamentos se aplica além do modo. Os fins permitidos para esses pagamentos estão nos termos da API para comerciantes.
Requisições e respostas
- Os métodos de leitura são
GET, com parâmetros na query string. Os métodos que movimentam dinheiro são apenasPOST— parâmetros como corpo JSON, form-urlencoded ou query params (em caso de conflito, vale o corpo);multipart/form-dataé rejeitado. - As respostas geradas pelos handlers da API usam um envelope JSON: sucesso
{"ok": true, "result": …}, erro{"ok": false, "error": {"code": <HTTP status>, "name": "<error_name>"}}. Faça a lógica peloerror.name— ele é a string estável legível por máquina. - Um parâmetro de query com tipo inválido em um método GET (por exemplo,
offset=abc) pode ser rejeitado antes de chegar ao handler da API. Verifique o status HTTP e não presuma que toda resposta de erro tenha o envelope acima. Envie os parâmetros de query com os tipos esperados.
Valores
- Os valores em cripto são strings decimais em unidades do ativo
(
"10.5") — nunca números JSON. As respostas também trazemamount_minor(extensão): o valor inteiro em unidades menores, como string, porque inteiros na escala de wei podem ultrapassar a precisão exata de umNumberdo JavaScript. - Os
decimalsde cada ativo vêm dogetCurrencies— baseie sua matemática de valores nisso, em vez de fixar no código. - Os valores em moeda fiduciária têm no máximo 2 casas decimais.
- As cotações são strings de ponto fixo, nunca números.
Paginação
Os métodos de lista (getInvoices, getChecks, getTransfers,
getSubscriptions) aceitam offset (padrão 0) e count (padrão 100, máx.
1000; getSubscriptions máx. 500) e devolvem {"items": […]}, dos mais novos
para os mais antigos. Os filtros por ID (invoice_ids, check_ids,
transfer_ids) são listas de inteiros separadas por vírgula. Os carimbos de
tempo, em toda a API, são strings ISO 8601.
Idempotência: spend_id
Os métodos que movimentam dinheiro aceitam uma chave spend_id gerada por
quem chama (de 1 a 64 caracteres): obrigatória no transfer e em cada item do
transferBatch, opcional no createCheck e no refundInvoice (extensão — use
mesmo assim). Repetir com a mesma chave e os mesmos parâmetros repete o resultado
original em vez de mover fundos duas vezes, então uma requisição que deu timeout
sempre pode ser repetida com segurança. A mesma chave com parâmetros
diferentes devolve 409 idempotency_conflict; uma nova tentativa enquanto a
original ainda está executando devolve 409 idempotency_in_progress.
Limites de requisições
Por app, compartilhados entre todos os tokens dele; ultrapassar devolve
429 rate_limited:
| Método | Limite |
|---|---|
createInvoice, createCheck | 60 por minuto |
refundInvoice | 30 por minuto |
transfer | 30 por minuto |
transferBatch | 10 por minuto |
updateApp | 10 por minuto |
createSubscriptionPlan | 20 por minuto |
Outros limites de requisições podem se aplicar. Ao receber 429 rate_limited,
aumente o intervalo antes de tentar novamente. Durante manutenções da plataforma, os
métodos de escrita devolvem 503 maintenance enquanto os de leitura continuam
funcionando.
Métodos de catálogo e de conta
getMe
GET /pay/api/getMe — sem parâmetros. Devolve a identidade do app: app_id,
name, payment_processing_bot_username, webhook_url, webhook_events (os
tipos de webhook estendidos que o app ativou), os campos de introspecção do
token scopes / token_name descritos acima e payout_mode (off /
allowlist / any), daily_payout_max_usd_cents (0 = sem limite definido pelo proprietário) e daily_payout_spent_usd_cents (gastos nas últimas 24 horas).
updateApp
POST /pay/api/updateApp — escopo webhooks. Parâmetros opcionais: name (de 1 a 64 caracteres), webhook_url (uma URL HTTPS pública; uma string vazia a remove) e webhook_events (array ou lista separada por vírgulas com nomes de eventos adicionais disponíveis). Uma lista de eventos vazia mantém apenas invoice_paid. Retorna os mesmos campos do app que getMe.
getBalance
GET /pay/api/getBalance — sem parâmetros. Devolve um array com uma linha por
ativo suportado, mesmo zerado: currency_code, available (saldo que dá para
gastar), onhold (fundos de cheques não resgatados e pagamentos pendentes para @username) e
amount_minor.
getCurrencies
GET /pay/api/getCurrencies — sem parâmetros. A lista oficial do que a API
suporta: linhas de cripto (is_blockchain: true) e as moedas fiduciárias em que
as faturas podem ser precificadas (is_fiat: true). Cada linha traz code,
name, decimals e a flag is_stablecoin.
getExchangeRates
GET /pay/api/getExchangeRates — sem parâmetros. Cotações de cripto para moeda
fiduciária: source, target, rate (uma string de ponto fixo) e is_valid. Trate essas cotações como indicativas. O campo is_valid: true não garante que uma cotação esteja atualizada. Se não for possível obter as cotações, o resultado pode ser um array vazio. Para conferir um pagamento efetivo, use os valores e as cotações registrados na fatura.
getStats
GET /pay/api/getStats — start_at / end_at opcionais (ISO 8601; a janela
padrão são as últimas 24 horas). Devolve volume (valor em dólares das faturas
pagas no período, estimado pelas cotações atuais; ativos sem cotação contam como zero), conversion (pagas/criadas, em porcentagem),
unique_users_count, created_invoice_count, paid_invoice_count e os limites
efetivos da janela. Uma data que não dá para interpretar devolve
400 invalid_date.
Erros que todo método pode devolver
| HTTP | error.name | Quando |
|---|---|---|
| 401 | unauthorized | token ausente, inválido ou revogado |
| 403 | scope_required | o token não tem o escopo do método |
| 403 | payouts_disabled | o modo de pagamentos do app é off (só métodos de pagamento) |
| 403 | recipient_not_allowed | quem recebe não está na lista de destinatários do app (só métodos de pagamento) |
| 400 | invalid_request | parâmetros inválidos ou impossíveis de interpretar (POST) |
| 403 | daily_cap_exceeded | o limite diário de pagamentos do app seria excedido |
| 403 | verification_required | as operações de saída do proprietário estão restritas; afeta transferências, cheques e reembolsos |
| 503 | merchant_payouts_paused | débitos no saldo do app estão temporariamente pausados |
| 429 | rate_limited | limite de requisições ultrapassado |
| 503 | maintenance | manutenção da plataforma (métodos de escrita) |
| 500 | internal_error | erro inesperado do servidor |
Os erros específicos de cada método estão na página do método.
Erros sem o formato JSON
Uma resposta de erro em texto simples ou HTML, por si só, não identifica em que camada o erro ocorreu. Confira o status HTTP, o corpo e os cabeçalhos da resposta.
Se a Cloudflare retornar error code: 1010, ela rejeitou o cliente pela assinatura do navegador antes que a solicitação chegasse à API. Os escopos do token não são a causa desse erro da Cloudflare. Um User-Agent ausente ou fora do padrão pode acionar a proteção de rede. Tente enviar um cabeçalho User-Agent que identifique seu cliente, como MyShop/1.0, e repita a solicitação; isso não garante a solução. Se o erro continuar, envie ao suporte o status HTTP, o corpo e os cabeçalhos da resposta, removendo tokens e cookies.
Este artigo foi útil?
Obrigado pelo retorno.