Stripe webhook 错误:找不到与有效负载的预期签名匹配的签名

Mag*_*nus 2 webhooks node.js express stripe-payments

我正在使用 Stripe 提供的代码来测试 webhook。Stripe 机密和端点机密已经过三重检查。

条纹版本:6.19 Body-Parser:1.19

当我在 Stripe 仪表板上测试 webhook 时,我得到了结果:(测试 webhook 错误:400)没有找到与负载的预期签名匹配的签名。您是否正在传递从 Stripe 收到的原始请求正文?

任何帮助,将不胜感激。

var bodyParser - require('body-parser);


// Using Express
const app = require('express')();

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


// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
const stripe = require('stripe')('sk_test_VPw...');

// Find your endpoint's secret in your Dashboard's webhook settings
const endpointSecret = 'whsec_...';


// Use body-parser to retrieve the raw body as a buffer
const bodyParser = require('body-parser');

// Match the raw body to content type application/json
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => {
  const sig = request.headers['stripe-signature'];

  let event;

  try {
    event = stripe.webhooks.constructEvent(request.body, sig, endpointSecret); //NOT WORKING!
  } catch (err) {
    return response.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Handle the checkout.session.completed event
  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;

    // Fulfill the purchase...
    handleCheckoutSession(session);
  }

  // Return a response to acknowledge receipt of the event
  response.json({received: true});
});
Run Code Online (Sandbox Code Playgroud)

Bug*_*lla 13

一个衬垫加上没有弃用的 bodyParser。确保在通用解析器(又名express.json())之前定义端点的解析器。

app.use('/stripe/webhook', express.raw({type: "*/*"}))
app.use(express.json())
Run Code Online (Sandbox Code Playgroud)

  • 经过两天的挣扎,你救了我。谢谢。 (2认同)

Vik*_*kii 13

除了一切之外,还要检查whsec_

在此输入图像描述

  • 我没有意识到每个端点的签名秘密是唯一的,直到这促使我检查它。非常感谢! (2认同)

kar*_*kko 8

通常这是由于您在检查签名之前解析或修改了原始请求字符串(因此签名是根据修改后的字符串计算的,而不是确切的 Stripe 发送)。在这种情况下,它看起来像JSON bodyParser中间件这样做: app.use(bodyParser.json());

Stripe 有一个在 webhook 端点上使用原始 bodyParser 中间件的示例,以便您的代码获取所需的原始字符串:

// Stripe requires the raw body to construct the event
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (req, res) => {
  //  raw body       ^^^^^^^^^^^^^^
  const sig = req.headers['stripe-signature'];

  let event;

  try {
    event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
    // body of request, already raw        ^^^^^^^^
  } catch (err) {
    // On error, log and return the error message
    console.log(`? Error message: ${err.message}`);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Successfully constructed event
  console.log('? Success:', event.id);

  // Return a response to acknowledge receipt of the event
  res.json({received: true});
});
Run Code Online (Sandbox Code Playgroud)