Telegram Bot Payments: A Developer’s Guide to Accepting Payments in Bots
Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.
Telegram bot payments let you sell digital goods, subscriptions, or services directly inside a chat, without redirecting users to a separate checkout page. If you’re building a bot that needs to charge customers, telegram bot payments give you a native invoice UI, built-in provider integration, and a webhook-driven flow that fits naturally into an existing DevOps or automation stack. This guide walks through how the system works, how to set it up correctly, and how to run it reliably in production.
What Are Telegram Bot Payments and How They Work
Telegram bot payments are a built-in feature of the Telegram Bot API that lets a bot send an invoice message to a user, collect shipping and payment details inside the Telegram client, and receive a confirmation once the charge succeeds. Telegram itself never touches the money — it acts as a UI and messaging layer on top of a real payment provider (Stripe, for example, is the most common choice for most regions).
The flow has three moving parts:
Because Telegram sits in the middle, telegram bot payments don’t require you to build a custom checkout UI. The invoice, currency formatting, and payment method entry are all handled by the Telegram client itself, which reduces the amount of frontend work significantly compared to a typical e-commerce integration.
The Three Payment Events You Must Handle
Every telegram bot payments integration revolves around three API objects your bot needs to respond to:
sendInvoice — the message your bot sends to initiate a purchase.pre_checkout_query — an event Telegram sends right before the charge is finalized, giving your bot a last chance to confirm the order is still valid (stock available, price still correct, etc.).successful_payment — the confirmation message that arrives once the charge has actually gone through.If your bot doesn’t answer the pre_checkout_query within a short timeout, Telegram cancels the transaction automatically. This is a common source of “payment just hangs” bugs, and it’s usually caused by a slow database lookup or an unhandled exception in the pre-checkout handler.
Setting Up Telegram Bot Payments With BotFather
Before you write any code, the provider connection has to be configured through BotFather, Telegram’s own bot-management bot. This step is easy to skip past and comes up constantly in support threads, so it’s worth doing carefully.
1. Open a chat with @BotFather and select the bot you want to enable payments on.
2. Choose Payments from the bot’s settings menu.
3. Pick a payment provider from the list Telegram offers for your bot’s region.
4. Connect your provider account and copy the provider token BotFather gives you — this is what your code uses to authorize invoices.
Registering a Payment Provider Token
The provider token is a secret and should be treated exactly like an API key or database password — never commit it to source control, and never log it. If you’re already using Docker Compose Secrets to manage other credentials in your stack, the provider token belongs in the same place rather than in a plaintext environment file checked into git.
A minimal docker-compose.yml snippet for a bot service that reads the token from a secret file looks like this:
services:
telegram-bot:
build: .
environment:
- PROVIDER_TOKEN_FILE=/run/secrets/telegram_provider_token
- TELEGRAM_BOT_TOKEN_FILE=/run/secrets/telegram_bot_token
secrets:
- telegram_provider_token
- telegram_bot_token
secrets:
telegram_provider_token:
file: ./secrets/telegram_provider_token.txt
telegram_bot_token:
file: ./secrets/telegram_bot_token.txt
Testing With Stripe’s Test Mode
If you connect Stripe as your provider, BotFather also gives you a separate test-mode provider token. Use it during development so you can run through the full telegram bot payments flow — invoice, pre-checkout, successful payment — with Stripe’s documented test card numbers instead of a real card. Switching to the live token should be a deployment-time configuration change, not a code change, so you never risk accidentally testing against real money.
Implementing the Payment Flow in Your Bot
Once the provider token is configured, the actual code for telegram bot payments is fairly small. Here’s a minimal example using Python and the python-telegram-bot library that sends an invoice and handles both required callbacks:
pip install python-telegram-bot==21.*
from telegram import LabeledPrice, Update
from telegram.ext import Application, CommandHandler, PreCheckoutQueryHandler, MessageHandler, filters
PROVIDER_TOKEN = "YOUR_PROVIDER_TOKEN"
async def send_invoice(update: Update, context):
chat_id = update.effective_chat.id
await context.bot.send_invoice(
chat_id=chat_id,
title="Pro Plan - 1 Month",
description="Unlocks premium bot features for 30 days.",
payload="pro-plan-1m",
provider_token=PROVIDER_TOKEN,
currency="USD",
prices=[LabeledPrice("Pro Plan", 999)], # amount in cents
)
async def precheckout_callback(update: Update, context):
query = update.pre_checkout_query
if query.invoice_payload != "pro-plan-1m":
await query.answer(ok=False, error_message="Something went wrong.")
else:
await query.answer(ok=True)
async def successful_payment_callback(update: Update, context):
payment = update.message.successful_payment
# Grant access, update your database, send a confirmation.
await update.message.reply_text("Payment received - your plan is now active.")
app = Application.builder().token("YOUR_BOT_TOKEN").build()
app.add_handler(CommandHandler("buy", send_invoice))
app.add_handler(PreCheckoutQueryHandler(precheckout_callback))
app.add_handler(MessageHandler(filters.SUCCESSFUL_PAYMENT, successful_payment_callback))
app.run_polling()
Handling send_invoice, precheckout_query, and successful_payment
Notice that the pre-checkout handler answers within the request itself — no external API call, no slow database round-trip. That’s deliberate: Telegram enforces a strict timeout on pre_checkout_query responses, and if your handler does anything expensive (like calling out to an inventory service), you should do it asynchronously and fail safe rather than block the callback.
The successful_payment_callback is where you’ll typically write to your own database, trigger fulfillment, or send a receipt. This is also the natural point to fire an event into a broader automation pipeline if you’re running one — for example, notifying an n8n Self Hosted workflow that a new order needs processing.
Automating Order Fulfillment With n8n
Once telegram bot payments are working, most of the ongoing engineering work isn’t the payment code itself — it’s what happens after a payment succeeds: provisioning access, updating a CRM, sending a receipt email, or logging the transaction for accounting. Wiring the bot’s successful_payment handler to call a webhook is usually simpler than building that logic into the bot itself.
A typical pattern:
successful_payment_callback posts the payment payload to an n8n webhook.Keeping fulfillment logic outside the bot process makes it easier to change business logic without redeploying the bot, and it keeps the bot codebase focused on the messaging and payment flow. If you’re deploying both the bot and an automation engine on the same infrastructure, a mid-tier VPS from a provider like DigitalOcean is usually enough to run both services comfortably for low-to-moderate transaction volume.
Securing Telegram Bot Payments in Production
Payment code deserves more scrutiny than an average feature, and telegram bot payments are no exception. A few practices matter more here than in most other parts of a bot:
pre_checkout_query, not just at invoice-creation time — prices or stock can change between the two events.payment_charge_id and your own internal order ID, but avoid logging full card or personal data — Telegram and the provider handle that, and you shouldn’t need to.successful_payment handler should check whether the order was already fulfilled before granting access a second time.Treat this list as a minimum bar, not a complete security review — if you’re processing meaningful payment volume, it’s worth a dedicated review pass against the Telegram Bot API documentation and your payment provider’s own integration checklist.
Monitoring and Debugging Telegram Bot Payments
Because the payment flow spans three systems — your bot, Telegram, and the provider — debugging failures means knowing where to look first. Most issues fall into one of three categories: the invoice never renders (usually a malformed prices array or an invalid currency code), the pre-checkout step times out (usually a slow or crashing handler), or the payment succeeds on the provider side but your bot never records it (usually a webhook delivery or idempotency bug).
Structured logging around each of the three callback stages — invoice sent, pre-checkout answered, payment confirmed — makes these failures much easier to trace than trying to reconstruct the sequence after the fact. If your bot runs as a containerized service, standard container log tooling is usually sufficient; the same debugging habits used for any other webhook-driven service apply here.
Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.
FAQ
Do I need a business account to use Telegram bot payments?
Requirements depend on the payment provider you connect, not Telegram itself. Stripe and most regional providers require a verified business or individual account capable of accepting card payments before they’ll issue a live provider token.
Can I accept cryptocurrency through Telegram bot payments?
The native sendInvoice flow is built around card-based payment providers. Crypto payments are typically handled outside this flow, through a separate integration with a crypto payment processor and custom bot commands.
What currencies does telegram bot payments support?
Supported currencies depend entirely on which provider you connect through BotFather. Most major providers support a wide range of standard ISO currency codes, but you should confirm the exact list with your specific provider before launch.
Why does my pre_checkout_query keep failing silently?
This almost always means the handler isn’t responding within Telegram’s timeout window, or it’s throwing an unhandled exception before calling answer(). Add explicit error handling around the handler and confirm it always calls answer(), even in failure cases.
Conclusion
Telegram bot payments give you a fast, native way to charge users without building a custom checkout experience. The mechanics are straightforward once you understand the three-event flow — invoice, pre-checkout, successful payment — but production reliability comes down to the details: secret management, idempotent fulfillment, and fast, defensive pre-checkout handling. Get those right, and telegram bot payments become a small, maintainable piece of a larger bot rather than a fragile bolt-on.
Leave a Reply