This commit is contained in:
southseact-3d
2026-02-11 20:16:01 +00:00
parent a66c983360
commit e2abb2ee98
2 changed files with 250 additions and 49 deletions

View File

@@ -1381,14 +1381,17 @@
return;
}
// Handle paid-to-free downgrade (cancel subscription)
// Handle paid-to-free downgrade (schedule cancellation at period end)
if (isPaidToFree) {
const renewsAt = account?.subscriptionRenewsAt;
const dateStr = renewsAt ? new Date(renewsAt).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' }) : 'the end of your billing period';
showConfirmModal({
title: 'Downgrade to Free Plan',
body: 'You are moving to the free Hobby plan. Your subscription will be cancelled and you will lose premium features and limits. Are you sure you want to continue?',
body: `You are moving to the free Hobby plan. Your subscription will be cancelled at the end of your current billing period (${dateStr}). You will continue to have access to premium features and your current token allowance until then.`,
icon: 'warning',
onConfirm: async () => {
setStatus('Cancelling subscription...');
setStatus('Scheduling cancellation...');
try {
const resp = await fetch('/api/account', {
method: 'POST',
@@ -1409,7 +1412,7 @@
if (!resp.ok) throw new Error(data.error || 'Unable to downgrade plan');
renderAccount(data.account || {});
setStatus('Downgraded to free plan successfully', 'success');
setStatus(`Downgrade scheduled. You will lose premium access on ${dateStr}`, 'success');
} catch (err) {
setStatus(err.message, 'error');
}
@@ -1418,7 +1421,7 @@
return;
}
// Handle free-to-paid upgrade (requires checkout)
// Handle free-to-paid upgrade (requires checkout - now called via /api/account)
if (isPlanChange && isNewPaidPlan && !isPaidPlan) {
showConfirmModal({
title: 'Upgrade to Paid Plan',
@@ -1427,7 +1430,7 @@
onConfirm: async () => {
setStatus('Starting checkout...');
try {
const resp = await fetch('/api/subscription/checkout', {
const resp = await fetch('/api/account', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -1438,20 +1441,27 @@
plan: newPlan,
billingCycle: newBillingCycle,
currency: newCurrency,
inline: true,
billingEmail: newBillingEmail,
}),
});
const data = await resp.json().catch(() => ({}));
if (!resp.ok) throw new Error(data.error || 'Unable to start checkout');
if (data.inlineCheckoutUrl) {
openInlineCheckout(data.inlineCheckoutUrl, data.sessionId, newPlan, newBillingCycle, newCurrency);
} else if (data.checkoutUrl) {
openInlineCheckout(data.checkoutUrl, data.sessionId, newPlan, newBillingCycle, newCurrency);
} else {
throw new Error('Checkout URL not returned');
// Handle seamless checkout redirect
if (data.requiresCheckout && data.checkoutUrl) {
// Redirect to checkout without showing error
window.location.href = data.checkoutUrl;
return;
}
// For inline checkout (fallback)
if (data.checkoutUrl) {
window.location.href = data.checkoutUrl;
return;
}
throw new Error('Checkout URL not returned');
} catch (err) {
setStatus(err.message, 'error');
}