Most Telegram commerce ideas hit the same wall right after the prototype stage: the bot or Mini App itself is easy to build, but Stars and Premium fulfilment still need a dependable backend flow. That's usually when people start searching for a Fragment API.
MyStars FaaS gives you that missing layer. FaaS here means Fragment as a Service: your Telegram product keeps the user experience and order database, while MyStars exposes the fulfilment workflow through an API, official SDKs, and signed status updates.
This guide is for wiring up a real Telegram app, bot, marketplace, creator tool, or reseller flow — not just another API overview.
The clean architecture: Telegram API in front, Fragment API behind it
Keep the boundary simple:
- Telegram API layer — the parts users can see: bot commands, inline keyboards, Mini App screens, order cards, messages, support replies.
- Your server layer — your business logic: local orders, margin, fraud rules, admin controls, database writes, support evidence.
- MyStars FaaS layer — the Fragment-as-a-Service workflow: pricing, recipient checks, order creation, payment instructions, fulfilment status.
That separation matters for security. Don't put the MyStars API key in a Telegram Mini App frontend. The client talks to your backend; your backend talks to MyStars.
Install the SDK for your stack
Node.js / TypeScript — @mystars-tg/faas-sdk:
npm install @mystars-tg/faas-sdk
Python — mystars-faas:
pip install mystars-faas
Both are the official MyStars FaaS SDKs and link back to the interactive API docs. The current package docs describe compatibility with FaaS API v1.9.0, worth checking against when comparing examples to the API reference.
Build the first backend route in TypeScript
Don't try to do everything in the first route. Start with a server-only action that quotes, checks the recipient, and creates one fulfilment order from your own local order ID.
Plain-English version of what it does:
- creates a MyStars client on the backend using
MYSTARS_API_KEY - asks MyStars for the current price of the selected Stars quantity
- checks whether the Telegram username can receive the product
- stops early if the recipient isn't eligible, instead of creating a bad order
- creates the fulfilment order with your own stable
localOrderIdas the idempotency basis - returns the quote and the MyStars order object so your app can store and show the payment instruction
import { MyStarsClient } from "@mystars-tg/faas-sdk";
const client = MyStarsClient.production(process.env.MYSTARS_API_KEY!);
export async function createStarsOrder(input: {
username: string;
quantity: number;
localOrderId: string;
}) {
const quote = await client.getPricing({
type: "stars",
quantity: input.quantity,
payment_currency: "ton",
});
const recipient = await client.checkRecipient({
type: "stars",
recipient: { username: input.username },
});
if (!recipient.eligible) {
return { ok: false, message: recipient.telegram_message };
}
const order = await client.createOrder(
{
type: "stars",
recipient: { username: input.username },
quantity: input.quantity,
payment_currency: "ton",
callback_url: "https://your-app.example.com/webhooks/mystars",
},
{ idempotencyKey: `local-${input.localOrderId}` },
);
return { ok: true, quote, order };
}
The important part is the idempotency key. Use something stable from your own system. If the HTTP request times out after the order was already created server-side, retry with the same key instead of creating a duplicate.
A few lines worth a second look:
-
MyStarsClient.production(...)hits the live API — use a test/local order in your own system until you're ready for real traffic. -
getPricing(...)gives your backend a current quote. Don't hardcode prices in the bot UI. -
payment_currency: "ton"is the API enum for the native payment route in this SDK example. In your product UI, label that route as Gram or Gram (ex. TON) — keep TON for the blockchain/network name. -
checkRecipient(...)protects the buyer from paying for a username or product that can't be fulfilled. -
callback_urlis where MyStars sends order status updates after creation. -
idempotencyKeyis the duplicate-order guard — it should come from your database order, not a random value generated in the browser.
The same flow in async Python
Python teams usually want async code because their Telegram bot framework already is. The Python SDK supports that directly.
from mystars_faas import AsyncMyStarsClient
async def create_premium_order(username: str, months: int, local_order_id: str):
async with AsyncMyStarsClient.production(MYSTARS_API_KEY) as client:
quote = await client.get_pricing(
type="premium",
months=months,
payment_currency="usdt_ton",
)
recipient = await client.check_recipient(username, type="premium")
if not recipient.eligible:
return {"ok": False, "message": recipient.telegram_message}
order = await client.create_order(
type="premium",
recipient=username,
months=months,
payment_currency="usdt_ton",
callback_url="https://your-app.example.com/webhooks/mystars",
idempotency_key=f"local-{local_order_id}",
)
return {"ok": True, "quote": quote, "order": order}
In production: use exact money handling, keep the API key in an environment variable, and store the payment instruction exactly as returned. If the instruction includes a memo/comment, treat it as data — not copy you can rewrite.
One clarification for anyone newer to this: the snippet above isn't a full bot. It's the backend piece your bot calls once the user has already picked a product — your bot still needs its own handlers, buttons, database writes, and user-facing messages around this function.
Add webhook verification before launch
Order creation working isn't the finish line — you also need a trustworthy status path.
Minimum webhook handler:
- Receive the raw request body.
- Read the
X-Faas-Signatureheader. - Verify the signature with your webhook secret.
- Dedupe by MyStars order ID and status.
- Update your local order only if the transition is valid.
- Notify the user through your bot or Mini App.
The TypeScript SDK ships webhook helpers (constructEvent, Express middleware, Fastify support). The Python SDK includes WebhookVerifier plus integrations for common Python web frameworks.
Keep a polling/reconcile job as a backup. Webhooks are the fast path — reconciliation is what saves you when a network edge case shows up at 3 a.m.
A working reference: the blueprint bot
The MyStars Python blueprint bot is the best place to see all the moving parts together. It uses mystars-faas==0.1.3 for fulfilment, an aiohttp server for health checks and MyStars webhooks, Postgres + Redis for state, TON Center monitoring for on-chain payments, and admin commands for margin/reconciliation.
Treat it as an engineering map, not a brand template — where to create the local order, where to call recipient checks, where to apply margin, where to monitor payment, where to call fulfilment, where to edit the Telegram order card after a terminal status.
The MyStars GitHub org also hosts the SDK repos if you need to debug past what the README covers.
Backend endpoints to create in your own app
A small production-grade integration usually starts with:
POST /api/faas/quote
POST /api/faas/recipient-check
POST /api/orders
POST /webhooks/mystars
GET /api/orders/:id
POST /api/admin/reconcile
Your Telegram bot or Mini App should call your own /api/orders route, not MyStars directly. That route validates the user, creates a local order, calls the SDK, stores the returned fulfilment order, and sends back only the safe fields your client needs.
Payment details users must not have to guess
If your product shows a payment screen, be precise. For MyStars flows, USDT means USDT on TON — other USDT networks aren't interchangeable. For the native route, current API examples still use payment_currency: "ton"; buyer-facing copy should say Gram / GRAM (ex. TON) for the token and TON for the network.
Read the order's expires_at field instead of hardcoding a payment timeout — the docs note the payment window was extended to 1 hour, and expires_at is the source of truth.
What to test before real traffic
- one Stars order and one Premium order
- one ineligible-recipient path
- retrying order creation with the same idempotency key
- valid and invalid webhook signatures
- duplicated webhook event delivery
- expired order handling
- support evidence: username, local order ID, MyStars order ID, payment hash, memo/comment, status
- admin-only access for margin, reconcile, refund, broadcast, and manual fulfilment commands
Unglamorous, but it's what makes a Telegram Stars bot feel reliable instead of experimental.
FAQ
Is this a direct public Fragment API?
MyStars FaaS is a Fragment-as-a-Service layer. Your app integrates with MyStars APIs and SDKs, while MyStars handles the fulfilment workflow behind that interface.
Can I use it from a Telegram Mini App?
Yes — keep the API key on your backend. The Mini App calls your server, your server calls MyStars FaaS.
Which package should I start with?
@mystars-tg/faas-sdk for Node.js/TypeScript, mystars-faas for Python and async Telegram bots.
Do I need the blueprint bot?
No, but it helps if you're building a reseller-style bot with payments, admin commands, reconciliation, and status updates.
What's the safest first milestone?
One end-to-end test: quote → recipient check → local order → MyStars order → verified webhook or polling update. After that works, add margin, refund policy, admin tools, and support workflows.
Full API reference, SDK links, and current contract notes: mystars.tg/docs. Source for the SDKs and the blueprint bot: github.com/MyStars-tg.
Originally published on the MyStars.tg blog.
Top comments (0)