feat(billing): implement robust in-app subscription cancellation & fix CI/CD socket port typo

This commit is contained in:
Antigravity
2026-05-28 20:50:11 +00:00
parent f5608372dc
commit 457c6fa626
22 changed files with 656 additions and 460 deletions

View File

@@ -31,21 +31,41 @@ export async function POST(req: NextRequest) {
const subscription = await prisma.subscription.findUnique({ where: { userId } });
let customerId = subscription?.stripeCustomerId ?? undefined;
if (customerId && customerId.startsWith('cus_mock')) {
customerId = undefined;
}
if (!customerId) {
const customer = await stripe.customers.create({
email: userEmail,
metadata: { userId },
});
customerId = customer.id;
// Update DB to save the real Stripe customer ID
await prisma.subscription.upsert({
where: { userId },
update: { stripeCustomerId: customerId },
create: {
userId,
stripeCustomerId: customerId,
tier: 'BASIC',
status: 'ACTIVE',
currentPeriodStart: new Date(),
currentPeriodEnd: new Date(Date.now() + 30 * 24 * 3600 * 1000), // temp basic dates
}
});
}
const origin = req.headers.get('origin') ?? process.env.NEXTAUTH_URL ?? 'http://localhost:3000';
const host = req.headers.get('x-forwarded-host') ?? req.headers.get('host') ?? 'localhost:3000';
const proto = req.headers.get('x-forwarded-proto') ?? 'http';
const origin = `${proto}://${host}`;
const sessionParams = {
customer: customerId,
mode: 'subscription' as const,
line_items: [{ price: priceId, quantity: 1 }],
ui_mode: 'embedded',
ui_mode: 'embedded_page',
return_url: `${origin}/settings/billing?session_id={CHECKOUT_SESSION_ID}`,
metadata: { userId, tier },
subscription_data: { metadata: { userId, tier } },