Next.js电商Stripe支付Webhook监听:Vercel部署实现方案咨询
在Vercel上实现Stripe Webhook监听的方案
本地开发用的stripe listen是Stripe CLI提供的本地转发工具,部署到Vercel后不需要这个命令,直接通过Stripe Dashboard配置Webhook端点即可,具体步骤如下:
1. 在Stripe Dashboard配置Webhook端点
- 先获取你的Vercel应用生产域名(比如
https://your-shop-app.vercel.app) - 登录Stripe Dashboard,进入Developers > Webhooks页面,点击Add endpoint
- 在Endpoint URL中填入完整的Webhook API路径:
https://your-shop-app.vercel.app/api/orders/webhook - 在Events to send中勾选需要监听的事件:
checkout.session.completed、checkout.session.canceled - 保存后,复制页面上的Signing secret(Webhook签名密钥),后续要用到
2. 在Vercel配置环境变量
- 登录Vercel控制台,找到你的项目,进入Settings > Environment Variables
- 添加以下变量:
STRIPE_WEBHOOK_SECRET:值为刚才复制的Stripe Webhook签名密钥- 确保已配置
STRIPE_API_KEY等其他Stripe必要环境变量
- 点击Save,重新部署项目让环境变量生效
3. 确保Webhook API路由正确处理签名验证
Next.js的API路由必须验证Stripe的请求签名,防止伪造请求,以下是两种路由模式的示例代码:
Pages Router 示例(pages/api/orders/webhook.js)
import { Stripe } from 'stripe'; const stripe = new Stripe(process.env.STRIPE_API_KEY, { apiVersion: '2024-06-20', // 使用Stripe最新兼容API版本 }); export default async function handler(req, res) { if (req.method !== 'POST') { return res.status(405).end('Method Not Allowed'); } const sig = req.headers['stripe-signature']; let event; try { // 验证Stripe请求签名 event = stripe.webhooks.constructEvent( req.body, sig, process.env.STRIPE_WEBHOOK_SECRET ); } catch (err) { return res.status(400).send(`Webhook Error: ${err.message}`); } // 处理对应事件 switch (event.type) { case 'checkout.session.completed': const completedSession = event.data.object; // 这里编写创建订单、更新支付状态的业务逻辑 console.log('支付完成,会话ID:', completedSession.id); break; case 'checkout.session.canceled': const canceledSession = event.data.object; // 这里编写支付取消后的订单状态更新逻辑 console.log('支付取消,会话ID:', canceledSession.id); break; default: console.log(`未处理的事件类型:${event.type}`); } res.json({ received: true }); } // 禁用Next.js自动解析请求体,Stripe需要原始请求体用于签名验证 export const config = { api: { bodyParser: false, }, };
App Router 示例(app/api/orders/webhook/route.js)
import { Stripe } from 'stripe'; const stripe = new Stripe(process.env.STRIPE_API_KEY, { apiVersion: '2024-06-20', }); export async function POST(req) { const rawBody = await req.text(); const sig = req.headers.get('stripe-signature'); let event; try { event = stripe.webhooks.constructEvent( rawBody, sig, process.env.STRIPE_WEBHOOK_SECRET ); } catch (err) { return new Response(`Webhook Error: ${err.message}`, { status: 400 }); } // 事件处理逻辑同Pages Router示例 switch (event.type) { case 'checkout.session.completed': // 创建订单逻辑 break; case 'checkout.session.canceled': // 取消订单逻辑 break; default: console.log(`未处理的事件类型:${event.type}`); } return new Response(JSON.stringify({ received: true }), { status: 200 }); } export const config = { api: { bodyParser: false, }, };
4. 测试验证(可选)
- 在Stripe Dashboard的Webhook端点详情页,点击Send test event,选择对应事件发送到Vercel端点,检查日志或数据库是否正确处理了事件
- 也可以用Stripe CLI执行
stripe trigger checkout.session.completed命令触发测试事件,验证生产环境的Webhook是否正常响应
注意事项
- 确保Webhook API的响应时间不超过30秒(Stripe的超时限制),如果业务逻辑复杂,建议用异步处理(比如Vercel Edge Functions或第三方队列服务)
- 所有Stripe密钥必须通过环境变量配置,禁止硬编码到代码中
内容的提问来源于stack exchange,提问作者user21299187
相关产品推荐
相关产品推荐

