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

Не так давно Telegram представили возможность оплаты товаров с помощью бота. В момент запуска платежей был доступен только Stripe, сейчас уже доступны ещё 3 платежные системы, так что теперь можно сказать что платежи доступны по всему миру.

Так как я давно пользуюсь Telegram ботами (о них будет ещё пару записей в будущем) мне захотелось реализовать эту возможность на PHP учитывая что я уже занимался поддержкой и разработкой библиотеки TelegramBot/Api и были просьбы от пользователей сделать это, но как на зло было море работы и банально не было времени чтобы начать это делать, но спустя пару недель время нашлось и платежи были написаны. Покажу на примере как всё работает со стороны PHP, в плане логики всё хорошо описано на официальном сайте.

Для начала нужно скачать саму библиотеку:

composer require telegram-bot/api

Теперь нужно отправить продукт, который будут покупать, сделать это достаточно просто (как мне кажется):

$botApi = new \TelegramBot\Api\BotApi(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.

После этого у покупателя в телеграме придет сообщение такого вида:

При нажатии оплатить покупатель вводит данные о доставке, если указан аттрибут is_flexible, если нет, то сразу будет предложено ввести данные о карте и оплатить продукт.

Но, в примере я указал что на сумму продукта так же влияет адрес доставки, поэтому вместо платежных данных мне будет предложено ввести данные о доставке. Потом эти данные через вебхук отправляются к нам на сервер, принимать эти данные стоит вот так:

try {
    $bot = new \TelegramBot\Api\Client(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 (\TelegramBot\Api\Exception $e) {
    $e->getMessage();
}

Я показал только ответ сервера, данные все лежат в переменной $query. (Эти массивы в ответе самого напрягают и когда то я до них доберусь и переделаю под объекты).

В итоге в телеграм придет вот такой ответ с вариантами доставки:

Выбрав вариант доставки мне предложат ввести данные о платеже, заполнив которые я получу уже счет, в котором посчитана общая цена и выведена информация за продукт:

После того как покупатель нажмет кнопку "Pay" на вебхук уйдет ещё один запрос, в котором будет доступна вся эта информация, и нужно будет ответить в течении 10 секунд информация верна или нет:

try {
    $bot = new \TelegramBot\Api\Client(env('BOT_TOKEN'));
    $bot->preCheckoutQuery(function ($query) use ($bot, $botApi) {
        $botApi->answerPreCheckoutQuery($query->getId(), true); //Говорим что всё хорошо, товар есть на складе и готовы отправить
    });
    $bot->run();
} catch (\TelegramBot\Api\Exception $e) {
    $e->getMessage();
}

В случае если что-то не так, нужно ещё указать текст ошибки, который будет отображаться в телеграме, если мы сказали что всё хорошо - телеграм отправляет данные в платежную систему и снимает деньги.

В итоге получим сообщение в чате что деьги переведены и можем посмотреть счет по товару вместо кнопки оплаты:


Вот так просто реализованы платежы,если не указывать доставку всё сводится к последнему шагу, на PHP тоже как видите работы не много, конечно я привел простой пример, полей на самом деле при создании продукта на много больше, ознакомится можно в самой библиотеке или на официальном сайте.

Комментарии (1)

  1. Сергей 11 месяцев назад / Reply
    А можно файлом приложить полный код скрипта? По частям вроде все понятно но не выходит каменный цветок(