import { headers } from "next/headers"; import { NextRequest, NextResponse } from "next/server"; import { getPrisma } from "../../../../lib/db"; import { loadSystemConfig } from "../../../../lib/system-config"; import { getStripe } from "../../../../lib/stripe"; import { sendEmail } from "../../../../lib/email"; import { createWebinarCalendarEvent } from "../../../../lib/calendar"; export const runtime = "nodejs"; export async function POST(req: NextRequest) { const prisma = await getPrisma(); const stripe = await getStripe(); const cfg = await loadSystemConfig(); const secret = cfg.stripe?.webhookSecret || process.env.STRIPE_WEBHOOK_SECRET; if (!prisma || !stripe || !secret) { // must still 200 to avoid retries in misconfigured env return NextResponse.json({ ok: true }); } const headersList = await headers(); const sig = headersList.get("stripe-signature"); const body = await req.text(); if (!sig) return NextResponse.json({ ok: true }); let event: any; try { event = stripe.webhooks.constructEvent(body, sig, secret); } catch { return NextResponse.json({ ok: true }); } if (event.type === "checkout.session.completed") { const session = event.data.object as any; const registrationId = session.metadata?.registrationId as string | undefined; const paymentIntent = session.payment_intent as string | undefined; if (registrationId) { try { await prisma.webinarRegistration.update({ where: { id: registrationId }, data: { status: "PAID", stripePaymentIntentId: paymentIntent ?? null }, }); // Send confirmation email with calendar invite const registration = await prisma.webinarRegistration.findUnique({ where: { id: registrationId }, include: { user: true, webinar: true }, }); if (registration && cfg.email?.enabled) { const { icsContent } = await createWebinarCalendarEvent( registration.webinar, registration.user.email ); const meetingInfo = registration.webinar.meetingInfo as any; const meetingLink = meetingInfo?.meetingLink || "TBD"; const htmlContent = `

Webinar Registration Confirmed

Hi ${registration.user.firstName},

Thank you for registering for ${registration.webinar.title}.

Date & Time: ${new Date(registration.webinar.startAt).toLocaleString()}

Duration: ${registration.webinar.duration} minutes

Join Link: ${meetingLink}

A calendar invitation is attached to this email.

See you there!

`; await sendEmail({ to: registration.user.email, subject: `Registration Confirmed: ${registration.webinar.title}`, html: htmlContent, attachments: [ { filename: "webinar-invite.ics", content: icsContent, contentType: "text/calendar", }, ], }); } } catch (error) { console.error("[WEBHOOK] Error processing payment:", error); // ignore } } } return NextResponse.json({ ok: true }); }