Loopback项目对接Stripe Webhooks异常:响应返回undefined
嘿,我来帮你搞定Stripe Webhook和Loopback的集成问题!你的当前代码有几个关键问题导致Stripe返回异常,咱们一步步修正:
核心问题分析
- HTTP方法错误:Stripe的Webhook是通过
POST请求发送事件 payload 的,你现在用的是GET,根本接不到正确的内容。 - 请求体解析方式不对:Stripe要求必须使用原始未解析的请求体来验证签名,但你的
accepts配置会让Loopback自动解析请求体,直接破坏了签名验证的基础。 - 缺少签名验证:这是Stripe Webhook的强制安全步骤,不验证签名的话,你无法确认请求确实来自Stripe,存在被伪造请求的风险。
修正后的完整代码
首先确保你已经安装了Stripe SDK:
npm install stripe
然后修改你的远程方法:
const stripe = require('stripe')('你的Stripe Secret Key'); const webhookSecret = '你的Stripe Webhook Secret'; // 从Stripe控制台的Webhook设置中获取 Stripeconnect.stripeWebhook = function(req, res, cb) { // 从请求头中获取Stripe的签名 const sig = req.headers['stripe-signature']; let event; try { // 用原始请求体和签名验证事件合法性 event = stripe.webhooks.constructEvent( req.rawBody, // 必须用未解析的原始请求体,不能用已解析的req.body sig, webhookSecret ); } catch (err) { // 签名验证失败,返回400给Stripe res.status(400).send(`Webhook Error: ${err.message}`); return cb(err); } // 验证成功,根据事件类型处理业务逻辑 switch (event.type) { case 'payment_intent.succeeded': const paymentIntent = event.data.object; console.log('支付成功:', paymentIntent.id); // 这里添加你的业务逻辑,比如更新订单状态、发送通知等 break; case 'charge.failed': const failedCharge = event.data.object; console.log('支付失败:', failedCharge.id); // 处理支付失败的逻辑,比如通知用户、记录日志 break; // 可以添加更多你需要监听的Stripe事件类型 default: console.log(`未处理的事件类型: ${event.type}`); } // 返回200给Stripe,表示事件已接收(必须返回2xx状态码,否则Stripe会重试) res.status(200).json({received: true}); cb(null, {status: 'success', processedEvent: event.type}); }; Stripeconnect.remoteMethod('stripeWebhook', { description: '接收并验证Stripe Webhook事件,处理对应业务逻辑', http: { path: '/stripeWebhook', verb: 'post' }, // 改为POST方法 accepts: [ { arg: 'req', type: 'object', http: { source: 'req' } }, // 获取完整请求对象 { arg: 'res', type: 'object', http: { source: 'res' } } // 获取响应对象 ], returns: { arg: 'status', type: 'any' } });
关键细节说明
req.rawBody的必要性:Stripe的签名是基于原始请求字节流生成的,Loopback默认会解析JSON请求体为req.body,但这会改变原始内容,导致签名验证失败。只要你的Loopback应用是默认配置,req.rawBody就可以直接访问到原始请求体。- 签名验证的重要性:
stripe.webhooks.constructEvent方法会帮你验证请求的真实性,过滤掉伪造的Webhook请求,这是生产环境必须的步骤。 - 响应要求:Stripe会在收到你的2xx响应后停止重试,如果返回非2xx状态码,Stripe会在接下来的几天内反复重试该Webhook。
内容的提问来源于stack exchange,提问作者Tony Hensler
相关产品推荐
相关产品推荐

