Compose a createInvoiceLink payload for Telegram Stars or a traditional card provider, with every limit checked as you type. The trap this page exists for is amount units: 1 means one star, 100 means one dollar, and 250 means two hundred and fifty yen. The live total is always rendered in the units the invoice will actually charge.
Your own opaque identifier — Telegram never shows it and hands it straight back on pre_checkout_query and successful_payment. The limit is 128 bytes, not 128 characters, so Cyrillic or emoji cost two to four bytes each.
{{ unitNote }}
is_flexible means the final price depends on the shipping address, so your bot must answer shipping_query. It is independent of max_tip_amount — tips work with or without it.
Tipping, name/phone/email collection, shipping and is_flexible are not supported for payments in Telegram Stars, so those fields are omitted here rather than shown greyed out. Stars invoices carry no billing details at all — Telegram handles the whole checkout.
Paste the JSON parameters you send to createInvoiceLink, or a whole cURL / Node.js / Python / PHP snippet containing them — the first complete JSON object in the text is used.
What cannot be decoded here: the https://t.me/$… link that createInvoiceLink returns is an opaque server-side handle with no client-readable contents, and a bare invoice_payload string is whatever bytes your own bot chose. Neither carries the invoice, so this tab does not pretend to parse them.
{{ form.title || 'Untitled invoice' }}
{{ form.description || 'No description yet.' }}
That photo_url did not load in this browser. Telegram fetches it server-side, so a URL behind auth or hotlink protection fails there too.
Layout is indicative. Telegram renders the real invoice; what matters here is that the numbers read the way they will charge.
Title, description, payload bytes, prices and provider rules all check out for this mode.
{{ payloadJson }}Paste createInvoiceLink parameters on the left.
{{ decoded.reason }}
| Field | Value |
|---|---|
| {{ row.key }} | {{ row.value }} |
{{ decodedTotalLabel }}
Every rule this tool knows about passes for the pasted parameters.
createInvoiceLink in {{ activeLang.label }}. The response's result is the link you send to the buyer. {{ exportedCode }}createInvoiceLink has roughly twenty parameters and two mutually exclusive modes, and almost every hour lost to it is lost to the same thing: amount units. Amounts are always integers in the currency's smallest unit. For traditional currencies that means amount: 100 is $1.00, not one hundred dollars. For zero-decimal currencies such as JPY the smallest unit is the currency, so amount: 250 is ¥250 — writing 25000 because "it worked for USD" charges a hundred times too much. For Telegram Stars there is no minor unit either: amount: 250 is 250 ⭐. This page keeps a per-currency exponent table and renders the running total in real units so the mistake is visible before it reaches a buyer.
The second recurring trap is payload. It is your own opaque string, returned to you untouched on pre_checkout_query and successful_payment, and its limit is 1–128 bytes. A .length check passes on a Cyrillic or emoji payload that Telegram then rejects, because UTF-8 spends two to four bytes per such character. The counter here measures encoded bytes.
Stars versus card is not a cosmetic switch. Stars invoices use currency: "XTR", carry no provider_token, must contain exactly one price line, and support none of the billing-detail flags — no tipping, no name, phone, email or shipping address, no is_flexible. Card invoices need a provider_token from @BotFather and may use all of them. Those are separate tabs here so the unsupported fields are absent rather than greyed out, and the Decode tab cross-checks a pasted payload for the mismatch in both directions.
Whatever createInvoiceLink returns is an opaque https://t.me/$… handle. There is nothing inside it to decode in a browser, so the Decode tab works on the parameters you send, not on the link you get back.
Companion tools: compose the message that carries the invoice button with Telegram Studio, and verify the pre_checkout_query and successful_payment updates that come back with Telegram Webhook Tester.
Privacy: 100% client-side. Nothing is submitted anywhere and no provider token is transmitted — it is only interpolated into the snippet shown on screen. The single exception is the optional photo_url: previewing it loads that image directly from the address you typed, exactly as your browser would for any image.