【问题标题】:Getting exception on webhook from Stripe从 Stripe 获取 webhook 异常
【发布时间】:2019-10-02 08:59:39
【问题描述】:

我正在尝试从 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'})argument 到我已经拥有的路由器。

谁能看到缺失的部分?

【问题讨论】:

    标签: node.js stripe-payments webhooks


    【解决方案1】:

    这是因为您已经将 express 应用设置为使用 bodyParser.json() 中间件,这与您在 webhook 路由中设置的 bodyParser.raw() 中间件发生冲突。

    如果您删除 app.use(bodyParser.json()); 行,您的 webhook 将按预期工作,但您的其余路由将没有解析的主体,这并不理想。

    我建议添加自定义中间件,根据路由选择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() 中间件。

    【讨论】:

    • 工作就像一个魅力!我以为我的 bodyParser.raw() 会针对该请求覆盖 ​​bodyParser.json() ,但事实并非如此。非常感谢!
    • 它添加到中间件队列而不是替换。所以首先它会进行json 编码,然后尝试raw,这会导致奇怪的事情发生并且您的签名会出现乱码/无法使用。
    猜你喜欢
    • 2020-02-22
    • 1970-01-01
    • 2021-12-05
    • 2020-12-12
    • 2015-04-18
    • 1970-01-01
    • 2023-03-27
    • 2017-11-01
    • 2019-10-11
    相关资源
    最近更新 更多