telegram-payments
Skill0 starsChanged 36 days agoMITView on GitHub
Charge users inside Telegram — Telegram Stars (currency XTR) for digital goods, subscriptions, paid media, gifts and paid broadcasts, card providers for physical goods, refunds and go-live requirements, in TypeScript (grammY) or Python (aiogram). Use this skill whenever the user wants to sell anything in a Telegram bot or Mini App, mentions Stars, XTR, sendInvoice, createInvoiceLink, openInvoice, pre_checkout_query, successful_payment, refunds, /paysupport, subscriptions, paid content, gifts or donations, or asks how to take money in Telegram, including "accept crypto for in-game items".
In this repository11 other files it gives its agents.
- add-paymentsSkill
- add-ton-connectSkill
- audit-projectSkill
- deploy-testnetSkill
- new-botSkill
- new-mini-appSkill
- telegram-botSkill
- telegram-devSkill
- telegram-launchSkill
- telegram-mini-appSkill
- telegram-tonSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 28
When a user asks for a crypto checkout for digital goods, say this first and propose Stars.
- Very specific: line 132
Before launch, run the telegram-security-reviewer agent on the payment code.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Payments in Telegram
Official references: https://core.telegram.org/bots/payments-stars, https://core.telegram.org/bots/payments and the Payments section of the Bot API. Checked October 2026; re-check limits before relying on them.
The rule that decides everything
Telegram requires that digital goods and services sold inside bots and Mini Apps are paid
only in Telegram Stars (XTR). Crypto (including TON and jettons) and third-party card
providers are not allowed for them because of App Store and Play Store rules; an app that
tries can stop being shown to mobile users. A separate website with other payment methods does
not change what is allowed inside Telegram.
| Selling | Use |
| In-app items, game currency, premium features, access, content, AI credits | Stars |
| Subscriptions to digital content | Stars subscription |
| Photos or videos behind a paywall | sendPaidMedia (Stars) |
| Physical goods and services | a payment provider from @BotFather (cards), currency of your choice |
| Payouts, deposits, on-chain assets the user owns | TON is possible, see telegram-ton |
When a user asks for a crypto checkout for digital goods, say this first and propose Stars; don't
silently build what they asked for. Borderline cases: point to Section 6.2 of the Telegram Bot
Platform Developer Terms and record the decision in PRODUCT.md.
Stars flow
- Invoice.
sendInvoiceinto a chat, orcreateInvoiceLinkfor a link a Mini App opens withWebApp.openInvoice(url).currency: "XTR", emptyprovider_token, exactly one item inprices. Title 1-32 chars, description 1-255,payload1-128 bytes (an opaque order id). - Pre-checkout. Answer
pre_checkout_querywithin 10 seconds withanswerPreCheckoutQuery, after checking the order exists, is unpaid and the price matches. On failure pass a human-readableerror_message. Keep this handler fast: no slow calls. - Fulfil only on
successful_payment. Answering pre-checkout doesn't mean money arrived. Storetelegram_payment_charge_id; key fulfilment on it so a redelivered update never grants twice. - Refunds:
refundStarPayment(user_id, telegram_payment_charge_id). - Reconcile:
getStarTransactions(pages of up to 100) andgetMyStarBalance.
Price and item always come from the server, never from the client. Reject payloads you didn't create, orders of another user, and orders already paid.
Subscriptions, paid media, gifts
createInvoiceLinkwithsubscription_period: 2592000(it must be exactly 30 days today),XTR, price up to 10000 Stars. Renewals arrive assuccessful_paymentwithis_recurring; changes to a user's subscription also come assubscriptionupdates (Bot API 10.2). Cancel or resume renewal witheditUserStarSubscription.sendPaidMedia: 1-25000 Stars per item.sendGiftsends a gift from the bot's Stars balance to a user or channel; the receiver can't convert it to Stars.giftPremiumSubscriptiongifts Premium for Stars.- Forwarded invoices and inline invoices can be paid by many users. Accept repeated payments only
if each can be fulfilled (stock, per-user limits);
start_parametermakes an invoice single-chat.
Code shape
TypeScript (grammY):
bot.on("pre_checkout_query", async (ctx) => {
const order = await orders.findPending(ctx.preCheckoutQuery.invoice_payload, ctx.from.id);
if (order) await ctx.answerPreCheckoutQuery(true);
else await ctx.answerPreCheckoutQuery(false, { error_message: "This order has expired." });
});
bot.on("message:successful_payment", async (ctx) => {
const p = ctx.message.successful_payment;
await orders.markPaidOnce(p.invoice_payload, p.telegram_payment_charge_id); // unique on charge id
});Python (aiogram 3):
from aiogram import F, Router
from aiogram.types import LabeledPrice, Message, PreCheckoutQuery
router = Router()
async def send_invoice(message: Message, order) -> None:
await message.answer_invoice(
title=order.title,
description=order.description,
payload=order.id,
currency="XTR",
prices=[LabeledPrice(label=order.title, amount=order.stars)],
)
@router.pre_checkout_query()
async def pre_checkout(query: PreCheckoutQuery) -> None:
order = await orders.find_pending(query.invoice_payload, query.from_user.id)
if order:
await query.answer(ok=True)
else:
await query.answer(ok=False, error_message="This order has expired.")
@router.message(F.successful_payment)
async def paid(message: Message) -> None:
p = message.successful_payment
await orders.mark_paid_once(p.invoice_payload, p.telegram_payment_charge_id)Signatures move between framework versions; check the current docs if a call fails. If the
webhook filters updates, allowed_updates must include pre_checkout_query and message.
Testing
Telegram has a separate test environment where Stars payments are free (https://core.telegram.org/bots/webapps#using-bots-in-the-test-environment). Run the whole flow there: invoice, pre-checkout, success, duplicate update, refund.
Go-live requirements
- 2-step verification on the Telegram account that owns the bot.
/terms(or an equally easy link) with clear terms; users agree before buying./paysupportanswered promptly; users told that Telegram support can't help with purchases made through your bot.- You handle disputes and refunds yourself.
- Stable hosting and backups of payment records; logs keep charge ids and order ids, not personal data.
Before launch, run the telegram-security-reviewer agent on the payment code.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

