How to accept payments in Telegram
Introduction
In the last article, I talked about how you can, by registering your telegram bot or website in the Yoomoney client, receive a token and with its help gain access to account information (transaction history, transaction details and account information), this is, in principle, the only option gain access to this data and, in general, this allowed you to somehow check the payment on your website or in a telegram bot, but still, from the user’s point of view, such an approach in which he needs to make some effort in order to make a banal payment is clearly not the best option, you always want to do everything in the usual way, namely, simply enter the data from the card and receive a service or product. In this article we will learn how to do this! All you need is yours ip address or domain name and port.
Description
Setting up notifications
Creating a payment link
Payment verification
Like I said all you need is ip your hosting address or domain name and port. I will use the utility Ngrokfor those who don’t know, Ngrok is a tool that allows you to create a secure tunnel connection between your local computer and the Internet. It allows you to temporarily expose a local server or other local services to the public, making them available through a public urlin short, yours localhost will be accessible from the external Internet network.
The entire tutorial is available at GitHub of the project.
Setting up notifications
Go to your YuMoney wallet. If you don’t have a wallet, let’s create itafter that we need to connect HTTP/HTTPS notifications to our Yoomoney wallet.
We indicate url for which we want to receive notifications and be sure to save the secret word (we will need it later).
Check the box “Send HTTP notifications”.
Press the button “Ready”.
Great, our wallet is ready to send notifications!
For further actions we need the yoomoney-api library, it can be installed using the following CLI command:
dotnet add package yoomoney-api --version 1.4.0
paste the code, change the parameters you need and run it:
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);
in property quickpay.LinkPayment
There will be a link for payment, and the following information will be displayed in the console:
https://yoomoney.ru/transfer/quickpay?requestId=353432303336353332305f39366662343561383966646635393039633365396165366566656231366237383762333062346237
IP-appec: XXX.X.X.X // Доменное имя: https://XXXXXXXXXXX, IP: XX.XXX.XXX.XX
Сервер запущен. Ожидание подключений...
What will happen in the application at this stage? At the moment, we are running a code that will send the parameters you specified to the Yoomoney server and return a link for payment, and the server will also wait asynchronously TCP connections within 12 minutes or until successful payment (I’ll explain why exactly 12 later), after which its lifetime will be terminated.
What are our next steps?
Before making a payment, let’s check that everything is working. To do this we need to go to the page where we connected notifications and press the button “Test.”
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 /
Great, Ngrok shows 2 POST / request, let’s see what we have there in the program console:
/Users/lilrockstar/RiderProjects/ConsoleApp7/ConsoleApp7/bin/Debug/net7.0/ConsoleApp7
https://yoomoney.ru/transfer/quickpay?requestId=353432313036303037355f31316533343866613130336137623165386531626634393566633231643731326465363137303431
IP-appec: 127.0.0.1
Сервер запущен. Ожидание подключений...
Подключен клиент.
Не текущий платеж...
Подключен клиент.
Не текущий платеж...
and our program accepted these 2 requests perfectly. I did not indicate test requests, so the program indicates to us that this is not a current payment (since this is not a payment, but just a test request).
Payment verification
Now all we have to do is follow the link and make the payment (you don’t have to restart the program). After we have followed the link, entered the card details and code, we need to wait for a payment notification from our bank from which we pay; the debit notification will arrive earlier than the credit notification. As soon as you receive a notification about the debit of money in Ngrok I received another post request:
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 /
great, let’s check the console of our application:
/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
Успешно!
Сервер завершил работу
Hurray, we tracked our payment!
What will happen in the application at this stage?
After it comes to our console “Client connected“, the application will install asynchronously TCP connection with Yoomoney and will wait HTTP POST / or HTTPS POST / request, after the data arrives, an array of bytes will be created into which we will read the request data from the stream, but why are we sure that this is our payment and it came from Yoomoney?
It’s simple, the fact is that we have such a unique parameter as Label
which we pass when creating a payment link, this parameter is attached to the payment and comes back to us with a notification. Also the parameter DateTime
which is also returned in the request, and this is where our secret word comes in handy; based on the passed parameters, Yoomoney generates a hash that comes to us as a parameter sha1_hash
.
For those less experienced, it should be said that, of course, it is worth assigning each user payment to this same user (for example, in a database, it is enough to save the date, parameter label And amnountthis is enough to track any payment).
At the request processing stage, our program also generates a hash code based on the request parameters along with a unique label
which we created when generating the link and the serket word that we received during registration notifications. After all the data has been accepted, we check the parameters: label + DataTime.Date + sha1_hash from the request with our saved ones, if all this data matches the payment is considered “Successful.”
Why exactly 12 minutes? The fact is that after successful replenishment of the account, Yoomoney sends to the registered url 3 notifications (immediately after receipt of funds to the current account, after 10 and after an hour), it is logical to assume that if the notification did not arrive immediately and after 10 minutes, it will not arrive even after an hour, 2 minutes are allocated for the user to make payment ( under normal circumstances this is quite enough), if he does not fit into these 2 minutes, then 10 minutes is definitely enough for him! If after payment under normal circumstances the message does not arrive immediately, it will be tracked after 10 minutes. If, nevertheless, in some mysterious way the payment was credited, but the notification did not arrive, then we charge datetime And label this payment and refer to the code of the previous article, thanks to which we can access transaction history And using the specified parameters, find it and check the parameter status is he success (that is, successful). It should be concluded: “Not a single payment will go unnoticed if the funds have actually been received.”
It is also worth noting that only via the HTTPS protocol it will be possible to have access to contact information (however, in the current version of the api there are problems with this, and Yoomoney support is currently ignoring questions and requests)
An example of how it should have been:
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);
conclusion:
Подключен клиент.
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
Успешно!
Сервер завершил работу
But there’s nothing wrong with that, considering that according to the unique parameter label we can track any user, this does not cause any problems.
Great, now we can accept payments!
Conclusion
If this post helped you, please rate it GitHub. I will be very pleased!