tgpay cryptoAPI
crypto-payapitokenapp

Getting started as a developer

4 min readUpdated Oct 9, 2026

Create an app in the Mini App, copy its API token once, and start calling the API. The whole setup lives under More → Merchant API.

Steps

  1. Open More → Merchant API and choose Create app.
  2. Enter an App name (e.g. “My Store”) and, optionally, a Webhook URL (optional).
  3. Accept the terms on the form and tap Create app. Confirm with your PIN or biometrics when prompted. Creating an app accepts the Merchant API terms — what you may and may not use the API for.
  4. Copy the API token immediately. It’s shown once and never again — the app stores only a hash of it.
  5. Send your first request with the token in the TgPayCrypto-API-Token header.
The Merchant API screen: create an app to get an API token

Your first call

Point your client at the API base https://app.tgpaycrypto.com/pay/api and call getMe to confirm the token works. getBalance returns your app’s balances, getCurrencies the assets you can use.

Read methods are GET. Write methods, such as createInvoice, transfer, createCheck, deleteInvoice and deleteCheck, are POST only. Parameters may be sent as a JSON body, form-urlencoded, or query params. Prefer a request body so amounts and idempotency keys stay out of URL access logs.

Testnet

Build against the test network first — same API, same Mini App, test funds with no value:

MainnetTestnet
Bot@tgpaycryptobot@tgpaycrypto_testnet_bot
API basehttps://app.tgpaycrypto.com/pay/apihttps://testnet.tgpaycrypto.com/pay/api
MCP serverhttps://app.tgpaycrypto.com/mcphttps://testnet.tgpaycrypto.com/mcp

Apps and tokens are separate: a testnet token does not work on mainnet, and vice versa. To get test funds, open the testnet Mini App and tap Get test coins on the home screen. The faucet credits a test pack as ordinary deposits; assets on disabled networks are skipped. The app shows what was credited and when another request is allowed. You can use a second Telegram account as the customer who pays your test invoices.

Deposits and withdrawals use simulated custody, without real blockchain transactions. Never send real funds to a testnet deposit address. The API contract is shared, but available features, rates and limits can differ from mainnet. When you’re done, create a production app in @tgpaycryptobot and switch the base URL.

Managing an app

Open an app in Merchant API to see its app ID and balance. From there you can:

  • Set or change the webhook URL under Webhook and save it.
  • Pick extra webhook events — the Extra webhook events toggles in the Webhook section select event types beyond invoice_paid (see the webhooks reference).
  • Narrow who the API may pay — under Payout settings, Payouts through the API is Any user for a new app; switch it to Listed users only (and list the recipients) or Off if your integration never pays people — a fence in case the token leaks (see payout mode).
  • Create restricted tokens — open Access and tokens for extra API tokens under Restricted tokens, each limited to the scopes you pick (see the API reference).
  • Rotate token — under Access and tokens, issues a new token and instantly invalidates the old one. Use this if a token leaked; the new one is shown once, same as at creation.
  • Delete — first pay out the available balance; otherwise deletion is rejected with app_has_balance. Also resolve outstanding checks and pending payouts before deleting. The app leaves the list and its tokens stop working; its payment history is retained.

Webhooks

If you set a webhook URL, the app POSTs a signed JSON body to it:

{ "update_id": …, "update_type": "invoice_paid", "request_date": …, "payload": { … } }

The signature is in the TgPayCrypto-API-Signature header (with TgCryptoPay-API-Signature and Crypto-Pay-API-Signature as compat aliases): HMAC-SHA256 over the raw body, keyed by the SHA-256 of your main API token. Verify it before trusting anything in the payload.

Deliveries are retried with exponential backoff over an extended period, and update_id stays the same across retries — key your deduplication on it and make your handler idempotent.

invoice_paid needs no separate opt-in when a webhook URL is configured. Other event types — expired invoices, claimed checks, refunds, subscription events — are opt-in via the Extra webhook events toggles. The full list, payload shapes, and retry behavior are in the webhooks reference.

⚠️ Guard the token like a private key

It authorizes payouts from your app balance. Keep it on your server, never in a mobile app, front-end bundle or committed config. If you’re unsure whether it leaked, rotate it — rotation is instant and costs nothing. And give each server only what it needs: a restricted token with only the invoices scope can create and delete invoices, but cannot transfer funds, create checks or issue refunds.