Mercado Pago支付网关重复执行与超时问题技术求助
问题修复方案
一、解决Mercado Pago支付验证超时错误
频繁触发AxiosError: connect ETIMEDOUT的原因是:未设置请求超时时间、无网络波动容错机制、手动调用API缺乏错误处理。
修复措施:
- 给请求添加超时限制,避免无限等待网络响应
- 改用Mercado Pago官方SDK查询状态,SDK自带重试和错误处理,比手动Axios请求更稳定
- 调整检查间隔,降低请求频率,避免触发API限流
代码替换:
// 替换原有的Axios查询逻辑,改用SDK自带方法 const checkPaymentStatus = async (paymentId) => { try { const payment = await mercadopago.payment.findById(paymentId); return payment.body.status; } catch (err) { console.error("查询支付状态失败:", err.message); return null; } }; // 重构循环检查逻辑 const statusChecker = setInterval(async () => { const paymentStatus = await checkPaymentStatus(data.body.id); if (!paymentStatus) return; if (paymentStatus === "approved") { // 先检查订单是否已处理,防止重复执行 if (db3.get(`${data_id}.status`) === "Concluido") { clearInterval(statusChecker); clearTimeout(venda); return; } // 执行支付批准后的逻辑 handlePaymentApproved(); } }, 10000); // 每10秒检查一次,避免高频请求
二、解决支付批准后无限循环与重复执行问题
当前代码存在3个核心逻辑错误,导致重复添加余额、重复发送通知:
- 变量覆盖错误:
const newsa = parseFloat(currentSaldo);将用户输入的金额覆盖为当前余额,导致余额计算错误 - 状态判断顺序颠倒:先更新状态为
Processando再判断状态,导致多次进入处理分支 - 无执行锁机制:未检查订单是否已完成,即使处理完成后循环仍可能触发执行
修复措施:
- 修正变量命名,将用户输入的金额命名为
addAmount,避免被覆盖 - 添加执行锁,处理前先检查订单状态,已完成则直接终止循环
- 调整状态更新时机,处理完成后立即将订单标记为
Concluido,防止重复触发 - 修正余额计算逻辑,用用户输入的金额加上当前余额
核心代码修改:
// 收集用户输入时,使用独立变量名 collector.on("collect", message => { message.delete() const addAmount = message.content; // 用addAmount保存用户输入的金额 db4.set(`${interaction.user}.saldopendente`, addAmount); // ...其他代码不变 }); // 支付批准后的处理函数 const handlePaymentApproved = () => { clearInterval(statusChecker); clearTimeout(venda); const currentSaldo = parseFloat(db4.get(`${interaction.user.id}.saldo`)) || 0; const amountToAdd = parseFloat(addAmount); const newSaldo = currentSaldo + amountToAdd; // 先标记订单为已完成,锁死执行 db3.set(`${data_id}.status`, "Concluido"); db4.set(`${interaction.user.id}.saldo`, newSaldo.toString()); // ...发送通知、添加角色、记录日志等逻辑 msg.channel.send({ embeds: [embedentrega2] }); // ...其他通知逻辑 };
三、额外优化建议
- 清理冗余定时器:原代码中
timer2和venda存在重复逻辑,合并为一个超时取消订单的定时器 - 添加全局错误捕获:给所有异步操作包裹
try/catch,避免单个请求崩溃整个流程 - 使用UUID生成订单ID:替代随机数,确保订单ID唯一,避免数据冲突
内容的提问来源于stack exchange,提问作者Guilherme Matias
相关产品推荐
相关产品推荐

