Как принимать платежи в Telegram | Оплата без всяких токенов и асинхронная обработка платежа

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Введение

В прошлой статье я рассказывал о том, как можно при помощи регистрации своего телеграм бота или сайта в клиенте Yoomoney получать токен и с его помощью получать доступ к информации об аккаунте (истории операций, деталей операций и информации о счете), это в принципе единственный вариант получить доступ к этим данным и в целом это позволяло как-то проверять оплату на своем сайте или в телеграм боте, но все же с точки зрения пользователя такой подход в котором ему нужно прикладывать какие-то усилия для того, чтобы произвести банальную оплату явно не лучший вариант, всегда хочется все сделать уже привычным способом, а именно просто ввести данные с карты и получить услугу или товар. В этой статье мы научимся это делать! Все, что вам нужно это ваш ip адрес или доменное имя и порт.

Описание

  • Настройка уведомлений

  • Создание ссылки для оплаты

  • Проверка оплаты

Как я уже сказал все, что вам нужно это ip адрес вашего хостинга или доменное имя и порт. Я буду пользоваться утилитой Ngrok, для тех кто не знает, Ngrok - это такой инструмент который позволяет создать защищенное туннельное соединение между локальным компьютером и интернетом. Он позволяет временно выставить локальный сервер или другие локальные сервисы наружу, делая их доступными через общедоступный url, короче говоря ваш localhost будет доступен из внешней сети «интернет».

Весь туториал есть на GitHub проекта.

Настройка уведомлений

Заходим в кошелек ЮMoney. Если кошелька нет, создаем его, после этого нам нужно подключить HTTP/HTTPS уведомления к нашему кошельку Yoomoney.

  1. Указываем url на который хотим принимать уведомления и обязательно сохраняем секретное слово (оно нам еще понадобиться).

  2. Ставим галочку "Отправлять HTTP-уведомления".

  3. Нажимаем кнопку "Готово".

Отлично, наш кошелек готов к отправке уведомлений!

Для дальнейших действий нам понадобиться библиотека yoomoney-api, ее можно установить с помощью следующей CLI команды:

dotnet add package yoomoney-api --version 1.4.0

вставляем код, изменяем нужные вам параметры и запускаем его:

using yoomoney_api.notification;
using yoomoney_api.quickpay;
using static System.Console;

var label = Guid.NewGuid().ToString();
var quickpay = new Quickpay(receiver: "4100118408605024", quickpayForm: "shop", sum: 10, 
	label: label, paymentType: "AC"); //Payment method. Possible values: PC - payment from the YuMoney wallet; AC - from a bank card.
WriteLine(quickpay.LinkPayment);

//заменяем --> ("YOUR_IP_ADDRESS_OR_DNS_NAME","NOTIFICATION_SECRET",YOUR_PORT")
PaymentListenerToYooMoney paymentListenerToYooMoney = new(label,DateTime.Today,"NOTIFICATION_SECRET");
var resultPayment = await paymentListenerToYooMoney.Listen("YOUR_IP_ADDRESS_OR_DNS_NAME","YOUR_PORT");
WriteLine(resultPayment);

в свойстве quickpay.LinkPayment будет находится ссылка для оплаты, а так же в консоли отобразиться следующая информация:

https://yoomoney.ru/transfer/quickpay?requestId=353432303336353332305f39366662343561383966646635393039633365396165366566656231366237383762333062346237

IP-appec: XXX.X.X.X // Доменное имя: https://XXXXXXXXXXX, IP: XX.XXX.XXX.XX
Сервер запущен. Ожидание подключений...

Что произойдет в приложении на данном этапе? В данный момент у нас выполниться код который отправит на сервер Yoomoney указанные вами параметры и вернет ссылку для оплаты, а так же асинхронно сервер будет ожидать TCP подключений в течении 12 минут или до успешной оплаты (почему именно 12 расскажу далее), после чего его время жизни будет перкращено.

Какие наши следующие действия?
Прежде чем проводить оплату давайте все-таки проверим, что все работает. Для этого нам нужно перейти на страницу, на которой мы подключали уведомления и нажать кнопку "Протестировать".

ngrok                                                                                                                                                                                               (Ctrl+C to quit)

Build better APIs with ngrok. Early access: ngrok.com/early-access

Session Status                online
Account                       arabaleevdennis@gmail.com (Plan: Free)
Version                       3.4.0
Region                        Europe (eu)
Latency                       56ms
Web Interface                 http://127.0.0.1:4040
Forwarding                    https://urchin-intimate-uniformly.ngrok-free.app -> http://127.0.0.1:3000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              4       0       0.01    0.01    0.01    0.05

HTTP Requests
-------------

POST /
POST /

Отлично, Ngrok показывает 2 POST / запроса, смотрим что же у нас там в консоли программы:

/Users/lilrockstar/RiderProjects/ConsoleApp7/ConsoleApp7/bin/Debug/net7.0/ConsoleApp7
https://yoomoney.ru/transfer/quickpay?requestId=353432313036303037355f31316533343866613130336137623165386531626634393566633231643731326465363137303431

IP-appec: 127.0.0.1
Сервер запущен. Ожидание подключений...

Подключен клиент.
Не текущий платеж...

Подключен клиент.
Не текущий платеж...

а наша программа отлично приняла эти 2 запроса. Я не стал обозначать тестовые запросы, по этому программа нам указывает на то, что это не текущий платеж (так как это не платеж, а просто тестовый запрос).

Проверка оплаты

Теперь нам осталось перейти по ссылке и произвести оплату (программу можно не перезапускать). После того как мы перешли по ссылке, ввели данные карты и код, нам нужно дождаться уведомления об оплате от нашего банка с которого мы оплачиваем, уведомление о списании придет раньше чем о зачислении. Как только пришло уведомление о списании денег в Ngrok поступил еще один пост запрос:

ngrok                                                                                                                                                                                               (Ctrl+C to quit)

Build better APIs with ngrok. Early access: ngrok.com/early-access

Session Status                online
Account                       arabaleevdennis@gmail.com (Plan: Free)
Version                       3.4.0
Region                        Europe (eu)
Latency                       56ms
Web Interface                 http://127.0.0.1:4040
Forwarding                    https://urchin-intimate-uniformly.ngrok-free.app -> http://127.0.0.1:3000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              4       0       0.01    0.01    0.01    0.05

HTTP Requests
-------------

POST /
POST /
POST /

отлично, проверяем консоль нашего приложения:

/Users/lilrockstar/RiderProjects/ConsoleApp7/ConsoleApp7/bin/Debug/net7.0/ConsoleApp7
https://yoomoney.ru/transfer/quickpay?requestId=353432313036303037355f31316533343866613130336137623165386531626634393566633231643731326465363137303431

IP-appec: 127.0.0.1
Сервер запущен. Ожидание подключений...

Подключен клиент.
Не текущий платеж...

Подключен клиент.
Не текущий платеж...

Подключен клиент.
HTTP Requests
-------------

POST /
Текущий платеж:
        NotificationType   --> card-incoming
        OperationId        --> 753616322448916124
        DateTime           --> 2023-11-18 13:52
        Amount             --> 9.70
        WithdrawAmount     --> 10.00
        Firstname          -->  Null
        Lastname           -->  Null
        Fathersname        -->  Null
        Email              -->  Null
        Phone              -->  Null
        City               -->  Null
        Street             -->  Null
        Building           -->  Null
        Suite              -->  Null
        Flat               -->  Null
        Zip                -->  Null
        Sender             -->  Null
        Unaccepted         --> false
        Codepro            --> false
        Currency           --> 643
        Label              --> 8cfc9e98-ce15-4187-9b1b-e30a07c336a1

Успешно!
Сервер завершил работу

Ура, мы отследили наш платеж!

Что произойдет в приложении на данном этапе?
После того как к нам придет в консоль "Подключен клиент", приложение асинхронно установит TCP соединение с Yoomoney и будет ожидать HTTP POST / или HTTPS POST / запрос, после того как данные придут, создастся массив байтов в который из потока мы прочитаем данные запроса, но почему мы уверены что это именно наш платеж и он пришел именно от Yoomoney?

Все просто, дело в том, что у нас есть такой уникальный параметр как Label который мы передаем при создании ссылки для оплаты, этот параметр прикрепляется к платежу и приходит нам обратно с уведомлением. Так же параметр DateTime который тоже возвращается в запросе, и вот тут нам пригождается наше секретное слово, на основе переданных параметров Yoomoney генерирует хеш который приходит нам параметром sha1_hash .

Для менее опытных следует сказать, что конечно стоит закреплять каждый платеж пользователя за этим самым пользователем (например в бд, достаточно сохранять туда дату, параметр label и amnount, этого достаточно, чтобы отследить любой платеж).

На этапе обработки запроса наша программа тоже генерирует хеш-код на основе параметров запроса вместе с уникальным label который мы создали при генерации ссылки и серкетным словом которое мы получили при регистрации уведомлений. После того как все данные приняты мы сверяем параметры: label + DataTime.Date + sha1_hash из запроса с нашими сохраненными, если все эти данные совпадают платеж считается "Успешным".

Почему именно 12 минут? Дело в том, что Yoomoney после успешного пополнения счета отправляет на зарегистрированный url 3 уведомления (сразу после поступления средств на текущий счет, через 10 и через час), логично предположить, что если уведомление не пришло сразу и через 10 минут, оно не придет и через час, 2 минуты выделяется на то, чтобы пользователь произвел оплату (при нормальных обстоятельствах этого вполне достаточно), если он не уложится в эти 2 минуты, то 10 минут ему точно предостаточно! Если же после оплаты при нормальных обстоятельствах сообщение не придет сразу, то оно отследится через 10 минут. Если же все-таки каким-то загадочным образом платеж зачислился, но уведомление не пришло, то мы берем datetime и label этого платежа и обращаемся к коду предыдущей статьи, благодаря которому мы можем получить доступ к истории операций и по указанным параметрам его найти и проверить параметр status является ли он success ( то есть успешным). Следует сделать вывод: "Не один платеж не останется незамеченным, если средства действительно поступили насчет".


Так же стоит отметить, что только по протоколу HTTPS можно будет иметь доступ к контактной информации (однако в текущей версии api с этим возникаю проблемы, а поддержка Yoomoney пока что игнорирует вопросы и прозьбы)

пример того как должно было быть:

var quickpay = new Quickpay(
	receiver: "4100118408605024",
	quickpayForm: "shop",
	sum: 10, 
	label: label,
	paymentType: "AC",
	firstname:"Oleg",
	lastname:"Olegov",
	fathersname:"Olegovich",
	city:"Saint Petersburg",
	street:"Begovaya street",
	zip:"197374",
	building:"11",
	suite:"1",
	flat:"43",
	phone:"+7987674115",
	sender:"4100167987654");

//replace --> ("YOUR_IP_ADDRESS_OR_DNS_NAME","NOTIFICATION_SECRET",YOUR_PORT")
PaymentListenerToYooMoney paymentListenerToYooMoney = new(label,DateTime.Today,"NOTIFICATION_SECRET");
var resultPayment = await paymentListenerToYooMoney.Listen("YOUR_IP_ADDRESS_OR_DNS_NAME","YOUR_PORT");
WriteLine(resultPayment);

вывод:

Подключен клиент.
HTTP Requests
-------------

POST /
Текущий платеж:
        NotificationType   --> card-incoming
        OperationId        --> 753525659460074104
        DateTime           --> 2020-01-12 01:22
        Amount             --> 9.70
        WithdrawAmount     --> 10.00
        Firstname          -->  Oleg
        Lastname           -->  Olegov
        Fathersname        -->  Olegovich
        Email              -->  Oleg@gmail.com
        Phone              -->  +79957773555
        City               -->  Saint Petersburg
        Street             -->  Begovaya street
        Building           -->  11
        Suite              -->  1
        Flat               -->  43
        Zip                -->  197374
        Sender             -->  4100167987654
        Unaccepted         --> false
        Codepro            --> false
        Currency           --> 643
        Label              --> 560bb09d-5986-38e9-abf8-cl59f21c0bh5

Успешно!
Сервер завершил работу

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

Отлично, теперь мы можем принимать платежи!

Заключение

Если данный пост вам помог, то поставьте звезду на GitHub. Мне будет очень приятно!

Источник: https://habr.com/ru/articles/774818/


Интересные статьи

Интересные статьи

Привет, Хабр! Меня зовут Роман Орлов, я Lead Software Test Automation Engineer в EPAM. Работал на разных платформах (Web, Desktop, Mobile) с разными типами тестов (UI, API, Unit-тесты) и архитект...
Не так давно опубликовал статью об экспресс-создании бота для Telegram на фреймворке SKitLs.Bots.Telegram. С тех пор внутренний состав фреймворка солидно изменился, вместе с тем были выпущены предвари...
Приветствую сообщество.Бот Telegram @wallet недавно предоставил API для приема платежей в сторонних Telegram ботах. Из крипто валют поддерживаются BTC, TON, USDT.Необходимо зарегистрироваться на сайте...
Идея В диалогах телеграма я очень часто использую телеграм бот: inlatexbot. Он позволяет вставлять Latex прямо в диалоге телеграма — это удобно: математическое обозначение можно отпр...
Недавно сидел я в одном сообществе программистов в Telegram и заметил один очень любопытный профиль. Любопытным было следующее — на главном фото у него было изображено нынешнее время. Мне стало ж...