import Stripe from "stripe"; import { usePrisma } from "../../utils/prisma"; /** * POST /api/stripe/webhook * Stripe Webhook – verarbeitet Subscription-Events. * Aktualisiert profiles.plan + stripe_* Felder. */ export default defineEventHandler(async (event) => { const config = useRuntimeConfig(); const stripe = new Stripe(config.stripeSecretKey); const body = await readRawBody(event); const sig = getHeader(event, "stripe-signature"); if (!body || !sig) { throw createError({ statusCode: 400, message: "Missing body or signature", }); } let stripeEvent: Stripe.Event; try { stripeEvent = stripe.webhooks.constructEvent( body, sig, config.stripeWebhookSecret, ); } catch (err: any) { throw createError({ statusCode: 400, message: `Webhook Error: ${err.message}`, }); } const db = usePrisma(); switch (stripeEvent.type) { case "checkout.session.completed": { const session = stripeEvent.data.object as Stripe.Checkout.Session; const userId = session.metadata?.user_id || session.client_reference_id; const plan = session.metadata?.plan || "legend"; if (userId) { await db.profile.update({ where: { id: userId }, data: { plan: plan === "legend" ? "legend" : plan === "pro" ? "pro" : "free", stripeCustomerId: session.customer as string, stripeSubId: session.subscription as string, }, }); } break; } case "customer.subscription.updated": { const sub = stripeEvent.data.object as Stripe.Subscription; const customerId = sub.customer as string; const profile = await db.profile.findFirst({ where: { stripeCustomerId: customerId }, select: { id: true, plan: true }, }); if (profile) { const isActive = ["active", "trialing"].includes(sub.status); await db.profile.update({ where: { id: profile.id }, data: { plan: isActive ? profile.plan : "free", premiumUntil: sub.current_period_end ? new Date(sub.current_period_end * 1000) : null, }, }); } break; } case "customer.subscription.deleted": { const sub = stripeEvent.data.object as Stripe.Subscription; const customerId = sub.customer as string; const profile = await db.profile.findFirst({ where: { stripeCustomerId: customerId }, select: { id: true }, }); if (profile) { await db.profile.update({ where: { id: profile.id }, data: { plan: "free", premiumUntil: null }, }); } break; } } return { received: true }; });