Описание
После того как пользователь подтвердил свои платежные и транспортные данные, Bot API отправляет окончательное подтверждение в виде Update с полем pre_checkout_query. Используйте этот метод для ответа на такие предварительные платежные запросы. При успешном выполнении возвращается True. Примечание: Bot API должен получить ответ в течение 10 секунд после отправки предварительного платежного запроса.
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| pre_checkout_query_id | String | Да | Уникальный идентификатор запроса, на который нужно ответить |
| ok | Boolean | Да | Укажите True, если все в порядке (товары доступны и т.д.) и бот готов продолжить оформление заказа. Используйте False, если есть какие-либо проблемы. |
| error_message | String | Опционально | Обязателен, если ok равен False. Сообщение об ошибке в удобочитаемой форме, объясняющее причину невозможности продолжить оформление заказа (например, "Извините, пока вы заполняли платежные данные, кто-то только что купил последнюю нашу удивительную черную футболку. Пожалуйста, выберите другой цвет или изделие!"). Telegram покажет это сообщение пользователю. |
Примеры
php
<?php
// Токен вашего бота
$botToken = 'YOUR_BOT_TOKEN';
// ID предварительного запроса на оплату из обновления
$preCheckoutQueryId = $_POST['pre_checkout_query_id'] ?? ''; // В реальном коде получайте из Update
// Статус проверки (true - всё хорошо, false - есть проблемы)
$ok = true;
// Сообщение об ошибке (только если $ok = false)
$errorMessage = '';
// Если есть проблемы с заказом
// $ok = false;
// $errorMessage = 'Извините, товар закончился. Пожалуйста, выберите другой товар.';
// Подготовка данных для запроса
$data = [
'pre_checkout_query_id' => $preCheckoutQueryId,
'ok' => $ok
];
// Добавляем сообщение об ошибке только если статус false
if (!$ok && !empty($errorMessage)) {
$data['error_message'] = $errorMessage;
}
// Отправка запроса к Telegram Bot API
$url = "https://api.telegram.org/bot{$botToken}/answerPreCheckoutQuery";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Обработка ответа
if ($httpCode === 200) {
$result = json_decode($response, true);
if ($result['ok'] === true) {
// Успешный ответ на pre-checkout запрос
echo "Pre-checkout query answered successfully.\n";
// Здесь можно обновить статус заказа в вашей базе данных
// и подготовить данные для отправки счёта
} else {
echo "Error: " . $result['description'] . "\n";
}
} else {
echo "HTTP Error: " . $httpCode . "\n";
}
// Альтернативный вариант с использованием file_get_contents
/*
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => json_encode($data)
]
]);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
if ($result['ok'] === true) {
echo "Success!\n";
} else {
echo "Error: " . $result['description'] . "\n";
}
*/
// Пример обработки в вебхуке
/*
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$update = json_decode(file_get_contents('php://input'), true);
if (isset($update['pre_checkout_query'])) {
$preCheckoutQuery = $update['pre_checkout_query'];
$preCheckoutQueryId = $preCheckoutQuery['id'];
$userId = $preCheckoutQuery['from']['id'];
$orderInfo = $preCheckoutQuery['order_info'] ?? [];
$totalAmount = $preCheckoutQuery['total_amount'];
$currency = $preCheckoutQuery['currency'];
$invoicePayload = $preCheckoutQuery['invoice_payload'];
// Проверяем доступность товара и другие условия
$isAvailable = checkProductAvailability($invoicePayload);
if ($isAvailable) {
// Всё хорошо, подтверждаем оплату
answerPreCheckoutQuery($preCheckoutQueryId, true);
// Помечаем заказ как ожидающий оплаты
updateOrderStatus($invoicePayload, 'pending_payment');
} else {
// Товар недоступен, отказываем в оплате
answerPreCheckoutQuery($preCheckoutQueryId, false,
'Извините, товар временно отсутствует на складе.');
}
}
}
function answerPreCheckoutQuery($queryId, $ok, $errorMessage = '') {
global $botToken;
$data = [
'pre_checkout_query_id' => $queryId,
'ok' => $ok
];
if (!$ok && !empty($errorMessage)) {
$data['error_message'] = $errorMessage;
}
$url = "https://api.telegram.org/bot{$botToken}/answerPreCheckoutQuery";
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => ['Content-Type: application/json']
]);
curl_exec($ch);
curl_close($ch);
}
*/
?>
python
import asyncio
from telegram import Bot, Update
from telegram.ext import Application, PreCheckoutQueryHandler
# Инициализация бота
bot = Bot(token="YOUR_BOT_TOKEN")
# Пример обработки pre-checkout запроса
async def handle_pre_checkout_query(update: Update, context):
query = update.pre_checkout_query
# Проверяем возможность обработки платежа
if is_payment_valid(query):
# Подтверждаем успешную проверку
await query.answer(ok=True)
else:
# Отклоняем с сообщением об ошибке
await query.answer(
ok=False,
error_message="Извините, товар временно недоступен. Пожалуйста, попробуйте позже."
)
# Вспомогательная функция для проверки платежа
def is_payment_valid(query):
# Здесь должна быть ваша логика проверки:
# - Доступность товара
# - Корректность суммы
# - Проверка пользователя и т.д.
# Пример простой проверки
if query.total_amount > 0:
return True
return False
# Пример использования в обработчике
async def main():
# Создаем приложение
application = Application.builder().token("YOUR_BOT_TOKEN").build()
# Регистрируем обработчик pre-checkout запросов
application.add_handler(PreCheckoutQueryHandler(handle_pre_checkout_query))
# Запускаем бота
await application.initialize()
await application.start()
await application.updater.start_polling()
# Альтернативный вариант - прямой вызов API
async def answer_pre_checkout_query_directly():
# Прямой вызов метода answer_pre_checkout_query
result = await bot.answer_pre_checkout_query(
pre_checkout_query_id="UNIQUE_QUERY_ID",
ok=True
)
# Или с ошибкой
result = await bot.answer_pre_checkout_query(
pre_checkout_query_id="UNIQUE_QUERY_ID",
ok=False,
error_message="Товар закончился на складе"
)
return result
# Запуск примера
if __name__ == "__main__":
asyncio.run(main())
История изменений
- API 3.0. Добавлен метод answerPreCheckoutQuery
Дополнительно
- Update - Объект Update представляет входящее событие в Telegram Bot API, содержащее информацию о сообщениях, запросах, изменениях статуса участников и других действиях, связанных с ботом.