Skip to content

sendInvoice

Use this method to send invoices. On success, the sent Message is returned.

Parameters

chat_idIntegerStringRequired
Unique identifier for the target chat or username of the target channel (in the format @channelusername)
message_thread_idIntegerOptional
Unique identifier for the target message thread (topic) of a forum; for forum supergroups and private chats of bots with forum topic mode enabled only
direct_messages_topic_idIntegerOptional
Identifier of the direct messages topic to which the message will be sent; required if the message is sent to a direct messages chat
titleStringRequiredminLen 1maxLen 32
Product name, 1-32 characters
descriptionStringRequiredminLen 1maxLen 255
Product description, 1-255 characters
payloadStringRequired
Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, use it for your internal processes.
provider_tokenStringOptional
Payment provider token, obtained via @BotFather. Pass an empty string for payments in Telegram Stars.
currencyCurrenciesRequired
Three-letter ISO 4217 currency code, see more on currencies. Pass "XTR" for payments in Telegram Stars.
pricesLabeledPrice[]Required
Price breakdown, a JSON-serialized list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.). Must contain exactly one item for payments in Telegram Stars.
max_tip_amountIntegerOptional Default: 0
The maximum accepted amount for tips in the smallest units of the currency (integer, not float/double). For example, for a maximum tip of US$ 1.45 pass maxtipamount = 145. See the exp parameter in currencies.json, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). Defaults to 0. Not supported for payments in Telegram Stars.
suggested_tip_amountsInteger[]Optional
A JSON-serialized array of suggested amounts of tips in the smallest units of the currency (integer, not float/double). At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max\tip\amount.
start_parameterStringOptional
Unique deep-linking parameter. If left empty, forwarded copies of the sent message will have a Pay button, allowing multiple users to pay directly from the forwarded message, using the same invoice. If non-empty, forwarded copies of the sent message will have a URL button with a deep link to the bot (instead of a Pay button), with the value used as the start parameter
provider_dataStringOptional
JSON-serialized data about the invoice, which will be shared with the payment provider. A detailed description of required fields should be provided by the payment provider.
photo_urlStringOptional
URL of the product photo for the invoice. Can be a photo of the goods or a marketing image for a service. People like it better when they see what they are paying for.
photo_sizeIntegerOptional
Photo size in bytes
photo_widthIntegerOptional
Photo width
photo_heightIntegerOptional
Photo height
need_nameBooleanOptional
Pass True if you require the user's full name to complete the order. Ignored for payments in Telegram Stars.
need_phone_numberBooleanOptional
Pass True if you require the user's phone number to complete the order. Ignored for payments in Telegram Stars.
need_emailBooleanOptional
Pass True if you require the user's email address to complete the order. Ignored for payments in Telegram Stars.
need_shipping_addressBooleanOptional
Pass True if you require the user's shipping address to complete the order. Ignored for payments in Telegram Stars.
send_phone_number_to_providerBooleanOptional
Pass True if the user's phone number should be sent to the provider. Ignored for payments in Telegram Stars.
send_email_to_providerBooleanOptional
Pass True if the user's email address should be sent to the provider. Ignored for payments in Telegram Stars.
is_flexibleBooleanOptional
Pass True if the final price depends on the shipping method. Ignored for payments in Telegram Stars.
disable_notificationBooleanOptional
Sends the message silently. Users will receive a notification with no sound.
protect_contentBooleanOptional
Protects the contents of the sent message from forwarding and saving
allow_paid_broadcastBooleanOptional
Pass True to allow up to 1000 messages per second, ignoring broadcasting limits for a fee of 0.1 Telegram Stars per message. The relevant Stars will be withdrawn from the bot's balance
message_effect_idStringOptional
Unique identifier of the message effect to be added to the message; for private chats only
suggested_post_parametersSuggestedPostParametersOptional
A JSON-serialized object containing the parameters of the suggested post to send; for direct messages chats only. If the message is sent as a reply to another suggested post, then that suggested post is automatically declined.
reply_parametersReplyParametersOptional
Description of the message to reply to
A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button will be shown. If not empty, the first button must be a Pay button.

Returns

On success, the Message object is returned.

GramIO Usage

ts
// Send a Telegram Stars invoice (no provider_token needed)
bot
.
command
("buy", (
ctx
) =>
ctx
.
sendInvoice
({
title
: "Premium Access",
description
: "Unlock all premium features for 30 days",
payload
: "premium_30d",
currency
: "XTR",
prices
: [{
label
: "Premium (30 days)",
amount
: 100 }],
}) );
ts
// Send an invoice with fiat currency and tipping options
bot
.
command
("donate", (
ctx
) =>
ctx
.
sendInvoice
({
title
: "Support the project",
description
: "Help us keep the bot running",
payload
: `donation_${
ctx
.
from
?.
id
}`,
provider_token
: "PROVIDER_TOKEN_FROM_BOTFATHER",
currency
: "USD",
// Prices are in smallest units: 100 = $1.00
prices
: [{
label
: "Donation",
amount
: 500 }],
max_tip_amount
: 1000,
suggested_tip_amounts
: [100, 300, 500, 1000],
}) );
ts
// Handle pre-checkout: MUST answer within 10 seconds
bot
.
on
("pre_checkout_query", async (
ctx
) => {
// Validate the order (check stock, verify payload, etc.) const
isValid
=
ctx
.
payload
.
invoice_payload
.
startsWith
("premium_");
if (
isValid
) {
await
bot
.
api
.
answerPreCheckoutQuery
({
pre_checkout_query_id
:
ctx
.
payload
.
id
,
ok
: true,
}); } else { await
bot
.
api
.
answerPreCheckoutQuery
({
pre_checkout_query_id
:
ctx
.
payload
.
id
,
ok
: false,
error_message
: "This product is no longer available.",
}); } });
ts
// Handle successful payment
bot
.
on
("message", (
ctx
) => {
if (!
ctx
.
payload
.
successful_payment
) return;
const
payment
=
ctx
.
payload
.
successful_payment
;
// payment.telegram_payment_charge_id — save for refund support // payment.invoice_payload — your bot-defined identifier return
ctx
.
send
(`✅ Payment received! Order: ${
payment
.
invoice_payload
}`);
});
ts
// Direct API call — send invoice to a channel
await 
bot
.
api
.
sendInvoice
({
chat_id
: "@mychannel",
title
: "Channel Subscription",
description
: "Support the channel with a Stars donation",
payload
: "channel_sub",
currency
: "XTR",
prices
: [{
label
: "Subscription",
amount
: 50 }],
});

Errors

CodeErrorCause
400Bad Request: chat not foundchat_id is invalid or the bot has no access
400Bad Request: CURRENCY_INVALIDcurrency code is not in the supported list
400Bad Request: INVOICE_PAYLOAD_INVALIDpayload is empty or exceeds 128 bytes
400Bad Request: prices must be non-emptyprices array is empty — at least one LabeledPrice is required
400Bad Request: XTR invoices must have exactly one priceFor currency: "XTR", the prices array must contain exactly one item
400Bad Request: provider_token is requiredNon-XTR currencies need a provider_token from BotFather
400Bad Request: TITLE_INVALIDtitle is empty or longer than 32 characters
400Bad Request: DESCRIPTION_INVALIDdescription is empty or longer than 255 characters
403Forbidden: bot was blocked by the userUser blocked the bot — catch and mark as inactive
429Too Many Requests: retry after NRate limit hit — check retry_after, use auto-retry plugin

TIP

Use GramIO's auto-retry plugin to handle 429 errors automatically.

Tips & Gotchas

  • For Telegram Stars (currency: "XTR"), omit provider_token. Pass an empty string "" or simply omit it. Stars payments don't go through an external provider.
  • XTR invoices must have exactly one price item. The prices array must contain a single LabeledPrice. Multiple items cause a 400 error.
  • Prices are in the smallest currency unit. For USD, amount: 100 = $1.00 (cents). For XTR (Stars), amount: 50 = 50 Stars. Check the exp field in currencies.json.
  • You MUST answer pre_checkout_query within 10 seconds. Failure to call answerPreCheckoutQuery in time causes the payment to fail on the user's side — always handle this event promptly.
  • The payload is your order identifier — store it. Use payload to link the payment to your internal order. It's returned in both pre_checkout_query and successful_payment events.
  • need_name, need_email, etc. are silently ignored for XTR payments. These data-collection flags only apply to fiat currency payments with a provider token.
  • If start_parameter is empty, forwarded invoices remain payable. Setting a start_parameter converts the Pay button in forwarded copies to a deep link, preventing others from paying the same forwarded invoice.

See Also