Stars
@vibegram/stars menyediakan helper production untuk pembayaran Telegram Stars: invoice builder, approval/decline pre-checkout, validasi successful payment, refund, workflow gift/business, dan fixture paid update untuk test.
Gunakan saat bot menjual digital goods, paid media, akses premium, gift, atau fitur Mini App melalui Telegram Stars.
Mapping Resmi Telegram
Plugin ini membungkus behavior Telegram Bot API tanpa mengubahnya.
Invoice Stars adalah invoice Telegram biasa dengan currency: "XTR", provider_token kosong, dan tepat satu item prices. Plugin memvalidasi aturan ini sebelum request masuk ke Telegram.
Update pre-checkout datang sebagai Update.pre_checkout_query dan harus dijawab dengan answerPreCheckoutQuery. Pembayaran selesai datang sebagai message.successful_payment. Refund dilakukan lewat refundStarPayment. Pembelian paid media datang sebagai purchased_paid_media.
Referensi: Payments, sendInvoice, createInvoiceLink, answerPreCheckoutQuery, PreCheckoutQuery, SuccessfulPayment, refundStarPayment, sendPaidMedia, dan BusinessConnection.
Install
Saat package plugin resmi ini sudah dipublish, install dari npm:
npm install vibegram @vibegram/starsUntuk saat ini, gunakan package repository sebagai local file dependency:
{
"dependencies": {
"vibegram": "^2.1.0",
"@vibegram/stars": "file:../vibegram/plugins/stars"
}
}Setup
import { Bot } from 'vibegram';
import { stars } from '@vibegram/stars';
const bot = new Bot(process.env.TELEGRAM_BOT_TOKEN!);
bot.use(stars());Middleware menambahkan helper request-scoped ctx.stars dan memulihkan nilai sebelumnya setelah handler selesai.
Invoice Stars
bot.command('beli', ctx => {
return ctx.stars.invoice({
title: 'Akses Premium',
description: 'Akses premium 30 hari',
payload: `premium:${ctx.from?.id}`,
amount: 100,
label: 'Premium',
});
});ctx.stars.invoice() mengirim sendInvoice ke chat saat ini dengan payload ini:
{
provider_token: '',
currency: 'XTR',
prices: [{ label: 'Premium', amount: 100 }]
}Untuk subscription, gunakan periode 30 hari yang didukung Telegram:
await ctx.stars.invoice({
title: 'Premium subscription',
description: 'Akses premium recurring 30 hari',
payload: `sub:${ctx.from?.id}`,
amount: 500,
subscriptionPeriod: 2592000,
});Invoice Link
const link = await ctx.stars.createInvoiceLink({
title: 'Akses Premium',
description: 'Akses premium 30 hari',
payload: 'premium:42',
amount: 100,
});Simpan payload di tabel order sebelum link dikirim.
Guard Pre-Checkout
bot.on('pre_checkout_query', async ctx => {
try {
await ctx.stars.approvePreCheckout({
payloadPrefix: 'premium:',
totalAmount: 100,
});
} catch {
await ctx.stars.declinePreCheckout('Order ini sudah tidak tersedia.');
}
});Validasi:
currencyadalahXTRtotal_amountcocok dengan order di serverinvoice_payloadada di database- order masih tersedia dan belum fulfilled
Telegram mengharapkan jawaban pre-checkout cepat. Jaga handler ini tetap ringan.
Pembayaran Berhasil
bot.on('message:successful_payment', async ctx => {
const payment = ctx.stars.requireSuccessfulPayment({
payloadPrefix: 'premium:',
});
await activatePremium({
payload: payment.invoice_payload,
chargeId: payment.telegram_payment_charge_id,
amount: payment.total_amount,
});
await ctx.reply('Premium aktif.');
});Lakukan fulfillment hanya setelah successful_payment, bukan setelah invoice dikirim atau pre-checkout disetujui.
Refund
await ctx.stars.refund(ctx.from!.id, 'telegram-payment-charge-id');Saat sedang menangani update successful-payment:
await ctx.stars.refundSuccessfulPayment();Catat status refund di database agar command yang sama tidak mencoba refund berulang kali.
Paid Media
await ctx.stars.paidMedia({
starCount: 25,
payload: `gallery:${ctx.from?.id}`,
media: [
{ type: 'photo', media: 'https://example.com/photo.jpg' },
],
caption: 'Galeri premium',
});Fixture purchase paid media untuk test:
import { createPaidMediaPurchasedUpdate } from '@vibegram/stars';
const update = createPaidMediaPurchasedUpdate({
userId: 42,
paidMediaPayload: 'gallery:42',
});Gift Dan Business Workflow
await ctx.stars.gifts.send(ctx.from!.id, 'gift-id', {
text: 'Terima kasih sudah mendukung kami',
});
await ctx.stars.gifts.premium(ctx.from!.id, 3, 1000, {
text: 'Hadiah Premium',
});Helper business account:
await ctx.stars.business.getStarBalance('business-connection-id');
await ctx.stars.business.transferStars('business-connection-id', 250);
await ctx.stars.business.convertGiftToStars('business-connection-id', 'owned-gift-id');
await ctx.stars.business.upgradeGift('business-connection-id', 'owned-gift-id', {
star_count: 0,
});
await ctx.stars.business.transferGift('business-connection-id', 'owned-gift-id', 123456789);Method ini membutuhkan business bot rights Telegram yang sesuai.
Fixture Test
import {
createPreCheckoutQueryUpdate,
createSuccessfulPaymentUpdate,
} from '@vibegram/stars';
const preCheckout = createPreCheckoutQueryUpdate({
payload: 'premium:42',
totalAmount: 100,
});
const successful = createSuccessfulPaymentUpdate({
payload: 'premium:42',
totalAmount: 100,
telegramPaymentChargeId: 'charge-1',
});Options Dan API
Export utama: stars(), buildStarsInvoice(), createPreCheckoutQueryUpdate(), createSuccessfulPaymentUpdate(), createPaidMediaPurchasedUpdate(), StarsPluginError, StarsFlavor, dan type TypeScript terkait.
buildStarsInvoice(options) menerima:
| Option | Type | Deskripsi |
|---|---|---|
title | string | Nama produk, maksimal 32 karakter |
description | string | Deskripsi produk, maksimal 255 karakter; default ke title |
payload | string | Payload order server-side, maksimal 128 bytes |
amount | number | Jumlah Stars saat memakai satu price otomatis |
label | string | Label harga, default Stars |
prices | LabeledPrice[] | Price list eksplisit; Stars wajib tepat satu item |
subscriptionPeriod | 2592000 | Periode subscription 30 hari opsional |
extra | object | Field invoice Telegram tambahan |
Keamanan Dan Rekonsiliasi
- Buat invoice di server.
- Perlakukan
payloadsebagai order ID opaque, bukan state user yang dipercaya. - Persist order sebelum invoice dikirim.
- Validasi pre-checkout dari database.
- Fulfill hanya setelah
successful_payment. - Buat fulfillment idempotent.
- Simpan
telegram_payment_charge_iddan status refund. - Gunakan
@vibegram/throttleruntuk offer berbayar skala broadcast dan jangan retrysendInvoicesecara buta.
Validasi
Plugin ini punya test untuk payload invoice Stars, handling pre-checkout, validasi successful payment, helper refund, helper gift/business, dan fixture paid media.
npm run plugins:validate
npm run docs:build