Accept Telegram Stars Inside a Mini App
A Mini App cannot charge a card on iOS. It can open a Stars invoice. You create the link on your server with currency XTR, call WebApp.openInvoice, and fulfill the order only after your bot receives successful_payment.
Key takeaways
- Never create the invoice in the Mini App. Call your server, which calls createInvoiceLink with currency XTR and an empty provider token.
- Open the sheet with Telegram.WebApp.openInvoice(url, callback). The callback status is not proof of payment.
- Fulfill the order from the bot update successful_payment, and store telegram_payment_charge_id.
- If you only need a link, a file or a channel membership, Telegram Stars Payment Platform already does this and sends you a webhook.
The flow that actually gets you paid
- The Mini App asks your backend for an invoice for a known product ID. Do not trust a price sent by the client.
- The backend calls
createInvoiceLinkwithcurrency: "XTR". - The Mini App passes that URL to
Telegram.WebApp.openInvoice. - Telegram shows the native sheet. The user pays or cancels.
- Your bot receives
pre_checkout_query(answer within 10 seconds) and thensuccessful_payment. - Only then do you unlock the item, credit the balance, or mark the order paid.
Create the link on the server
Stars invoices use one price line. The amount is the number of Stars, not cents. provider_token stays empty.
const link = await bot.api.createInvoiceLink(
"Extra lives",
"5 extra lives in this Mini App",
orderId, // payload, 1–128 bytes, your order id
"", // provider_token empty for XTR
"XTR",
[{ label: "Extra lives", amount: 50 }],
);
Full parameter notes and the pre-checkout handler are in the Bot API guide.
Open it from the Mini App
const invoiceUrl = await fetch("/api/invoice", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ sku: "lives-5" }),
}).then((r) => r.text());
Telegram.WebApp.openInvoice(invoiceUrl, (status) => {
if (status === "paid") {
// Optimistic UI only. Confirm with your server.
pollOrderUntilPaid();
} else if (status === "cancelled") {
showIdle();
} else {
showFailed();
}
});
Load telegram-web-app.js before this runs, and call Telegram.WebApp.ready(). The invoice URL is a Telegram link. Do not wrap it in your own domain if you want the native sheet; a redirect is fine only if it ends on that URL without an extra interstitial.
Statuses you will see
| openInvoice status | What it means | What to do |
|---|---|---|
| paid | The sheet completed | Poll your server. Unlock when successful_payment is stored. |
| cancelled | The user closed the sheet | Leave the order unpaid. |
| failed | The charge did not go through | Let them retry. Do not unlock. |
| pending | Not finished yet | Keep waiting. Rare for Stars. |
Answer pre_checkout_query
If nobody answers within 10 seconds, Telegram fails the payment and the Mini App sees failed. The handler should check that the order exists and the amount matches, then call answerPreCheckoutQuery. Do not call a slow third party from that handler.
When not to build this
Build a Mini App checkout when the purchase is an item inside a game or a tool the user already has open. Do not build one when the product is a link in a channel bio, an ebook, or a private channel. Those are payment links:
- A reusable or single-use link: payment links.
- A file sent after payment: automatic delivery.
- A 30-day channel: subscriptions.
Telegram Stars Payment Platform exposes a REST API and a webhook for the same ledger, 21-day maturity and TON withdrawal, with a 3% fee. Use that when you want the money movement without operating pre_checkout_query yourself.
Frequently asked questions
Can a Mini App use Stripe on iOS?
Digital goods inside Telegram on iOS and Android are expected to use Stars. A card form for a digital item is what Stars were introduced to replace.
Does openInvoice work on desktop Telegram?
Yes. The same invoice URL opens the native payment sheet on iOS, Android, desktop and Telegram Web.
Where is the payer’s card number?
Nowhere on your server. Stars payments do not hand you card data. You receive the Stars amount, your payload, and telegram_payment_charge_id.
Can the Mini App create the invoice with the bot token?
Do not ship the bot token in the Mini App. Anything in the client can be read. Create the link on the server.
Ready to accept Telegram Stars?
Create a free account, generate a payment link and start receiving Stars today. No code, no monthly fee, 3% per transaction. Get started · see how it works.
Related articles
Telegram Stars Bot API Guide: sendInvoice, XTR, Webhooks, Subscriptions and Refunds
Developer guide to Telegram Stars payments with the Bot API: createInvoiceLink with currency XTR, pre_checkout_query, successful_payment, subscriptions, refundStarPayment and getStarTransactions, with code examples.
Telegram Stars Payment Links: Create One in 60 Seconds Without Coding
What a Telegram Stars payment link is, how it works, how to create one without a bot or code, and how to track clicks and conversions with short redirect links.
How to Accept Telegram Stars Payments: Step-by-Step Guide for Creators and Merchants
Learn how to accept Telegram Stars payments in minutes: with a no-code payment link, through your own bot, or in a Mini App. Fees, payouts to TON and best practices.
Deliver a File Automatically After a Telegram Stars Payment
Sell an ebook, video, audio, photo, HTTPS link or message with Telegram Stars. The file is sent after payment, up to 20 MB.