我正在开发一个 Express.js 应用程序来处理 Stripe webhooks。尽管按照建议配置了 Webhook 路由,但当 Stripe 尝试将事件发布到我的 Webhook 端点时,我仍然遇到
404 Not Found
错误。
当我运行 Stripe CLI 将事件转发到本地服务器时,每个事件都会收到
404 Not Found
错误。以下是错误消息的详细信息:
2024-06-09 16:30:24 --> invoice.paid [evt_1PPfGkRsJfE0QDMT8OOiGWVh]
2024-06-09 16:30:24 <-- [404] POST http://localhost:3080/webhook [evt_1PPfGkRsJfE0QDMT8OOiGWVh]
javascript
require('dotenv').config();
const path = require('path');
const express = require('express');
const cors = require('cors');
const mongoSanitize = require('express-mongo-sanitize');
const routes = require('./routes');
const webhookRoutes = require('./routes/webhookRoutes');
const { PORT, HOST } = process.env;
const port = Number(PORT) || 3080;
const host = HOST || 'localhost';
const app = express();
app.disable('x-powered-by');
app.use(cors());
app.use(express.json({ limit: '3mb' }));
app.use(mongoSanitize());
app.use(express.urlencoded({ extended: true, limit: '3mb' }));
// Webhook route must handle raw request bodies for signature verification
app.use('/webhook', express.raw({ type: 'application/json' }), webhookRoutes);
app.use('/api', routes); // Example for other routes
app.use((req, res) => {
res.status(404).sendFile(path.join(__dirname, 'public', '404.html'));
});
app.listen(port, host, () => {
console.log(`Server listening at http://${host}:${port}`);
});
Webhook 路由 (webhookRoutes.js)
javascript
Copy code
const express = require('express');
const router = express.Router();
const { handleWebhook } = require('../controllers/webhookController');
router.post('/', express.raw({ type: 'application/json' }), handleWebhook);
module.exports = router;
Webhook 控制器 (webhookController.js)
javascript
Copy code
const Stripe = require('stripe');
const { updateUserSubscriptionStatus } = require('../../models/userMethods');
const { logger } = require('~/config');
const stripe = Stripe(process.env.STRIPE_SECRET_KEY);
const endpointSecret = process.env.STRIPE_ENDPOINT_SECRET;
const handleWebhook = async (req, res) => {
logger.info('Received a webhook event');
let event = req.body;
// Verify webhook signature
if (endpointSecret) {
const signature = req.headers['stripe-signature'];
try {
event = stripe.webhooks.constructEvent(req.body, signature, endpointSecret);
logger.info('Webhook signature verified');
} catch (err) {
logger.error('⚠️ Webhook signature verification failed:', err.message);
return res.status(400).send(`Webhook Error: ${err.message}`);
}
}
try {
switch (event.type) {
case 'invoice.paid': {
const invoice = event.data.object;
const customerId = invoice.customer;
logger.info(`Handling invoice.paid for customer ${customerId}`);
const updateResult = await updateUserSubscriptionStatus(customerId, 'active');
if (updateResult instanceof Error) {
logger.error('[updateUserSubscriptionStatus]', updateResult);
const { status, message } = updateResult;
return res.status(status).send({ message });
}
logger.info('User subscription status updated successfully');
res.status(200).send('Success');
break;
}
case 'payment_intent.succeeded': {
const paymentIntent = event.data.object;
logger.info(`PaymentIntent for ${paymentIntent.amount} was successful!`);
res.status(200).send('Success');
break;
}
case 'payment_method.attached': {
const paymentMethod = event.data.object;
logger.info('PaymentMethod successfully attached');
res.status(200).send('Success');
break;
}
default: {
logger.warn(`Unhandled event type ${event.type}`);
res.status(400).send(`Unhandled event type ${event.type}`);
}
}
} catch (err) {
logger.error('[handleWebhook]', err);
res.status(500).json({ message: err.message });
}
};
module.exports = {
handleWebhook,
};
重现步骤 启动服务器:
节点索引.js 使用 Stripe CLI 转发事件:
启动 Stripe CLI 监听事件并将其转发到本地服务器:
stripe 监听 --forward-to http://localhost:3080/webhook 触发测试事件:
使用 Stripe CLI 触发测试事件:
条纹触发发票.已付款 预期行为 Webhook 端点应正确接收和处理 Stripe 事件,服务器应记录事件并以 200 状态代码进行响应。
实际行为 服务器响应 Webhook 端点的 404 Not Found 错误。
请求帮助 如果您能帮助我诊断 webhook 端点未被识别的原因以及如何修复 404 错误,我将不胜感激。谢谢!
您应该在 webhook 路由之后使用主体解析器中间件