import { NextResponse } from 'next/server' import { z } from 'zod' import { stripe } from '@/lib/stripe-server' import { prisma } from '@/lib/db' import { verifyToken } from '@/lib/auth' export const runtime = 'nodejs' const portalSchema = z.object({ locale: z.string().default('en') }) export async function POST(request: Request) { try { // Verify authentication const authHeader = request.headers.get('authorization') if (!authHeader?.startsWith('Bearer ')) { return NextResponse.json( { success: false, error: 'Authentication required' }, { status: 401 } ) } const token = authHeader.substring(7) let payload try { payload = await verifyToken(token) } catch (error) { return NextResponse.json( { success: false, error: 'Invalid or expired token' }, { status: 401 } ) } const userId = payload.userId // Get user const user = await prisma.user.findUnique({ where: { id: userId }, select: { stripeCustomerId: true, subscriptionTier: true } }) if (!user) { return NextResponse.json( { success: false, error: 'User not found' }, { status: 404 } ) } if (!user.stripeCustomerId) { return NextResponse.json( { success: false, error: 'No subscription found', code: 'NO_SUBSCRIPTION' }, { status: 404 } ) } const body = await request.json() const { locale } = portalSchema.parse(body) // Create billing portal session const session = await stripe.billingPortal.sessions.create({ customer: user.stripeCustomerId, return_url: `${process.env.NEXTAUTH_URL}/${locale}/settings` }) console.log('✅ Customer portal session created:', { sessionId: session.id, userId, customerId: user.stripeCustomerId }) return NextResponse.json({ success: true, url: session.url }) } catch (error) { console.error('Customer portal error:', error) if (error instanceof z.ZodError) { return NextResponse.json( { success: false, error: 'Invalid request format', details: error.errors }, { status: 400 } ) } return NextResponse.json( { success: false, error: 'Failed to create portal session' }, { status: 500 } ) } }