TG Crypto PayTG Crypto PayHelp Center
#crypto-pay#invoices#api#webhook

Accepting payments with invoices

2 min readUpdated Aug 7, 2026

An invoice is how you charge a Telegram user. You create one through the API, send the payer its link, and your app balance is credited the instant they confirm.

The flow

  1. Create the invoice with createInvoice, giving an asset and amount (or a fiat price — see below).
  2. Send the payer the link from the response. Opening it takes them to the Pay screen in the app.
  3. They confirm and pay from their balance — instantly, with no network fee.
  4. You’re notified. The invoice_paid webhook fires, and the amount lands in your app balance.
  5. Fulfil the order. Don’t wait for anything else; the payment is final at that point.

If you’d rather poll than take a webhook, getInvoices returns your invoices with their current status. The webhook is the faster path — polling is the fallback.

Pricing in fiat

An invoice can be priced in crypto, or in a fiat currency with a list of accepted assets. The payer then settles in whichever accepted asset they hold, converted at the rate at payment time. That’s the usual choice for a shop whose catalogue is denominated in a real-world currency.

You can also set swap_to so incoming payments are converted into a single asset as they arrive — useful for keeping your balance in a stablecoin without running the swaps yourself.

Useful invoice options

  • description — shown to the payer on the Pay screen.
  • hidden_message — revealed to the payer only after they pay. This is how you deliver a code, a key or a link without a separate delivery channel.
  • payload — your own opaque string, echoed back on the webhook. Put your order ID here.
  • expires_in — a time limit, after which the invoice can no longer be paid.
  • paid_btn_name / paid_btn_url — the button the payer sees after paying, to send them back to your bot, channel or item page.

An unpaid invoice can be withdrawn with deleteInvoice.

Refunds

refundInvoice returns a paid invoice’s full face amount from your app balance to whoever paid it — including anonymous payers, without revealing who they were. It’s full-amount only and can be done once per invoice; the platform fee stays charged.

⚠️ Verify the webhook signature before you fulfil

Anyone can POST to your webhook URL. Check the TgCryptoPay-API-Signature header — HMAC-SHA256 over the raw request body, keyed by the SHA-256 of your API token — before you treat a payment as real, and dedupe on update_id so a retry doesn’t ship the order twice.