fix(dashboard): cancel subscription before new checkout if free

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-03-24 18:49:17 +01:00
parent a26e64e80d
commit b77ee71445
2 changed files with 31 additions and 10 deletions

View File

@@ -15,6 +15,7 @@ import { Widget, WidgetBody, WidgetHead } from '@/components/widget';
import { WidgetTable } from '@/components/widget-table'; import { WidgetTable } from '@/components/widget-table';
import { useAppParams } from '@/hooks/useAppParams'; import { useAppParams } from '@/hooks/useAppParams';
import useWS from '@/hooks/useWS'; import useWS from '@/hooks/useWS';
import { showConfirm } from '@/modals';
import { api } from '@/trpc/client'; import { api } from '@/trpc/client';
import type { IServiceOrganization } from '@openpanel/db'; import type { IServiceOrganization } from '@openpanel/db';
import type { IPolarPrice } from '@openpanel/payments'; import type { IPolarPrice } from '@openpanel/payments';
@@ -257,12 +258,23 @@ function CheckoutButton({
disabled={disabled !== null || (isActive && !isCanceled)} disabled={disabled !== null || (isActive && !isCanceled)}
key={price.id} key={price.id}
onClick={() => { onClick={() => {
const createCheckout = () =>
checkout.mutate({ checkout.mutate({
projectId, projectId,
organizationId: organization.id, organizationId: organization.id,
productPriceId: price!.id, productPriceId: price!.id,
productId: price.productId, productId: price.productId,
}); });
if (organization.subscriptionStatus === 'active') {
showConfirm({
title: 'Are you sure?',
text: `You're about the change your subscription.`,
onConfirm: () => createCheckout(),
});
} else {
createCheckout();
}
}} }}
loading={checkout.isLoading} loading={checkout.isLoading}
className="w-28" className="w-28"

View File

@@ -53,17 +53,26 @@ export const subscriptionRouter = createTRPCRouter({
organization.subscriptionId && organization.subscriptionId &&
organization.subscriptionStatus === 'active' organization.subscriptionStatus === 'active'
) { ) {
const existingProduct = organization.subscriptionProductId
? await getProduct(organization.subscriptionProductId)
: null;
// If the existing product is free, cancel the subscription and then jump to the checkout
if (existingProduct?.prices.some((p) => p.amountType === 'free')) {
await cancelSubscription(organization.subscriptionId);
} else {
if (organization.subscriptionCanceledAt) { if (organization.subscriptionCanceledAt) {
await reactivateSubscription(organization.subscriptionId); await reactivateSubscription(organization.subscriptionId);
} else { return null;
}
await changeSubscription( await changeSubscription(
organization.subscriptionId, organization.subscriptionId,
input.productId, input.productId,
); );
}
return null; return null;
} }
}
const checkout = await createCheckout({ const checkout = await createCheckout({
priceId: input.productPriceId, priceId: input.productPriceId,