Payment Processing Fails with Timeout in Telegram Bot Using Stripe Test Environment

I’m working on a Node.js Telegram bot that downloads video content from social media posts. Everything works fine, but I want to add a payment system where users need to pay after making a few requests.

I implemented payment functionality using Telegram’s invoice system with Stripe as the payment provider in test mode. The issue occurs when users try to complete the payment - they can enter their card details, but the payment just keeps loading and eventually times out.

I tried both the invoice sending method and creating payment links, but both have the same timeout problem. I’m directly using Telegram API endpoints without any external libraries.

Here’s my payment implementation:

const server = express();
const serverPort = 8080;

const telegramToken = process.env.BOT_TOKEN;
server.use(bodyParser.json());

// Bot webhook handler
server.post(`/webhook${telegramToken}`, async (req, res) => {
  const { message } = req.body;

  console.log({ message });

  if (message && message.text) {
    const userId = message.chat.id;
    const userMessage = message.text;

    // Send payment request after user reaches limit

    const paymentResult = await createPaymentInvoice(
      userId,
      "Pro Access",
      "Get unlimited downloads with pro access.",
      "pro_access_payment",
      process.env.STRIPE_TOKEN,
      "access",
      "USD",
      [{ label: "Pro Access", amount: 500 }],
    );

    console.log(JSON.stringify(paymentResult, null, 2));
  }

  res.status(200).end();
});

async function createPaymentInvoice(
  userId,
  invoiceTitle,
  invoiceDesc,
  invoicePayload,
  stripeToken,
  paramStart,
  currencyType,
  priceList,
) {
  const telegramApiUrl = `https://api.telegram.org/bot${telegramToken}/sendInvoice`;

  const paymentData = {
    chat_id: userId,
    title: invoiceTitle,
    description: invoiceDesc,
    payload: invoicePayload,
    provider_token: stripeToken,
    start_parameter: paramStart,
    currency: currencyType,
    prices: priceList,
  };

  try {
    const apiResponse = await fetch(telegramApiUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(paymentData),
    });

    const responseData = await apiResponse.json();
    return responseData;
  } catch (err) {
    console.error("Invoice sending failed:", err);
    return err.message;
  }
}

I think I might need to set up some kind of webhook to handle payment completion, but I’m not sure how to configure this properly. The Telegram docs don’t clearly explain if I need to add webhook endpoints in my Stripe dashboard or how Telegram would know about my payment webhook URL.

I’m using ngrok for local development with the webhook setup. My Stripe account is still unverified, which might be causing issues.

Any guidance on what I’m missing would be really helpful. Do I need to handle payment webhooks differently, or is there some configuration I’m missing?

Check your Stripe provider token - I had the same timeouts using the wrong test key. Make sure you’re using sk_test_ not pk_test_ in your env variable. Also, Telegram payments need the webhook alive during the entire payment flow. Ngrok drops after inactivity sometimes. Try adding keep_alive: true to your webhook or switch to localtunnel for testing - it’s more stable.

That timeout’s probably from your unverified Stripe account. I hit the same issue building my payment bot last year. Stripe test mode acts weird with unverified accounts, especially around payment timeouts. For webhooks, you don’t need to configure anything in your Stripe dashboard for Telegram payments. Telegram talks to Stripe directly and sends payment updates through your existing bot webhook. Just listen for pre_checkout_query and successful_payment update types in your webhook handler. Add these to your webhook function: javascript if (req.body.pre_checkout_query) { // Answer pre-checkout query await answerPreCheckoutQuery(req.body.pre_checkout_query.id, true); } if (req.body.message && req.body.message.successful_payment) { // Handle successful payment console.log('Payment completed:', req.body.message.successful_payment); } Verify your Stripe account first though. That fixed most of my timeout issues, even in test mode. Everything runs way smoother once your account’s properly set up.

Your timeout issue is probably webhook configuration, not the unverified Stripe account. Make sure you’ve properly registered your ngrok webhook URL with Telegram using setWebhook - I’ve hit similar problems when my ngrok tunnel wasn’t stable or responded too slowly. Your code looks fine, but your webhook needs to respond to Telegram fast enough. Add error handling and return status 200 right after processing. Also check if ngrok is dropping connections during payment processing. Payments can take several seconds, and if your webhook goes down during that time, Telegram will timeout. I’d add logging to track when you’re getting payment updates and confirm you’re actually receiving the pre_checkout_query events.