Next.js 14中Prisma未定义(ReferenceError)问题修复求助
问题:Next.js 14 + Prisma + Stripe Webhook 出现
ReferenceError: prisma is not defined错误 我在Next.js 14环境中使用Prisma,并已实现Stripe支付API功能,但在编写的Stripe Webhook接口中遇到了ReferenceError: prisma is not defined错误,请求帮助修复。
原接口代码
import { NextApiRequest, NextApiResponse } from "next" import { buffer } from "stream/consumers" import Stripe from "stripe" export const config = { api:{ bodyParser: false } } const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string,{ apiVersion: '2023-10-16' }) export default async function handler( req: NextApiRequest, res: NextApiResponse ){ const buf = await buffer(req) const sig = req.headers['stripe-signature'] if(!sig){ return res.status(400).send("Missing the stripe signature!") } let event: Stripe.Event try{ event = stripe.webhooks.constructEvent( buf, sig, process.env.STRIPE_WEBHOOK_SECRET! ) }catch(err){ return res.status(400).send("Webhook error" + err) } switch(event.type){ case 'charge.succeeded': const charge: any = event.data.object as Stripe.Charge; if(typeof charge.payment_intent === 'string'){ await prisma?.order.update({ where: {paymentIntentId: charge.payment_intent}, data: {status: "complete", address: charge.shipping?.address}, }); } break; default: console.log("Unhandled event type:" + event.type) } res.json({received: true}) }
项目目录结构

错误信息
Unhandled event type:payment_intent.succeeded ⨯ pages\api\stripe-webhook.ts (41:16) @ handler ⨯ ReferenceError: prisma is not defined at handler (webpack-internal:///(api)/./pages/api/stripe-webhook.ts:38:17) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { page: '/api/stripe-webhook' } 39 | const charge: any = event.data.object as Stripe.Charge; 40 | if(typeof charge.payment_intent === 'string'){ > 41 | await prisma?.order.update({ | ^ 42 | where: {paymentIntentId: charge.payment_intent}, 43 | data: {status: "complete", address: charge.shipping?.address}, 44 | }); ○ Compiling /_error ... ✓ Compiled /_error in 2.7s (736 modules)
解决方案
1. 导入并初始化Prisma客户端
错误核心是代码中使用了prisma对象但未导入。根据你的项目目录,已存在prisma文件夹,说明已生成Prisma客户端,只需在Webhook文件中添加导入逻辑:
- 直接导入并初始化:
在文件顶部添加:
import { PrismaClient } from '@prisma/client' const prisma = new PrismaClient()
- 若项目已创建全局Prisma实例(如
prisma/client.ts),可直接导入:
import prisma from '../../prisma/client'
2. 补充处理未捕获的payment_intent.succeeded事件
从错误日志可见,Stripe触发了payment_intent.succeeded事件,但原代码仅处理charge.succeeded,建议补充该事件的处理逻辑(根据业务需求调整)。
修改后的完整代码
import { NextApiRequest, NextApiResponse } from "next" import { buffer } from "stream/consumers" import Stripe from "stripe" import { PrismaClient } from '@prisma/client' // 初始化Prisma客户端 const prisma = new PrismaClient() export const config = { api:{ bodyParser: false } } const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string,{ apiVersion: '2023-10-16' }) export default async function handler( req: NextApiRequest, res: NextApiResponse ){ const buf = await buffer(req) const sig = req.headers['stripe-signature'] if(!sig){ return res.status(400).send("Missing the stripe signature!") } let event: Stripe.Event try{ event = stripe.webhooks.constructEvent( buf, sig, process.env.STRIPE_WEBHOOK_SECRET! ) }catch(err){ return res.status(400).send("Webhook error" + err) } switch(event.type){ case 'charge.succeeded': case 'payment_intent.succeeded': // 补充处理该事件 const chargeOrIntent: any = event.data.object; // 根据事件类型获取payment_intent ID const paymentIntentId = typeof chargeOrIntent.payment_intent === 'string' ? chargeOrIntent.payment_intent : chargeOrIntent.id; if(paymentIntentId){ await prisma.order.update({ where: {paymentIntentId}, data: {status: "complete", address: chargeOrIntent.shipping?.address}, }); } break; default: console.log("Unhandled event type:" + event.type) } res.json({received: true}) }
注意事项
- 确保已运行
npx prisma generate生成Prisma客户端,否则会出现导入错误。 - 生产环境建议使用单例模式的Prisma客户端,避免重复创建数据库连接,可参考Prisma官方最佳实践。
内容的提问来源于stack exchange,提问作者Nuwan Chamikara
相关产品推荐
相关产品推荐

