Payments

Telegram Stars

How to accept Telegram Stars (XTR) — the native currency for digital goods. sendInvoice with currency=XTR, pre_checkout_query, successful_payment, refunds via refundStarPayment, and transaction history.

Telegram Stars (XTR) is Telegram's built-in currency for digital goods and donations. Unlike regular payments via providers, Stars do not require setting up provider_token, work in all countries, and handle KYC/AML. Telegram's commission is 30% (just like in the App Store/Google Play), and the rest goes to the developer. Withdrawal is available via Fragment (in Toncoin) or for advertising in Telegram Ads.

Sending an Invoice in Stars

The sendInvoice method with the currency XTR. The provider_token parameter is omitted — Stars is a native method. Prices are specified in the smallest units (1 Star = 1 XTR, fractional parts are not supported).

The telegramApi() helper is described in chapter Первый запрос: getMe.

<?php
function sendStarsInvoice(int $chatId, string $title, string $description, string $payload, int $amount, array $prices): array {
return telegramApi('sendInvoice', [
'chat_id' => $chatId,
'title' => $title,
'description' => $description,
'payload' => $payload, // ваш внутренний ID заказа
'currency' => 'XTR', // Telegram Stars
'prices' => $prices, // [['label' => 'Подписка на месяц', 'amount' => $amount]]
'start_parameter' => 'stars_' . $payload,
'provider_data' => json_encode([]), // пустой объект, обязателен для XTR
]);
}

// Пример вызова
$prices = [['label' => 'Premium на 30 дней', 'amount' => 150]]; // 150 Stars
sendStarsInvoice($chatId, 'Premium доступ', 'Без рекламы и лимитов', 'premium_30d', 150, $prices);
?>

Handling pre_checkout_query

Telegram sends pre_checkout_query 10 seconds before the charge. The bot must check the availability of the product and reply with answerPreCheckoutQuery with ok: true. If the product is unavailable — ok: false with error_message.

<?php
function handlePreCheckout(array $update): void {
$query = $update['pre_checkout_query'];
$payload = $query['invoice_payload']; // ваш payload из sendInvoice

// Проверка: товар доступен, пользователь не купил уже и т.д.
$available = checkProductAvailable($payload, $query['from']['id']);

telegramApi('answerPreCheckoutQuery', [
'pre_checkout_query_id' => $query['id'],
'ok' => $available,
'error_message' => $available ? null : 'Товар временно недоступен, попробуйте позже',
]);
}

function checkProductAvailable(string $payload, int $userId): bool {
// Ваша логика: проверка БД, лимитов, подписок
return true;
}
?>

Handling successful_payment

After a successful charge, an update with the successful_payment object is received. The currency field will be XTR, and total_amount will be in Stars. This is the moment to deliver the product.

<?php
function handleSuccessfulPayment(array $update): void {
$payment = $update['message']['successful_payment'];
$payload = $payment['invoice_payload'];
$userId = $update['message']['from']['id'];
$stars = $payment['total_amount']; // уже в Stars, не в копейках

// Выдача товара
grantProduct($userId, $payload, $stars);

// Подтверждение пользователю
telegramApi('sendMessage', [
'chat_id' => $update['message']['chat']['id'],
'text' => "✅ Оплата прошла успешно! Списано {$stars} ⭐. Товар выдан.",
'reply_to_message_id' => $update['message']['message_id'],
]);
}

function grantProduct(int $userId, string $payload, int $stars): void {
// Ваша логика: активация подписки, выдача ключа, начисление баланса
}
?>

Refunding Stars

The refundStarPayment method refunds Stars to the user. It works only for payments in Stars and does not require a provider. Telegram retains its commission (30%) upon refund — the developer gets 70% back.

<?php
function refundStars(int $userId, string $telegramPaymentChargeId): array {
return telegramApi('refundStarPayment', [
'user_id' => $userId,
'telegram_payment_charge_id' => $telegramPaymentChargeId,
]);
}

// telegram_payment_charge_id берётся из successful_payment.telegram_payment_charge_id
// Сохраняйте его в БД при обработке successful_payment
?>

Stars Transaction History

The getStarTransactions method returns a list of incoming/outgoing bot operations. Useful for reports and reconciliation.

<?php
function getStarTransactions(int $offset = 0, int $limit = 100): array {
return telegramApi('getStarTransactions', [
'offset' => $offset,
'limit' => $limit,
]);
}

// Ответ содержит массив StarTransaction с полями:
// id, amount, date, type (incoming/outgoing/refund), user, invoice_payload, telegram_payment_charge_id
?>

Withdrawing Stars

There is no direct API for withdrawing to a bank card. There are two ways:

  1. Fragment — exchanging Stars for Toncoin (via @Fragment bot or Fragment API), then withdrawing to a wallet.
  2. Telegram Ads — spending Stars on bot/channel advertising directly in Telegram Ads.

To automate the exchange to Toncoin, use unofficial Fragment API libraries or manual withdrawal via the @Fragment bot.

Limitations and Nuances

  • The minimum invoice amount is 1 Star.
  • The maximum amount of a single invoice is 10,000 Stars.
  • Stars do not work for physical goods (requires need_shipping_address and a provider). Only digital goods, donations, and subscriptions.
  • provider_data is required, but must be an empty JSON object {}.
  • There is no provider_payment_charge_id in successful_payment — only telegram_payment_charge_id.

Next: Inline mode