74 lines
2.4 KiB
TypeScript
74 lines
2.4 KiB
TypeScript
import { type NextRequest, NextResponse } from "next/server";
|
|
import { z } from "zod";
|
|
import { auth } from "@/app/(auth)/auth";
|
|
import { getStripePriceIdForPlan, isPaidBillingPlanId, type PaidBillingPlanId } from "@/lib/billing/plans";
|
|
import { createStripeCheckoutSession, StripeRequestError } from "@/lib/billing/stripe";
|
|
|
|
const checkoutSchema = z.object({
|
|
planId: z.string(),
|
|
});
|
|
|
|
function getExternalBase(request: NextRequest) {
|
|
return (
|
|
process.env.AUTH_URL ??
|
|
`${request.nextUrl.protocol}//${request.headers.get("host") ?? request.nextUrl.host}`
|
|
);
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const session = await auth();
|
|
|
|
if (!session?.user?.id || !session.user.email) {
|
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
}
|
|
|
|
if (session.user.type === "guest") {
|
|
return NextResponse.json({ error: "Guest user cannot checkout" }, { status: 403 });
|
|
}
|
|
|
|
const parsed = checkoutSchema.safeParse(await request.json());
|
|
|
|
if (!parsed.success || !isPaidBillingPlanId(parsed.data.planId)) {
|
|
return NextResponse.json({ error: "Invalid plan ID" }, { status: 400 });
|
|
}
|
|
|
|
const planId = parsed.data.planId as PaidBillingPlanId;
|
|
const stripeSecretKey = process.env.STRIPE_SECRET_KEY;
|
|
const priceId = getStripePriceIdForPlan(planId);
|
|
|
|
if (!stripeSecretKey || !priceId) {
|
|
return NextResponse.json(
|
|
{ error: "Billing is not configured. Missing Stripe keys or plan price ID." },
|
|
{ status: 503 }
|
|
);
|
|
}
|
|
|
|
const baseUrl = getExternalBase(request);
|
|
const successUrl = new URL(`/lovart/pricing?checkout=success&plan=${planId}`, baseUrl).toString();
|
|
const cancelUrl = new URL(`/lovart/pricing?checkout=cancelled&plan=${planId}`, baseUrl).toString();
|
|
|
|
const checkoutSession = await createStripeCheckoutSession({
|
|
secretKey: stripeSecretKey,
|
|
priceId,
|
|
userId: session.user.id,
|
|
email: session.user.email,
|
|
planId,
|
|
successUrl,
|
|
cancelUrl,
|
|
});
|
|
|
|
return NextResponse.json({
|
|
id: checkoutSession.id,
|
|
url: checkoutSession.url,
|
|
});
|
|
} catch (error) {
|
|
if (error instanceof StripeRequestError) {
|
|
return NextResponse.json({ error: error.message }, { status: error.status });
|
|
}
|
|
|
|
console.error("[Billing Checkout API] Error:", error);
|
|
return NextResponse.json({ error: "Failed to create checkout session" }, { status: 500 });
|
|
}
|
|
}
|