feat: billing fix

This commit is contained in:
Nevo David 2025-11-29 23:05:43 +07:00
parent d5729e25a4
commit 6ab8a2471b
1 changed files with 119 additions and 96 deletions

View File

@ -239,46 +239,15 @@ export const MainBillingComponent: FC<{
return subscription?.subscriptionTier;
}, [subscription, initialChannels, monthlyOrYearly, period]);
const moveToCheckout = useCallback(
(billing: 'STANDARD' | 'PRO' | 'FREE') => async () => {
const messages = [];
if (
!pricing[billing].team_members &&
pricing[subscription?.subscriptionTier!]?.team_members
) {
messages.push(
`Your team members will be removed from your organization`
);
}
if (billing === 'FREE') {
if (
subscription?.cancelAt ||
(await deleteDialog(
`Are you sure you want to cancel your subscription? ${messages.join(
', '
)}`,
'Yes, cancel',
'Cancel Subscription'
))
) {
const info = await new Promise((res) => {
modal.openModal({
title: t(
'we_are_sorry_to_see_you_go',
'We are sorry to see you go :('
),
withCloseButton: true,
classNames: {
modal: 'bg-transparent text-textColor',
},
children: <Info proceed={(e) => res(e)} />,
});
});
(billing: 'STANDARD' | 'PRO' | 'FREE', reactivate = false) =>
async () => {
if (reactivate) {
setLoading(true);
const { cancel_at } = await (
await fetch('/billing/cancel', {
method: 'POST',
body: JSON.stringify({
feedback: info,
feedback: '',
}),
headers: {
'Content-Type': 'application/json',
@ -289,72 +258,126 @@ export const MainBillingComponent: FC<{
...subs!,
cancelAt: cancel_at,
}));
if (cancel_at)
toast.show('Subscription set to canceled successfully');
if (!cancel_at) toast.show('Subscription reactivated successfully');
toast.show('Subscription reactivated successfully');
setLoading(false);
return;
}
return;
}
if (
messages.length &&
!(await deleteDialog(messages.join(', '), 'Yes, continue'))
) {
return;
}
setLoading(true);
const { url, portal } = await (
await fetch('/billing/subscribe', {
method: 'POST',
body: JSON.stringify({
period: monthlyOrYearly === 'on' ? 'YEARLY' : 'MONTHLY',
utm,
billing,
tolt: tolt(),
}),
})
).json();
if (url) {
await track(TrackEnum.InitiateCheckout, {
value:
pricing[billing][
monthlyOrYearly === 'on' ? 'year_price' : 'month_price'
],
});
window.location.href = url;
return;
}
if (portal) {
const messages = [];
if (
await deleteDialog(
'We could not charge your credit card, please update your payment method',
'Update',
'Payment Method Required'
)
!pricing[billing].team_members &&
pricing[subscription?.subscriptionTier!]?.team_members
) {
window.open(portal);
messages.push(
`Your team members will be removed from your organization`
);
}
} else {
setPeriod(monthlyOrYearly === 'on' ? 'YEARLY' : 'MONTHLY');
setSubscription((subs) => ({
...subs!,
subscriptionTier: billing,
cancelAt: null,
}));
mutate(
'/user/self',
{
...user,
tier: billing,
},
{
revalidate: false,
if (billing === 'FREE') {
if (
subscription?.cancelAt ||
(await deleteDialog(
`Are you sure you want to cancel your subscription? ${messages.join(
', '
)}`,
'Yes, cancel',
'Cancel Subscription'
))
) {
const info = await new Promise((res) => {
modal.openModal({
title: t(
'we_are_sorry_to_see_you_go',
'We are sorry to see you go :('
),
withCloseButton: true,
classNames: {
modal: 'bg-transparent text-textColor',
},
children: <Info proceed={(e) => res(e)} />,
});
});
setLoading(true);
const { cancel_at } = await (
await fetch('/billing/cancel', {
method: 'POST',
body: JSON.stringify({
feedback: info,
}),
headers: {
'Content-Type': 'application/json',
},
})
).json();
setSubscription((subs) => ({
...subs!,
cancelAt: cancel_at,
}));
if (cancel_at)
toast.show('Subscription set to canceled successfully');
setLoading(false);
}
);
toast.show('Subscription updated successfully');
}
setLoading(false);
},
return;
}
if (
messages.length &&
!(await deleteDialog(messages.join(', '), 'Yes, continue'))
) {
return;
}
setLoading(true);
const { url, portal } = await (
await fetch('/billing/subscribe', {
method: 'POST',
body: JSON.stringify({
period: monthlyOrYearly === 'on' ? 'YEARLY' : 'MONTHLY',
utm,
billing,
tolt: tolt(),
}),
})
).json();
if (url) {
await track(TrackEnum.InitiateCheckout, {
value:
pricing[billing][
monthlyOrYearly === 'on' ? 'year_price' : 'month_price'
],
});
window.location.href = url;
return;
}
if (portal) {
if (
await deleteDialog(
'We could not charge your credit card, please update your payment method',
'Update',
'Payment Method Required'
)
) {
window.open(portal);
}
} else {
setPeriod(monthlyOrYearly === 'on' ? 'YEARLY' : 'MONTHLY');
setSubscription((subs) => ({
...subs!,
subscriptionTier: billing,
cancelAt: null,
}));
mutate(
'/user/self',
{
...user,
tier: billing,
},
{
revalidate: false,
}
);
toast.show('Subscription updated successfully');
}
setLoading(false);
},
[monthlyOrYearly, subscription, user, utm]
);
if (user?.isLifetime) {
@ -401,7 +424,7 @@ export const MainBillingComponent: FC<{
<div className="gap-[3px] flex flex-col">
<div>
<Button
onClick={moveToCheckout('FREE')}
onClick={moveToCheckout('FREE', true)}
loading={loading}
>
{t(