import { NextRequest, NextResponse } from 'next/server'; import { jsonError } from '@/lib/auth-helpers'; export const dynamic = 'force-dynamic'; const BACKEND_URL = process.env.BACKEND_URL || 'http://localhost:3000'; /** * Stripe billing-portal proxy (security follow-up item 6) — Next → Express → * Stripe. Forwards the browser's bearer token (Express's requireAuth verifies * the same one) and returns the hosted portal URL. The portal is fully * configured in Stripe (cancellations, plan switching, invoice history); this * is the app-side link from account settings. */ export async function POST(req: NextRequest) { const authHeader = req.headers.get('authorization'); if (!authHeader) return jsonError(401, 'Log in to manage billing.'); try { const upstream = await fetch(`${BACKEND_URL}/api/stripe/portal`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: authHeader }, }); const data = (await upstream.json().catch(() => ({}))) as { portal_url?: string; error?: string }; if (!upstream.ok || !data.portal_url) { return NextResponse.json( { error: data.error || 'Billing portal is unavailable right now.' }, { status: upstream.ok ? 502 : upstream.status }, ); } return NextResponse.json({ portal_url: data.portal_url }, { status: 200 }); } catch { return jsonError(503, 'Billing portal is unavailable right now.'); } }