简体   繁体   English

从 Stripe 获取 webhook 异常

[英]Getting exception on webhook from Stripe

I'm trying to set up a webhook from Stripe to handle the payment_intent.succeeded event, but I get an exception.我正在尝试从 Stripe 设置一个 webhook 来处理payment_intent.succeeded事件,但我得到了一个例外。 This is my code from the Node backend (I have extracted all the relevant parts I hope. Let me know if anything else is needed):这是我来自 Node 后端的代码(我已经提取了我希望的所有相关部分。如果需要其他内容,请告诉我):

const stripeWebHookSecret = 'whsec_WA0Rh4vAD3z0rMWy4kv2p6XXXXXXXXXX';常量条带WebHookSecret = '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);

And the implementation of registerOpenPaymentRoutes looks like this: 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 });
        }
    });
}

So far so good.When I fire a test webhook event from the Stripe dashboard, I hit the endpoint, but get the result from the catch block.到目前为止一切顺利。当我从 Stripe 仪表板触发测试 webhook 事件时,我点击了端点,但从 catch 块中获取了结果。 The error message is as follows:错误信息如下:

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"

I'm returning the signature with the error message as well as you see above, and the signature looks like this:我正在返回带有错误消息的签名,正如您在上面看到的那样,签名看起来像这样:

"t=1557911017,v1=bebf499bcb35198b8bfaf22a68b8879574298f9f424e57ef292752e3ce21914d,v0=23402bb405bfd6bd2a13c310cfecda7ae1905609923d801fa4e8b872a4f82894"

As far as I understand from the documentation, what is needed to get the raw request body as mentioned are the bodyParser.raw({type: 'application/json'}) argument to the router that I already have there.据我从文档中了解到,获取所提到的原始请求正文所需的是我已经拥有的路由器的bodyParser.raw({type: 'application/json'})参数。

Can anyone see the missing part?任何人都可以看到缺少的部分吗?

It's because you've already set your express app to use the bodyParser.json() middleware, which clashes with the bodyParser.raw() middleware you set up in your webhook route.这是因为您已经将 express 应用程序设置为使用bodyParser.json()中间件,这与您在 webhook 路由中设置的bodyParser.raw()中间件冲突。

If you remove the app.use(bodyParser.json());如果删除app.use(bodyParser.json()); line your webhooks will work as intended, but then the rest of your routes won't have a parsed body, which isn't ideal. line 您的 webhooks 将按预期工作,但是您的其余路由将没有解析的主体,这并不理想。

I suggest adding a custom middleware to choose the bodyParser version based on route.我建议添加一个自定义中间件来根据路由选择bodyParser版本。 Something like:就像是:

// 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);
  }
});

Then explicitly use the bodyParser.raw() middleware on the webhook routes.然后在 webhook 路由上显式使用bodyParser.raw()中间件。

I came up with the very same problem, the answer above gave me an idea on how to solve it but didn't make the gig for me, so thanks for pointing me in the right direction.我遇到了同样的问题,上面的答案给了我一个关于如何解决它的想法,但没有为我做演出,所以感谢你为我指明了正确的方向。

I share the way it worked for me to bring the body raw without too much effort我分享它的工作方式,让我不费吹灰之力就能把身体生下来

I just add in my index.js after我只是在我的 index.js 之后添加

app.use(bodyParser.urlencoded({ extended: false }));

this这个

app.use(
  bodyParser.json({ 
    verify: function (req, res, buf, encoding) {
      req.rawBody = buf;
    },
  })
);
app.use(
  bodyParser.urlencoded({
    extended: false,
    verify: function (req, res, buf, encoding) {
      req.rawBody = buf;
    },
  })
);

And then on the function where I needed a raw body I used:然后在 function 上,我需要一个我使用的原始身体:

router.post("/webhook",express.raw({ type: "application/json" }),async (req, res) => {
    const sig = req.headers["stripe-signature"];
    const body = req.rawBody; //here I got the raw body
});

And that was enough to pass the (in this case) stripe validation这足以通过(在这种情况下)条带验证

Hope to be helpful to somebody!希望对某人有所帮助!

Have a great coding!有一个伟大的编码!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM