Платежі
Invoices і Payments
Telegram Bot API позволяет принимать платежи через sendInvoice — бот отправляет инвойс, пользователь оплачивает в клиенте Telegram, а ваш сервер получает подтверждение через pre_checkout_query и successful_payment.
Отправка инвойса
Метод sendInvoice требует токена провайдера (provider_token), полученного в BotFather при настройке платежей (Stripe, YooKassa, и др.). Минимальный набор параметров:
chat_id— целевой чатtitle— название товара (до 32 символов)description— описание (до 255 символов)payload— ваша внутренняя строка (до 128 байт), вернётся в вебхукахprovider_token— токен платёжного провайдераcurrency— трёхбуквенный код ISO 4217 (RUB, USD, EUR)prices— массивLabeledPrice(label, amount в минимальных единицах валюты)
$payload = json_encode([
'chat_id' => $chatId,
'title' => 'Подписка Pro',
'description' => 'Доступ к закрытым материалам на 30 дней',
'payload' => 'sub_pro_30_' . $userId,
'provider_token' => '398062629:TEST:999999999_F91D8F69C042267464B7',
'currency' => 'RUB',
'prices' => [[
'label' => 'Подписка 30 дней',
'amount' => 29900 // 299.00 RUB в копейках
]],
'start_parameter' => 'sub_pro_30', // для deep-linking
]);
$ch = curl_init('https://api.telegram.org/bot' . $botToken . '/sendInvoice');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
$res = curl_exec($ch);
if ($res === false) {
throw new RuntimeException('cURL error: ' . curl_error($ch));
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($res, true);
if (!$data['ok']) {
throw new RuntimeException('API error: ' . ($data['description'] ?? 'unknown'));
}
// $data['result'] — Message с invoice
Подтверждение предоплаты (pre_checkout_query)
Когда пользователь нажимает «Оплатить», Telegram отправляет ваш боту pre_checkout_query. У вас есть 10 секунд, чтобы ответить answerPreCheckoutQuery с ok: true (всё готово) или ok: false + error_message (товар закончился, цена изменилась). Без ответа платёж отменится.
// В обработчике обновлений
if (isset($update['pre_checkout_query'])) {
$query = $update['pre_checkout_query'];
$payload = json_decode($query['invoice_payload'], true);
// Проверяем, что товар актуален
$ok = verifyProductAvailable($payload);
$answer = [
'pre_checkout_query_id' => $query['id'],
'ok' => $ok,
];
if (!$ok) {
$answer['error_message'] = 'Товар временно недоступен, попробуйте позже.';
}
$ch = curl_init('https://api.telegram.org/bot' . $botToken . '/answerPreCheckoutQuery');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($answer),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
exit; // Важно: не обрабатывать дальше
}
Обработка успешной оплаты
После оплаты приходит Update с полем successful_payment. В нём: total_amount, currency, invoice_payload, telegram_payment_charge_id, provider_payment_charge_id. Сохраняйте эти данные для отчётности и выдачи товара.
if (isset($update['message']['successful_payment'])) {
$pay = $update['message']['successful_payment'];
$payload = json_decode($pay['invoice_payload'], true);
// Выдача доступа
grantAccess($payload['user_id'] ?? $update['message']['from']['id'], $payload);
// Логирование
logPayment([
'tg_charge_id' => $pay['telegram_payment_charge_id'],
'provider_charge_id' => $pay['provider_payment_charge_id'],
'amount' => $pay['total_amount'],
'currency' => $pay['currency'],
'payload' => $payload,
]);
// Ответ пользователю
sendMessage($chatId, 'Оплата прошла успешно! Доступ открыт.');
}
Важные нюансы
payload— единственное поле, которое вы полностью контролируйте. Кладьте туда JSON сuser_id,item_id, подписью HMAC для защиты от подделки.- Тестовые платежи: используйте тестовый токен провайдера и карту
4242 4242 4242 4242(Stripe) или аналоги для других ПС. В тестовом режиме деньги не списываются. - Возврат: метод
refundStarPaymentработает только для Telegram Stars. Для обычных платежей возврат инициируется в панели провайдера (Stripe Dashboard, YooKassa и т.д.). - Чеки: если нужен фискальный чек (54-ФЗ в РФ), настройте отправку чеков на стороне провайдера (YooKassa, CloudPayments поддерживают это из коробки).
Платежи в Bot API — это мост между Telegram-клиентом и вашим платёжным шлюзом. Бот не видит реквизитов карты, только подтверждение. Дальше: Telegram Stars — встроенная валюта для цифровых товаров без внешних провайдеров.