chatbot-template/app/(chat)/api/billing/checkout/route.ts
dmitry.galkin b5c399257f checkout: omit customerEmail when user has guest-style email
Stripe rejects emails like 'guest-1779719735974' with 400 email_invalid.
Falling back to no email lets Stripe collect it on the checkout page itself,
which is the standard flow for unauthenticated upgrades.
2026-05-25 18:36:12 +04:00

45 lines
1.3 KiB
TypeScript

import { auth } from "@/app/(auth)/auth";
import {
createCheckoutSession,
isBillingConfigured,
} from "@/lib/billing/gateway";
import { ChatbotError } from "@/lib/errors";
export async function POST(request: Request) {
const session = await auth();
if (!session?.user) {
return new ChatbotError("unauthorized:chat").toResponse();
}
if (!isBillingConfigured()) {
return Response.json(
{
error: "billing_not_configured",
message:
"Set EGBE_PAYMENT_GATEWAY_URL, EGBE_GATEWAYS_TOKEN, and PRO_STRIPE_PRICE_ID to enable upgrades.",
},
{ status: 501 }
);
}
const appSlug = process.env.APP_SLUG ?? "chatbot";
const baseUrl =
process.env.NEXT_PUBLIC_BASE_URL ?? new URL(request.url).origin;
const rawEmail = session.user.email ?? "";
const looksLikeEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(rawEmail);
const customerEmail = looksLikeEmail ? rawEmail : undefined;
try {
const result = await createCheckoutSession({
userId: session.user.id,
customerEmail,
appSlug,
baseUrl,
});
return Response.json({ url: result.url, id: result.id });
} catch (error) {
const message = error instanceof Error ? error.message : "checkout failed";
return Response.json({ error: "checkout_failed", message }, { status: 502 });
}
}