fix: migrate billing to RR7

This commit is contained in:
David Nguyen
2025-02-21 01:16:23 +11:00
parent 991ce5ff46
commit 139bc265c7
10 changed files with 456 additions and 15 deletions

View File

@ -205,7 +205,7 @@ export const createTeamFromPendingTeam = async ({
pendingTeamId,
subscription,
}: CreateTeamFromPendingTeamOptions) => {
return await prisma.$transaction(async (tx) => {
const createdTeam = await prisma.$transaction(async (tx) => {
const pendingTeam = await tx.teamPending.findUniqueOrThrow({
where: {
id: pendingTeamId,
@ -249,19 +249,21 @@ export const createTeamFromPendingTeam = async ({
mapStripeSubscriptionToPrismaUpsertAction(subscription, undefined, team.id),
);
// Attach the team ID to the subscription metadata for sanity reasons.
await stripe.subscriptions
.update(subscription.id, {
metadata: {
teamId: team.id.toString(),
},
})
.catch((e) => {
console.error(e);
// Non-critical error, but we want to log it so we can rectify it.
// Todo: Teams - Alert us.
});
return team;
});
// Attach the team ID to the subscription metadata for sanity reasons.
await stripe.subscriptions
.update(subscription.id, {
metadata: {
teamId: createdTeam.id.toString(),
},
})
.catch((e) => {
console.error(e);
// Non-critical error, but we want to log it so we can rectify it.
// Todo: Teams - Alert us.
});
return createdTeam;
};

View File

@ -0,0 +1,22 @@
import type { User } from '@prisma/client';
import { getStripeCustomerByUser } from '@documenso/ee/server-only/stripe/get-customer';
import { getPortalSession } from '@documenso/ee/server-only/stripe/get-portal-session';
import { IS_BILLING_ENABLED, NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
export type CreateBillingPortalOptions = {
user: Pick<User, 'id' | 'customerId' | 'email' | 'name'>;
};
export const createBillingPortal = async ({ user }: CreateBillingPortalOptions) => {
if (!IS_BILLING_ENABLED()) {
throw new Error('Billing is not enabled');
}
const { stripeCustomer } = await getStripeCustomerByUser(user);
return getPortalSession({
customerId: stripeCustomer.id,
returnUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/settings/billing`,
});
};

View File

@ -0,0 +1,39 @@
import type { User } from '@prisma/client';
import { getCheckoutSession } from '@documenso/ee/server-only/stripe/get-checkout-session';
import { getStripeCustomerByUser } from '@documenso/ee/server-only/stripe/get-customer';
import { getPortalSession } from '@documenso/ee/server-only/stripe/get-portal-session';
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { getSubscriptionsByUserId } from '../subscription/get-subscriptions-by-user-id';
export type CreateCheckoutSession = {
user: Pick<User, 'id' | 'customerId' | 'email' | 'name'>;
priceId: string;
};
export const createCheckoutSession = async ({ user, priceId }: CreateCheckoutSession) => {
const { stripeCustomer } = await getStripeCustomerByUser(user);
const existingSubscriptions = await getSubscriptionsByUserId({ userId: user.id });
const foundSubscription = existingSubscriptions.find(
(subscription) =>
subscription.priceId === priceId &&
subscription.periodEnd &&
subscription.periodEnd >= new Date(),
);
if (foundSubscription) {
return getPortalSession({
customerId: stripeCustomer.id,
returnUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/settings/billing`,
});
}
return getCheckoutSession({
customerId: stripeCustomer.id,
priceId,
returnUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/settings/billing`,
});
};