Webhook 错误:Webhook 负载必须以字符串或缓冲区的形式提供

问题描述 投票:0回答:1

我被困在这个问题上,有人可以帮助我吗? 我把它放在邮递员:

https://my-server/api/webhook

我收到了这个:

Webhook 错误:Webhook 负载必须以字符串或 Buffer (https://nodejs.org/api/buffer.html) 实例代表 raw 请求正文。Payload 作为已解析的 JavaScript 对象提供。如果没有访问权限,则无法进行签名验证 原始签名材料。

了解有关 Webhook 签名的更多信息并探索 Webhook 集成 各种框架的示例位于 https://github.com/stripe/stripe-node#webhook-signing

我正在使用 ReactJS 和 Node

const express = require('express');
const Stripe = require('stripe');
const bodyParser = require('body-parser');
const cors = require('cors');
const webhookRoutes = require('./routes/webhook');

const app = express();
const stripe = Stripe(
  'sk_test_51Q1x2cRraDIE2N6qLbzeQgMBnW5xSG7gCB6W3tMxCfEWUz8p7vhjnjCAPXHkT2Kr50i6rgAC646BmqglaGWp5dhd00SZi9vWQg',
);

app.use(cors());
app.use(express.json());
app.use('/webhook', express.raw({ type: 'application/json' }));
app.use('/api', webhookRoutes);

app.post('/create-checkout-session', async (req, res) => {
  try {
    console.log('Received request to create checkout session');

    const session = await stripe.checkout.sessions.create({
      payment_method_types: ['card'],
      line_items: [
        {
          price_data: {
            currency: 'usd',
            product_data: {
              name: 'Nome do Produto',
            },
            unit_amount: 2000,
          },
          quantity: 1,
        },
      ],
      mode: 'payment',
      success_url: 'http://localhost:5173/success',
      cancel_url: 'http://localhost:5173/cancel',
    });

    console.log('Checkout session created successfully:', session);
    res.json({ id: session.id });
  } catch (error) {
    console.error('Error creating checkout session:', error.message);
    res.status(500).json({
      error: 'Failed to create checkout session',
    });
  }
});

const PORT = process.env.PORT || 4242;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
const express = require('express');
const Stripe = require('stripe');
const router = express.Router();
const stripe = Stripe('sk_test');

router.post('/webhook', async (req, res) => {
  const sig = req.headers['stripe-signature'];

  let event;

  try {
    event = stripe.webhooks.constructEvent(req.body, sig, 'whsec_');
  } catch (err) {
    console.log(`Webhook Error: ${err.message}`);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

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

    console.log('Pagamento confirmado:', session);
  }

  res.json({ received: true });
});

module.exports = router;
javascript node.js express stripe-payments
1个回答
0
投票

问题是...

app.use(express.json());

这会将所有

application/json
请求主体解析为 JavaScript 数据结构(使用
JSON.parse()
),而 Stripe 希望您将原始请求主体作为字符串转发。

您可以通过 stringifying

req.body
来解决这个问题,例如

event = stripe.webhooks.constructEvent(JSON.stringify(req.body), sig, 'whsec_');

或者您可以简单地注册您的 webhook 路由处理程序 before

express.json()

app.use(cors());
app.use('/api', express.raw({ type: 'application/json' }), webhookRoutes);
app.use(express.json());

另请参阅 https://docs.stripe.com/identity/handle-verification-outcomes#create-webhook

© www.soinside.com 2019 - 2024. All rights reserved.