54 lines
1.9 KiB
TypeScript
54 lines
1.9 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { auth } from "@/lib/auth";
|
|
import { stripe, PRICE_MAP, getOrCreateStripeCustomer } from "@/lib/stripe";
|
|
|
|
export async function POST(request: NextRequest) {
|
|
// Require authentication
|
|
const session = await auth();
|
|
if (!session?.user?.id) {
|
|
return NextResponse.json({ error: "Not authenticated" }, { status: 401 });
|
|
}
|
|
|
|
const { serviceKey } = await request.json();
|
|
const service = PRICE_MAP[serviceKey];
|
|
|
|
if (!service) {
|
|
return NextResponse.json({ error: "Invalid service" }, { status: 400 });
|
|
}
|
|
|
|
// One Stripe Customer per user (keyed by keycloak_id) — never customer_email,
|
|
// which would create a new Stripe Customer on every checkout
|
|
const stripeCustomerId = await getOrCreateStripeCustomer({
|
|
keycloakId: session.user.id,
|
|
email: session.user.email || "",
|
|
name: session.user.name || "",
|
|
});
|
|
|
|
const checkoutSession = await stripe.checkout.sessions.create({
|
|
mode: "payment",
|
|
payment_method_types: ["card"],
|
|
// The Stripe account has Managed Payments (Stripe = merchant of record) on by
|
|
// default; disable it per session: invoicing is done by TOP CLOSSERS through
|
|
// the ERP, and Managed Payments rejects payment_method_types anyway.
|
|
...({ managed_payments: { enabled: false } } as Record<string, unknown>),
|
|
customer: stripeCustomerId,
|
|
line_items: [
|
|
{
|
|
price: service.priceId,
|
|
quantity: 1,
|
|
},
|
|
],
|
|
metadata: {
|
|
user_email: session.user.email || "",
|
|
user_name: session.user.name || "",
|
|
keycloak_id: session.user.id || "",
|
|
component: service.component,
|
|
media_type: service.mediaType,
|
|
service_label: service.label,
|
|
},
|
|
success_url: `${process.env.NEXT_PUBLIC_SITE_URL}/dashboard/checkout/success?session_id={CHECKOUT_SESSION_ID}`,
|
|
cancel_url: `${process.env.NEXT_PUBLIC_SITE_URL}/pricing`,
|
|
});
|
|
|
|
return NextResponse.json({ url: checkoutSession.url });
|
|
}
|