Payments
Sell digital goods with Telegram Stars, or accept real-world payment providers — invoices, pre-checkout, and refunds.
Telegram bots can charge users two ways: Telegram Stars — Telegram's own in-app currency, no payment provider or bank account needed — or a traditional payment provider (Stripe and others) for real-world currency. Both flows go through the same three Bot API steps: send an invoice, answer the pre-checkout query, then handle the successful payment.
Telegram Stars
Stars are Telegram's built-in currency for digital goods — bot features, premium content, in-app items. There is no provider token, no KYC, and no bank account required: users buy Stars once inside Telegram, then spend them across any bot.
Send a Stars invoice with ctx.replyWithInvoice (or bot.telegram.sendInvoice for a specific chat). The two things that mark it as a Stars invoice: an empty provider_token and currency: 'XTR'.
amount is the number of Stars directly — unlike real currencies, there's no ×100 minor-unit conversion. A price of 100 charges exactly 100 Stars.You can also attach a photo_url to the invoice for a product image, and split prices into multiple line items if you're charging for a bundle — Telegram sums them for the displayed total.
Pre-checkout
Before Telegram charges the user, it sends your bot a pre_checkout_query — your last chance to confirm the order is still valid (stock available, price unchanged) before money moves. You must answer within 10 seconds or the payment is cancelled automatically.
ctx.answerPreCheckoutQuery(true), for every invoice you send.Successful payment
Once the charge clears, Telegram delivers a message containing a successful_payment object. This is where you actually grant whatever was purchased — Telegraf recognises it as a message sub-type, so you can listen for it directly.
Save telegram_payment_charge_id whenever you handle a successful payment — it's the only identifier Telegram accepts later for issuing a refund.
Refunds
Stars purchases can be refunded from your bot with refundStarPayment, using the user's ID and the charge ID you saved from the successful payment. There's no dashboard step — it's a direct API call.
refundStarPayment only applies to Stars (XTR) payments.Provider payments
For real-world currency instead of Stars, get a provider_token from @BotFather (Payments → connect a provider like Stripe) and pass it into the same invoice call, along with a real ISO currency code.
The pre_checkout_query and successful_payment handlers above work identically for provider payments — the only differences are the invoice fields and that amounts are in minor currency units (cents), not whole Stars.
| Telegram Stars | Provider (Stripe, etc.) | |
|---|---|---|
provider_token | Empty string | From @BotFather |
currency | XTR | ISO code, e.g. `USD` |
amount | Whole Stars | Minor units (cents) |
| Refunds | refundStarPayment | Provider's own dashboard/API |
| Setup | None — works immediately | Requires provider approval |