Telegram sendInvoice调用失败:Stripe测试交易遇预检查超时错误
问题修复与支付成功逻辑实现
一、解决“bot precheckout timeout”错误
这个错误的核心原因是未在10秒内响应Telegram的pre_checkout_query请求。Telegram要求收到该请求后,必须调用answerPreCheckoutQuery接口完成确认,否则会触发超时。你的代码仅发送了消息,未执行关键的确认步骤,修改如下:
if(req.body.pre_checkout_query?.id){ // 必须先调用该接口确认,否则会触发超时 await axios.post(`${TELEGRAM_API}/answerPreCheckoutQuery`, { pre_checkout_query_id: req.body.pre_checkout_query.id, ok: true // 设为true允许支付,设为false则拒绝支付 }); // 执行保存到sqlite的逻辑 console.log("保存预支付信息到sqlite", req.body); // 补充你的sqlite插入代码,例如: // db.run('INSERT INTO pre_payments (username, chat_id, amount) VALUES (?, ?, ?)', // [req.body.pre_checkout_query.from.username, req.body.pre_checkout_query.from.id, 4000]); await axios.post(`${TELEGRAM_API}/sendMessage`, { chat_id: req.body.pre_checkout_query?.from.id, text: "正在确认支付,请稍候...", }); }
二、完善支付成功后的处理逻辑
支付完成后,Telegram会发送successful_payment类型的消息,你需要监听该事件来完成后续业务逻辑(如标记订单完成、发送最终通知等),补充到webhook处理逻辑中:
app.post(URI, async (req, res) => { console.log(req.body); let text = "", chatId = "", userObjectForTable = {}; // 处理普通消息 if(req.body.message?.chat?.id && req.body.message?.text){ chatId = req.body.message.chat.id; text = req.body.message.text; await axios.post(`${TELEGRAM_API}/sendMessage`, { chat_id: chatId, text: text, }); } // 处理支付指令 if (text === "/pay") { const message = await axios.post(`${TELEGRAM_API}/sendInvoice`, { chat_id: chatId, title: `FinnessinPips`, description: invoiceDescription, payload: "Invoice for payment", provider_token: BOTTOKEN, currency: "USD", prices: [{ label: "服务费用", amount: 4000 }], // 建议修改label为更清晰的描述 start_parameter: "payment-finnessinpips" // 可选,用于区分不同支付场景 }); userObjectForTable = { date: new Date(message.data.result.date), username: message.data.result.from.username }; } // 处理预支付查询 if(req.body.pre_checkout_query?.id){ try { await axios.post(`${TELEGRAM_API}/answerPreCheckoutQuery`, { pre_checkout_query_id: req.body.pre_checkout_query.id, ok: true }); } catch (err) { console.error("响应预支付查询失败:", err); } console.log("保存预支付信息到sqlite", req.body); // 补充sqlite插入逻辑 await axios.post(`${TELEGRAM_API}/sendMessage`, { chat_id: req.body.pre_checkout_query.from.id, text: "正在确认支付,请稍候...", }); } // 处理支付成功事件(支付完成后Telegram会推送该事件) if(req.body.message?.successful_payment){ const payment = req.body.message.successful_payment; const chatId = req.body.message.chat.id; // 保存支付成功记录到sqlite console.log("保存支付成功记录到sqlite", payment); // 示例sqlite插入逻辑: // db.run('INSERT INTO successful_payments (username, chat_id, total_amount, currency) VALUES (?, ?, ?, ?)', // [req.body.message.from.username, chatId, payment.total_amount, payment.currency]); // 发送最终支付成功通知 await axios.post(`${TELEGRAM_API}/sendMessage`, { chat_id: chatId, text: `✅ 支付成功!\n金额:${payment.total_amount / 100} ${payment.currency}\n订单标识:${payment.invoice_payload}`, }); // 这里可添加专属链接生成、内容推送等后续逻辑 } return res.sendStatus(200); // 返回200告知Telegram已成功接收请求 });
三、额外注意事项
- 超时排查:确保服务器能在10秒内完成
answerPreCheckoutQuery调用;本地测试需用ngrok等工具暴露公网地址,保证Telegram能正常回调。 - 测试信用卡:使用Stripe官方测试卡(如
4242 4242 4242 4242,过期日期选未来任意月份,CVV填任意3位),确保测试环境配置正确。 - 错误捕获:用
try-catch包裹所有异步API调用,避免因接口调用失败导致webhook响应超时。
内容的提问来源于stack exchange,提问作者The Coder
相关产品推荐
相关产品推荐

