我正在尝试从Stripe建立一个Webhook来处理payment_intent.succeeded
事件,但是出现异常。这是我来自Node后端的代码(我提取了我希望的所有相关部分。让我知道是否还有其他需要):
const stripeWebHookSecret ='whsec_WA0Rh4vAD3z0rMWy4kv2p6XXXXXXXXXX';
import express from 'express';
const app = express();
app.use(bodyParser.urlencoded({ extended:true }));
app.use(bodyParser.json());
app.use(session({ <some params here> }));
const openRouter = express.Router();
registerOpenPaymentRoutes(openRouter);
app.use('/open', openRouter);
registerOpenPaymentRoutes
的实现如下所示:
export const registerOpenPaymentRoutes = (router) => {
router.post('/payment/intent/webhook', bodyParser.raw({type: 'application/json'}), (req, res) => {
let signature = req.headers['stripe-signature'];
try {
let event = stripe.webhooks.constructEvent(req.body, signature, stripeWebHookSecret);
switch(event.type){
case 'payment_intent.succeeded':
let intent = event.data.object;
res.json({ message: 'Everything went smooth!', intent });
default:
res.status(400).json({ error: 'Event type not supported' });
}
}
catch (error){
res.status(400).json({ message: `Wrong signature`, signature, body: req.body, error });
}
});
}
到目前为止一切顺利。当我从Stripe仪表板触发测试Webhook事件时,我命中了端点,但从catch块中得到了结果。错误消息如下:
No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing"
我将返回带有错误消息的签名以及上面的内容,签名看起来像这样:
"t=1557911017,v1=bebf499bcb35198b8bfaf22a68b8879574298f9f424e57ef292752e3ce21914d,v0=23402bb405bfd6bd2a13c310cfecda7ae1905609923d801fa4e8b872a4f82894"
据我从文档中了解到的那样,获取原始请求正文所需要的是bodyParser.raw({type: 'application/json'})
关于路由器的参数,我已经在那里拥有了。
任何人都可以看到缺少的部分吗?
答案 0 :(得分:1)
这是因为您已经将Express应用程序设置为使用bodyParser.json()
中间件,该中间件与您在Webhook路由中设置的bodyParser.raw()
中间件相冲突。
如果您删除app.use(bodyParser.json());
行,则您的网络钩子将按预期工作,但是其余路由将没有经过解析的正文,这是不理想的。
我建议添加自定义中间件以根据路由选择bodyParser
版本。像这样:
// only use the raw bodyParser for webhooks
app.use((req, res, next) => {
if (req.originalUrl === '/payment/intent/webhook') {
next();
} else {
bodyParser.json()(req, res, next);
}
});
然后在Webhook路由上显式使用bodyParser.raw()
中间件。