mirror of
https://github.com/documenso/documenso.git
synced 2025-11-18 02:32:00 +10:00
97 lines
2.8 KiB
TypeScript
97 lines
2.8 KiB
TypeScript
import type Stripe from 'stripe';
|
|
|
|
import { stripe } from '@documenso/lib/server-only/stripe';
|
|
import {
|
|
getTeamSeatPriceId,
|
|
isSomeSubscriptionsActiveAndCommunityPlan,
|
|
} from '@documenso/lib/utils/billing';
|
|
import { prisma } from '@documenso/prisma';
|
|
import type { Subscription, Team, User } from '@documenso/prisma/client';
|
|
|
|
import { getStripeCustomerByUser } from './get-customer';
|
|
|
|
type TransferStripeSubscriptionOptions = {
|
|
user: User & { Subscription: Subscription[] };
|
|
team: Team;
|
|
};
|
|
|
|
/**
|
|
* Transfer the Stripe Team seats subscription from one user to another.
|
|
*
|
|
* Will create a new subscription for the new owner and cancel the old one.
|
|
*
|
|
* Returns the new subscription, null if no subscription is needed (for community plan).
|
|
*/
|
|
export const transferTeamSubscription = async ({
|
|
user,
|
|
team,
|
|
}: TransferStripeSubscriptionOptions) => {
|
|
const teamSeatPriceId = getTeamSeatPriceId();
|
|
const { stripeCustomer } = await getStripeCustomerByUser(user);
|
|
|
|
const newOwnerHasCommunityPlan = isSomeSubscriptionsActiveAndCommunityPlan(user.Subscription);
|
|
const currentTeamSubscriptionId = team.subscriptionId;
|
|
|
|
let oldSubscription: Stripe.Subscription | null = null;
|
|
let newSubscription: Stripe.Subscription | null = null;
|
|
|
|
if (currentTeamSubscriptionId) {
|
|
oldSubscription = await stripe.subscriptions.retrieve(currentTeamSubscriptionId);
|
|
}
|
|
|
|
const numberOfSeats = await prisma.teamMember.count({
|
|
where: {
|
|
teamId: team.id,
|
|
},
|
|
});
|
|
|
|
if (!newOwnerHasCommunityPlan) {
|
|
let stripeCreateSubscriptionPayload: Stripe.SubscriptionCreateParams = {
|
|
customer: stripeCustomer.id,
|
|
items: [
|
|
{
|
|
price: teamSeatPriceId,
|
|
quantity: numberOfSeats,
|
|
},
|
|
],
|
|
metadata: {
|
|
teamId: team.id.toString(),
|
|
},
|
|
};
|
|
|
|
// If no payment method is attached to the new owner Stripe customer account, send an
|
|
// invoice instead.
|
|
if (!stripeCustomer.invoice_settings.default_payment_method) {
|
|
stripeCreateSubscriptionPayload = {
|
|
...stripeCreateSubscriptionPayload,
|
|
collection_method: 'send_invoice',
|
|
days_until_due: 7,
|
|
};
|
|
}
|
|
|
|
newSubscription = await stripe.subscriptions.create(stripeCreateSubscriptionPayload);
|
|
}
|
|
|
|
if (oldSubscription) {
|
|
try {
|
|
// Set the quantity to 0 so we can refund/charge the old Stripe customer the prorated amount.
|
|
await stripe.subscriptions.update(oldSubscription.id, {
|
|
items: oldSubscription.items.data.map((item) => ({
|
|
id: item.id,
|
|
quantity: 0,
|
|
})),
|
|
});
|
|
|
|
await stripe.subscriptions.cancel(oldSubscription.id, {
|
|
invoice_now: true,
|
|
prorate: false,
|
|
});
|
|
} catch (e) {
|
|
// Do not error out since we can't easily undo the transfer.
|
|
// Todo: Teams - Alert us.
|
|
}
|
|
}
|
|
|
|
return newSubscription;
|
|
};
|