Stripe Webhooks 实现和元数据 - 未找到与有效负载的预期签名匹配的签名

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

我目前正在 Node.js 中使用服务器。我正在实施 Stripe 来管理订阅付款,但我无法成功请求。

我总是收到错误: 未找到与有效负载的预期签名匹配的签名。您是否正在传递从 Stripe 收到的原始请求正文?如果 Webhook 请求由第三方工具转发,请确保保留准确的请求正文,包括 JSON 格式和新行样式

难道我没有使用正确的whsec?在 Stripe 提供的示例中,它给出了 whsec,但是在检查 webhook 是否正常工作时,会出现不同的 whsec。

第二个签名秘诀

我会留下我的后端服务器的代码:

index.js

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
const serviceAccount = require("./credentials.json");
const cors = require('cors');
const jwt = require('jsonwebtoken');
const dotenv = require('dotenv');
const cookieParser = require('cookie-parser');

dotenv.config();

const app = express();

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: process.env.URL
});

app.use(cookieParser(process.env.TOKEN_SECRET));
app.use(cors({
  origin: true,
  credentials: true
}));

app.use('/api', require('./routes/stripe.webhook.routes'));  // Webhook routes

app.use('/api', express.json());
app.use('/api', require('./routes/login.routes'));
app.use('/api', require('./routes/register.routes'));
app.use('/api/', require('./routes/auth.routes'));
app.use('/api', require('./routes/schedule.routes'));
app.use('/api', require('./routes/appointments.routes'));
app.use('/api', require('./routes/users.routes'));
app.use('/api', require('./routes/doctors.routes'));
app.use('/api', require('./routes/illness.routes'));
app.use('/api', require('./routes/stripe.routes'));

exports.app = functions.https.onRequest(app);

stripe.webhook.routes.js

const express = require('express');
const router = express.Router();
const dotenv = require('dotenv');
dotenv.config();

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const admin = require('firebase-admin');

const endpointSecret = process.env.WHSEC;

router.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;
  try {
    // Verificar que el webhook venga de Stripe usando la firma
    event = stripe.webhooks.constructEvent(
      req.rawBody,
      sig,
      endpointSecret,
    );
  } catch (err) {
    console.error(`Webhook signature verification failed.`, err.message);
    console.log(err)
    return res.status(400).send(`Webhook Error: ${err}`);
  }

  switch (event.type) {
    case 'invoice.payment_succeeded':
      console.log('Succeed')
      //handlePaymentSucceeded(event.data.object);
      break;
    case 'invoice.payment_failed':
      console.log('Failed')
      break;
    default:
      console.log(`Unhandled event type ${event.type}`);
  }

  res.status(200).send(req);
});

module.exports = router;

此外,我的 Stripe 会话不会将元数据发送到 webhook。我想发送正在进行该过程的用户的 ID。当我打印会话时,元数据确实出现,但在 Webhook 中,元数据不再出现。

stripe.routes.js

// IMPORTS - - - - - - - - - - - - - - - - - - - - - - - - 
const admin = require('firebase-admin')
const {Router} = require('express')
const dotenv = require('dotenv');

// CONFIG  - - - - - - - - - - - - - - - - - - - - - - - - 
const router = Router();
const db = admin.firestore();
dotenv.config();

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY)

router.post('/create-checkout-session', async (req, res) => {
  try {
    const userId = req.body.userId;

    createSession({priceId: req.body.priceId, userId: userId}).then(response => {
      return res.status(200).send(response);
    }).catch(e => {
      return res.status(400).send(e);
    });
  } catch (e) {
    
  }
});

async function createSession(params) {
  console.log(params)
  try {
    const session = await stripe.checkout.sessions.create({
      payment_method_types: ['card'],
      line_items: [{price: params.priceId, quantity: 1}],
      mode: 'subscription',
      success_url: process.env,SUCCESS,
      cancel_url: process.env.FAILED,
      metadata: {
        userId: params.userId,
        test: 'test
      }
    });
    console.log('Session created: ', session);

    return { id: session.id };  
  } catch (error) {
    console.log(error)
    throw new Error(`Failed to create session: ${error.message}`);
  }
}


module.exports = router

我尝试过 req.body 和 req.rawBody,但无法让它工作。

200 可以

我希望 Webhook 能够正常工作,这样我就可以通过从元数据收集数据来更新刚刚付款的用户。

node.js firebase stripe-payments webhooks
1个回答
0
投票

Stripe 有 此文档页面,其中涵盖了可能导致签名验证失败的常见问题。

最常见的根本原因是您使用了错误的秘密。例如,如果您使用 Stripe CLI,它有自己的秘密。

第二个最常见的根本原因是您的基础设施中的某些内容正在“更改”Stripe 发送给您的有效负载的内容。 Node.js 非常常见,它会检测带有 JSON 有效负载的请求并为您解析它。该文档提供了多种调试方法,并链接到这个 Github 问题,其中包含数十种潜在的解决方案,具体取决于您自己的环境。

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