Cat

AIOgram3 18. Подключаем оплату Telegram Stars

В Telegram вводится новая валюта — Stars. Stars позволят производить покупку цифровых товаров и услуг. Введение нового способа оплаты влечёт за собой отключение всех остальных платёжных средств. Причины таких изменений оставим за скобками и сосредоточимся на том, как внедрить в Telegram-бота новый способ оплаты — Telegram Stars.

Все статьи

Icon Link

Дополнительные материалы

Icon Link

Реклама

Icon Link
Telegram-бот на AIOgram3 proDream 13 Июнь 2024 Просмотров: 2019

6 июня Павел Дуров сообщил, что в Telegram вводится новая валюта — Stars. Stars позволят производить покупку цифровых товаров и услуг, проще говоря, оплачивать покупки внутри Telegram, например, в ботах или в MiniApps. Однако не всё так радужно. Введение нового способа оплаты влечёт за собой отключение всех остальных платёжных средств. Если ваш бот принимал оплату через ЮКассу, то теперь только "Звёзды". Причины таких изменений оставим за скобками и сосредоточимся на более важных вещах, а именно на том, как внедрить в Telegram-бота новый способ оплаты — Telegram Stars.

Приобрести звёзды можно, открыв настройки Telegram и найдя пункт "Звёзды Telegram".

 

Стоит отметить. На момент написания не было актуальной информаций по тому, как и где использовать полученные от пользователей звёзды. Статья будет дополняться по мере обновления информации от Telegram. Если вам что-то известно, сообщите нам!

 

Обновление зависимостей.

Для полноценной поддержки нового способа оплаты требуется версия AIOgram 3.7.0. Для обновления библиотеки достаточно выполнить команду:

pip install -U aiogram

 

После этого обновите версию в файле requirements.txt.

aiogram==3.7.0

 

Кнопка оплаты.

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

В пакете botlogic создадим новый пакет keyboards, а в нём файл payment_keyboard.py.

Пропишем функцию payment_keyboard, которая ничего не принимает.

В теле функции создадим переменную builder, в которой определим экземпляр класса InlineKeyboardBuilder.

В него можно передать список списков с объектами класса кнопки, но это не совсем удобно, проще пользоваться методами класса. На следующей строке вызываем у объекта класса метод .button, добавляющий кнопку в сборщик клавиатуры. Передаём два аргумента:

  • text — Определяет текст на кнопке. Если в тексте будет XTR или эмодзи звезды ⭐️, оно автоматически заменится на иконку Telegram Stars.
  • pay — Определяет тип кнопки как кнопку для оплаты.

Далее делаем возврат переменной builder, применив к ней метод .as_markup, чтобы получить объект готовой к размещению в сообщении клавиатуры.

 

Код файла:

from aiogram.utils.keyboard import InlineKeyboardBuilder  


def payment_keyboard():  
    builder = InlineKeyboardBuilder()  
    builder.button(text=f"Оплатить 20 ⭐️", pay=True)  

    return builder.as_markup()

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

 

Обработчик выставления счёта.

Приступим к написанию обработчика команды.

В пакете handlers создадим файл payment.py.

В этом файле пропишем асинхронную функцию send_invoice_handler, принимающую message — объект класса Message.

Создадим переменную prices, в которую поместим список с объектами класса LabeledPrice, вернее, с одним объектом, так как для оплаты через Telegram Stars этот список должен состоять из одного элемента. В объект класса передаём следующие аргументы:

  • label — Определение валюты. В нашем случае это XTR.
  • amount — Стоимость в звёздах.

Далее у переменной message вызываем метод .answer_invoice, чтобы бот ответил на сообщение пользователя кнопкой со счётом на оплату. В метод передаём следующие аргументы:

  • title — Название платежа, товара или услуги.
  • description — Описание платежа, товара или услуги.
  • prices — Список объектов LabeledPrice, определённый ранее в одноимённой переменной.
  • provider_token — Токен платёжной системы, для Telegram Stars просто отправляем пустую строку.
  • payload — Маркировка платежа. Она не отображается пользователю, а может использоваться для разделения платежей по их типам и так далее. Максимум 128 байт данных (в Python один символ занимает один байт, но стоит учитывать, что специальные символы или эмодзи могут занимать больше места).
  • currency — Валюта платежа, для Telegram Stars это XTR.
  • reply_markup — Объект клавиатуры.

 

Код обработчика:

from aiogram.types import LabeledPrice, Message  

from botlogic.keyboards.payment_keyboard import payment_keyboard  


async def send_invoice_handler(message: Message):  
    prices = [LabeledPrice(label="XTR", amount=20)]  
    await message.answer_invoice(  
        title="Поддержка канала",  
        description="Поддержать канал на 20 звёзд!",  
        prices=prices,  
        provider_token="",  
        payload="channel_support",  
        currency="XTR",  
        reply_markup=payment_keyboard(),  
    )

 

Предпродажная проверка.

Счёт выставлен, пользователь нажимает "Оплатить". Если у него не хватает звёзд, система предложит их приобрести. Если звёзд у него хватает, он произведёт оплату, и в этот момент Telegram пришлёт в бота запрос "точно ли всё хорошо?". На ответ у нас будет ровно 10 секунд. Если мы по каким-то причинам не хотим принимать оплаты у данного пользователя или логика бота настроена на отмену платежа, в таком случае необходимо дать ответ, сигнализирующий об отмене платежа, сопроводив его причиной отмены. В противном же случае, подтверждаем, что всё "Ок".

В этом же файле создадим асинхронную функцию pre_checkout_handler, принимающую аргумент pre_checkout_query — объект класса PreCheckoutQuery.

В теле функции у переменной pre_checkout_query вызываем метод .answer, передавая в него аргумент ok со значением True.

 

Код функции:

from aiogram.types import PreCheckoutQuery


async def pre_checkout_handler(pre_checkout_query: PreCheckoutQuery):  
    await pre_checkout_query.answer(ok=True)

 

Информирование о покупке.

Бюрократия позади, осталось только поздравить пользователя с покупкой!

В этом же файле создадим асинхронную функцию success_payment_handler, принимающую аргумент message — объект класса Message.

В объекте класса Message хранится различная информация о текущем сообщении, а в поле successful_payment находится информация о платеже, такая, как идентификатор платежа, сумма, валюта, информация, полученная от пользователя. По-хорошему, это всё необходимо сохранить во избежание возможных вопросов по платежам в будущем.

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

 

Код функции:

async def success_payment_handler(message: Message):  
    await message.answer(text="🥳Спасибо за вашу поддержку!🤗")

 

Команда paysupport и немного про возврат средств.

Telegram также предъявляет условия к возврату средств пользователям. Не за все товары и услуги подразумевается возврат средств, однако у пользователя всё равно должна быть возможность запросить возврат средств, либо быть проинформированным касательно этого.

Для информирования пользователя обязательно должна быть команда /paysupport. В ней можно указать условия возврата, контактные данные и др. Давайте сделаем эту команду.

Создадим асинхронную функцию pay_support_handler, принимающую message — объект класса Message. В теле функции пропишем ответ на сообщение с текстом, описывающим условия для возврата средств.

 

Код функции:

async def pay_support_handler(message: Message):  
    await message.answer(  
        text="Добровольные пожертвования не подразумевают возврат средств, "  
        "однако, если вы очень хотите вернуть средства - свяжитесь с нами."    )

 

Непосредственно возврат средств можно сделать доступным пользователю. Для этого необходимо создать обработчик команды возврата, в котором, обращаясь к методу .refund_star_payment у объекта Bot, передать в него user_id и telegram_payment_charge_id.

  • user_id — Telegram-ID пользователя, запрашивающего возврат средств.
  • telegram_payment_charge_id — Идентификатор платежа, совершённого пользователем.

 

Регистрация обработчиков.

Всё готово, осталось зарегистрировать обработчики в main.py.

Откроем файл main.py и в функции start добавим четыре регистрации:

  1. send_invoice_handler — Регистрируем как обычное сообщение, указав фильтр команды donate.
  2. pre_checkout_handler — Регистрируем как событие pre_checkout_query.
  3. success_payment_handler — Регистрируем как обычное сообщение. В качестве фильтра используем так называемый "Магический фильтр F", представляющий собой объект Message. В фильтре обращаемся к полю successful_payment. Если оно не пустое (успешная оплата), будет вызван обработчик.
  4. pay_support_handler — Регистрируем как обычное сообщение с фильтром на команду paysupport.
from aiogram import F


dp.message.register(payment.send_invoice_handler, Command(commands="donate"))
dp.pre_checkout_query.register(payment.pre_checkout_handler)
dp.message.register(payment.success_payment_handler, F.successful_payment)
dp.message.register(payment.pay_support_handler, Command(commands="paysupport"))

 

Тестирование.

Запустим бота и выполним команду /donate.

 

Получим сообщение с информацией о платеже и кнопкой-счётом. Нажмём на кнопку.

Откроется окно с подтверждением оплаты (если у вас нет звёзд — откроется окно приобретения, как на первом скриншоте в начале поста). Нажимаем "Подтвердить и заплатить".

 

В чате выстрелит конфетти, и мы увидим сообщение об успешном платеже.

 

Заключение.

Нововведение, конечно, всех удивило и немного застало врасплох. На переход дали мало времени, и наверняка не все даже узнали об этом. Интересно будет посмотреть, к чему всё это приведёт.

Автор

  • 3 сентября 2024 г. 16:35

    Классная статья. Я сейчас как раз учусь писать бота и данная статья даёт некое ознакомление с системой оплаты. Конечно пример тут самый элементарный, но новичкам этого достаточно чтоб потом написать что-то более сложное добавив к этим знаниям знания документации.

  • Реклама