How to create SendInvoice
Hello, I need the full example of bot.sendInvoice, examples from core.telegram and so on are not understandable for me. If you worked with bot.sendInvoice or with all functions of Invoice, pls send me examples. Thanks
Is simple :)
First go to BotFather and follow instruction to link Stripe account (/mybots > bot > payments). Then you have a test token and production token, for testing use test token (to avoid pay yourself, lol).
Then use this code:
bot.onText(/pay/i, function (message) {
var iKeys = [];
iKeys.push([{
text: "2 €",
callback_data: "pay:2.00"
},{
text: "10 €",
callback_data: "pay:10.00"
}]);
bot.sendMessage(message.chat.id, "Select an amount to pay", {
parse_mode: 'HTML',
disable_web_page_preview: true,
reply_markup: {
inline_keyboard: iKeys
}
});
});
bot.on('callback_query', function (message) {
var StripeToken = "xxx";
var func = text.split(":")[0];
var param = text.split(":")[1];
if (func == "pay") {
var payload = player_id + Date.now() + param; // you can use your own payload
var prices = [{
label: "Donation",
amount: parseInt(param.replace(".", "")) // if you have a decimal price with . instead of ,
}];
bot.sendInvoice(message.from.id, "Donation", "Donation of " + param + "€", payload, StripeToken, "pay", "EUR", prices); // send invoice button to user
// remember to save payload and user data in db, it will be useful later
// usually i save Payload and Status = WAIT
}
});
bot.on('message', function (message) {
if (message.successful_payment != undefined) {
var savedPayload = "yyy"; // get from db
var savedStatus = "zzz"; // get from db, this should be "WAIT"
if ((savedPayload != message.successful_payment.invoice_payload) || (savedStatus != "WAIT")) { // match saved data to payment data received
bot.sendMessage(message.chat.id, "Payment verification failed");
return;
}
// payment successfull
bot.sendMessage(message.chat.id, "Payment complete!");
}
});
If you need further info please answer ;)
Oh thank you very much, but why we should use "payload","provider_data" and "start_parameter" what is the sense of them?
- For check reason: if a user send manual payload and not match with your, transaction will fail.
- For history reason: if you save all payloads you can later use as you need (statistics, etc.).
do you know, how to change the text in the inline button of the invoice? For example, now it's "Pay 1000 UZS", but I need "Make a payment". And how to get the users phone? Because there are not enough functions in node-telegram-bot-api in sendInvoice
I don't think you can do it, cause a bad user can replace text with fake description and trick people. I'm not totally sure but... maybe at 90%.
oh okay, thank you very much for your help
I have a problem, I'm already desperate. When i tried to pay in test mode with stripe he shows me "timeout" and never confirm the pay, why is this problem happening? Any ideas?
@AHGsystems Maybe you have not enabled payments in Botfather? Anyway check in Stripe Dashboard, there is a calls history that you can use for debugging.
I am new and I am desperate, I can't find a way to process the payment, it simply answers me with a "timeout". This is my code //-------------------------------------------------------------
const TelegramBot = require('node-telegram-bot-api'); const token = 'yyyyyyyyyyyyyyy:xxxxxxxxxxxxxxxx';
const bot = new TelegramBot(token, {polling: true});
bot.onText(/pay/i, function (message) { var iKeys = []; iKeys.push([{ text: "2 €", callback_data: "pay:2.00" },{ text: "10 €", callback_data: "pay:10.00" }]);
bot.sendMessage(message.chat.id, "Select an amount to pay", {
parse_mode: 'HTML',
disable_web_page_preview: true,
reply_markup: {
inline_keyboard: iKeys
}
});
}); bot.on('callback_query', function (message) { var StripeToken = "-------------:TEST:-----------------";
var payload = "12345" + Date.now() + "pay";// you can use your own payload
var prices = [{
label: "Donation",
amount: parseInt("1000") // if you have a decimal price with . instead of ,
}];
bot.sendInvoice(message.from.id, "Donation", "Donation of " + "pay"+ "€", payload, StripeToken, "pay", "EUR", prices); // send invoice button to user
// remember to save payload and user data in db, it will be useful later
// usually i save Payload and Status = WAIT
});
bot.on('message', function (message) {
if (message.successful_payment != undefined) {
var savedPayload = "12345" + Date.now() + "pay"; // get from db
var savedStatus = "WAIT"; // get from db, this should be "WAIT"
if ((savedPayload != message.successful_payment.invoice_payload) || (savedStatus != "WAIT")) { // match saved data to payment data received
bot.sendMessage(message.chat.id, "Payment verification failed");
return;
}
// payment successfull
bot.sendMessage(message.chat.id, "Payment complete!");
}
});
@AHGsystems Have you enabled Payments with Botfather? Anyway try to put some logs everywhere to find where it stops.

YES, I have enabled and connected the TEST stripe payment
Hello Sidelux. I have the very same problem as AHGsystems. I have connected a Stripe TEST account to my Telegram bot. When fired, the Stripe bot runs, asks me my (fake) credit card data (any of the ones suggested in https://stripe.com/docs/testing#cards) but it times out. The Stripe dashboard reports no traffic. Should I try a real world payment? (If so, what is test mode for?) Thank you for your help
I am having the same issue. Does anyone find a solution ?
do you answer the pre_checkout_query during press pay button
do you answer the pre_checkout_query during press pay button
I have this fault. why don't answer the pre_checkout_query during press pay button ? do anyone know ?
I am using telegram TEST payment ....
do you answer the pre_checkout_query during press pay button
can i have an example?
Is simple :)
First go to BotFather and follow instruction to link Stripe account (/mybots > bot > payments). Then you have a test token and production token, for testing use test token (to avoid pay yourself, lol).
Then use this code:
bot.onText(/pay/i, function (message) { var iKeys = []; iKeys.push([{ text: "2 €", callback_data: "pay:2.00" },{ text: "10 €", callback_data: "pay:10.00" }]); bot.sendMessage(message.chat.id, "Select an amount to pay", { parse_mode: 'HTML', disable_web_page_preview: true, reply_markup: { inline_keyboard: iKeys } }); }); bot.on('callback_query', function (message) { var StripeToken = "xxx"; var func = text.split(":")[0]; var param = text.split(":")[1]; if (func == "pay") { var payload = player_id + Date.now() + param; // you can use your own payload var prices = [{ label: "Donation", amount: parseInt(param.replace(".", "")) // if you have a decimal price with . instead of , }]; bot.sendInvoice(message.from.id, "Donation", "Donation of " + param + "€", payload, StripeToken, "pay", "EUR", prices); // send invoice button to user // remember to save payload and user data in db, it will be useful later // usually i save Payload and Status = WAIT } }); bot.on('message', function (message) { if (message.successful_payment != undefined) { var savedPayload = "yyy"; // get from db var savedStatus = "zzz"; // get from db, this should be "WAIT" if ((savedPayload != message.successful_payment.invoice_payload) || (savedStatus != "WAIT")) { // match saved data to payment data received bot.sendMessage(message.chat.id, "Payment verification failed"); return; } // payment successfull bot.sendMessage(message.chat.id, "Payment complete!"); } });If you need further info please answer ;)
Quite unfortunate , I got an exception raised:
Unhandled rejection Error: ETELEGRAM: 400 Bad Request: can't parse prices JSON object
Alternatively, I use RESTFUL API method instead :
Method: GET
const sendInvoice = async (chatId, product, description, payload, currency, price) => {
// https://core.telegram.org/bots/payments#supported-currencies
const url = `https://api.telegram.org/bot${BOT_oken}/sendInvoice`;
const response = await axios.get(url, {
params: {
chat_id: chatId,
title: product,
description: description,
payload: payload,
provider_token: YOUR_payment_token,
currency: currency,
prices: JSON.stringify([
{
label: product,
amount: price,
},
]),
}
});
console.log(response.data);
};