我目前正在 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,但无法让它工作。
我希望 Webhook 能够正常工作,这样我就可以通过从元数据收集数据来更新刚刚付款的用户。
Stripe 有 此文档页面,其中涵盖了可能导致签名验证失败的常见问题。
最常见的根本原因是您使用了错误的秘密。例如,如果您使用 Stripe CLI,它有自己的秘密。
第二个最常见的根本原因是您的基础设施中的某些内容正在“更改”Stripe 发送给您的有效负载的内容。 Node.js 非常常见,它会检测带有 JSON 有效负载的请求并为您解析它。该文档提供了多种调试方法,并链接到这个 Github 问题,其中包含数十种潜在的解决方案,具体取决于您自己的环境。