Платежи через PHP Telegram Bot API

Не так давно Telegram представили возможность оплаты товаров с помощью бота. В момент запуска платежей был доступен только Stripe, сейчас уже доступны ещё 3 платежные системы, так что теперь можно сказать что платежи доступны по всему миру.
Так как я давно пользуюсь Telegram ботами (о них будет ещё пару записей в будущем) мне захотелось реализовать эту возможность на PHP учитывая что я уже занимался поддержкой и разработкой библиотеки TelegramBot/Api и были просьбы от пользователей сделать это, но как на зло было море работы и банально не было времени чтобы начать это делать, но спустя пару недель время нашлось и платежи были написаны. Покажу на примере как всё работает со стороны PHP, в плане логики всё хорошо описано на официальном сайте.
Для начала нужно скачать саму библиотеку:
composer require telegram-bot/api
Теперь нужно отправить продукт, который будут покупать, сделать это достаточно просто (как мне кажется):
$botApi = new TelegramBotApiBotApi(env('BOT_TOKEN'));
$botApi->sendInvoice(
1223121, // ID получателя, взять его можно во время входящего вебхука от этого пользователя
'Powerball', // Название продукта
'Новая модель Powerball Classic. От старой модели отличается обновленным дизайном: стильный синий корпус, белый ротор, новое модерн лого.', // Описание продукта
'powerball-classic', // Пишем свою внутренюю ID платежа, что либо по этому значению потом будете понимать что покупают
env('PAYMENT_PROVIDER_TOKEN'), // Токен платежной системы, получить можно у @Botfather
'pb-classic', // Начальный параметр который будет использован для генерации платежа
'UAH', // Валюта в которой будет оплачиваться товар
[
['label' => 'Powerball 250Hz Classic Blue', 'amount' => 55100], //Массив цен, пользователь выберет только одну цену
['label' => 'Powerball 250Hz Pro Blue', 'amount' => 79600],
['label' => 'Powerball 280Hz Autostart', 'amount' => 146400]
],
true // Указываем в том случае если цена может измениться в зависимости от доставки
);
Весь список параметров с атрибутами можно посмотреть на Github.
После этого у покупателя в телеграме придет сообщение такого вида:
Но, в примере я указал что на сумму продукта так же влияет адрес доставки, поэтому вместо платежных данных мне будет предложено ввести данные о доставке. Потом эти данные через вебхук отправляются к нам на сервер, принимать эти данные стоит вот так:
try {
$bot = new TelegramBotApiClient(env('BOT_TOKEN'));
$bot->shippingQuery(function ($query) use ($bot, $botApi) {
//Собираем информацию о способах доставки и ценах, делаем что-то ещё и отправляем ответ:
$botApi->answerShippingQuery(
$query->getId(), // уникальное id query который пришел на вебхук
true, // отвечаем что всё хорошо и отправляем массив вариантов доставки
[
[
'id' => 'np',
'title' => 'Новая почта',
'prices' => [
[
'label' => 'На склад',
'amount' => 4000
]
]
],
[
'id' => 'up',
'title' => 'Укрпочта',
'prices' => [
[
'label' => 'В отделение',
'amount' => 2000
]
]
]
]);
});
$bot->run();
} catch (TelegramBotApiException $e) {
$e->getMessage();
}
Я показал только ответ сервера, данные все лежат в переменной $query. (Эти массивы в ответе самого напрягают и когда то я до них доберусь и переделаю под объекты).
В итоге в телеграм придет вот такой ответ с вариантами доставки:
Выбрав вариант доставки мне предложат ввести данные о платеже, заполнив которые я получу уже счет, в котором посчитана общая цена и выведена информация за продукт:
После того как покупатель нажмет кнопку "Pay" на вебхук уйдет ещё один запрос, в котором будет доступна вся эта информация, и нужно будет ответить в течении 10 секунд информация верна или нет:
try {
$bot = new TelegramBotApiClient(env('BOT_TOKEN'));
$bot->preCheckoutQuery(function ($query) use ($bot, $botApi) {
$botApi->answerPreCheckoutQuery($query->getId(), true); //Говорим что всё хорошо, товар есть на складе и готовы отправить
});
$bot->run();
} catch (TelegramBotApiException $e) {
$e->getMessage();
}
В случае если что-то не так, нужно ещё указать текст ошибки, который будет отображаться в телеграме, если мы сказали что всё хорошо - телеграм отправляет данные в платежную систему и снимает деньги.
В итоге получим сообщение в чате что деьги переведены и можем посмотреть счет по товару вместо кнопки оплаты:
Вот так просто реализованы платежы,если не указывать доставку всё сводится к последнему шагу, на PHP тоже как видите работы не много, конечно я привел простой пример, полей на самом деле при создании продукта на много больше, ознакомится можно в самой библиотеке или на официальном сайте.