import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/auth'; import { stripe } from '@/lib/stripe'; import { resolvePriceId } from '@/lib/billing/stripe-prices'; import { prisma } from '@/lib/prisma'; import { z } from 'zod'; const bodySchema = z.object({ tier: z.enum(['PRO', 'BUSINESS']), interval: z.enum(['month', 'year']), }); export async function POST(req: NextRequest) { const session = await auth(); if (!session?.user?.id || !session.user.email) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const parsed = bodySchema.safeParse(await req.json()); if (!parsed.success) { return NextResponse.json({ error: 'Invalid request body' }, { status: 400 }); } const { tier, interval } = parsed.data; const userId = session.user.id; const userEmail = session.user.email; try { const priceId = resolvePriceId(tier, interval); const subscription = await prisma.subscription.findUnique({ where: { userId } }); let customerId = subscription?.stripeCustomerId ?? undefined; if (customerId && customerId.startsWith('cus_mock')) { customerId = undefined; } if (!customerId) { const customer = await stripe.customers.create({ email: userEmail, metadata: { userId }, }); customerId = customer.id; // Update DB to save the real Stripe customer ID await prisma.subscription.upsert({ where: { userId }, update: { stripeCustomerId: customerId }, create: { userId, stripeCustomerId: customerId, tier: 'BASIC', status: 'ACTIVE', currentPeriodStart: new Date(), currentPeriodEnd: new Date(Date.now() + 30 * 24 * 3600 * 1000), // temp basic dates } }); } const host = req.headers.get('x-forwarded-host') ?? req.headers.get('host') ?? 'localhost:3000'; const proto = req.headers.get('x-forwarded-proto') ?? 'http'; const origin = `${proto}://${host}`; const sessionParams = { customer: customerId, mode: 'subscription' as const, line_items: [{ price: priceId, quantity: 1 }], ui_mode: 'embedded_page', return_url: `${origin}/settings/billing?session_id={CHECKOUT_SESSION_ID}`, metadata: { userId, tier }, subscription_data: { metadata: { userId, tier } }, customer_update: { address: 'auto' }, }; const checkoutSession = await stripe.checkout.sessions.create(sessionParams as any); if (checkoutSession.client_secret) { return NextResponse.json({ clientSecret: checkoutSession.client_secret, sessionId: checkoutSession.id, }); } return NextResponse.json({ url: checkoutSession.url }); } catch (error) { console.error('[billing/create-checkout]', error); return NextResponse.json({ error: 'Failed to create checkout session' }, { status: 500 }); } }