Files
documenso/packages/trpc/server/organisation-router/create-organisation.ts
David Nguyen 2805478e0d feat: billing
2025-05-19 12:38:50 +10:00

77 lines
2.4 KiB
TypeScript

import { createCheckoutSession } from '@documenso/ee/server-only/stripe/create-checkout-session';
import { createCustomer } from '@documenso/ee/server-only/stripe/create-customer';
import { IS_BILLING_ENABLED, NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { createOrganisation } from '@documenso/lib/server-only/organisation/create-organisation';
import { generateStripeOrganisationCreateMetadata } from '@documenso/lib/utils/billing';
import { prisma } from '@documenso/prisma';
import { authenticatedProcedure } from '../trpc';
import {
ZCreateOrganisationRequestSchema,
ZCreateOrganisationResponseSchema,
} from './create-organisation.types';
export const createOrganisationRoute = authenticatedProcedure
// .meta(createOrganisationMeta)
.input(ZCreateOrganisationRequestSchema)
.output(ZCreateOrganisationResponseSchema)
.mutation(async ({ input, ctx }) => {
const { name, priceId } = input;
const { user } = ctx;
// Todo: orgs
// Todo: Check if user has reached limit.
if (IS_BILLING_ENABLED() && !priceId) {
const userOrganisations = await prisma.organisation.findMany({
where: {
ownerUserId: user.id,
subscription: {
is: null,
},
},
});
if (userOrganisations.length >= 1) {
throw new AppError(AppErrorCode.LIMIT_EXCEEDED, {
message: 'You have reached the maximum number of free organisations.',
});
}
}
// Create checkout session for payment.
if (IS_BILLING_ENABLED() && priceId) {
// if (!claimId) {
// throw new AppError(AppErrorCode.INVALID_REQUEST, {
// message: 'Claim ID is required',
// });
// }
const customer = await createCustomer({
email: user.email,
name: user.name || user.email,
});
const checkoutUrl = await createCheckoutSession({
priceId,
customerId: customer.id,
returnUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/settings/organisations`,
subscriptionMetadata: generateStripeOrganisationCreateMetadata(name, user.id),
});
return {
paymentRequired: true,
checkoutUrl,
};
}
await createOrganisation({
userId: user.id,
name,
});
return {
paymentRequired: false,
};
});