Files
calendar/packages/trpc/server/routers/loggedInViewer/stripeCustomer.handler.ts
T
Joe Au-YeungGitHubjoe@cal.com <j.auyeung419@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
b312955838 feat: Add subscription start, trial end, and dates to billing tables (#24408)
* Add subscription start, trial end, and end dates to db

* Add subscription start, trial end, and end date to db

* Write subscription start date on new team subscriptions

* Write subscription start date for new orgs

* Fix typo in stripe billing service file (billling -> billing)

* Use `StripeBillingService.extractSubscriptionDates`

* Remove comments

* Address comment

* Fix typo in file import

* Fix typo in file import

* Add missing SubscriptionStatus enum values

- Add INCOMPLETE, INCOMPLETE_EXPIRED, UNPAID, PAUSED enum values
- These values are referenced in stripe-billing-service.ts status mapping
- Fixes type errors in billing-related code

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-14 21:12:31 -04:00

72 lines
1.7 KiB
TypeScript

import { StripeBillingService } from "@calcom/features/ee/billing/stripe-billing-service";
import { prisma } from "@calcom/prisma";
import { userMetadata } from "@calcom/prisma/zod-utils";
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
import { TRPCError } from "@trpc/server";
type StripeCustomerOptions = {
ctx: {
user: NonNullable<TrpcSessionUser>;
};
};
export const stripeCustomerHandler = async ({ ctx }: StripeCustomerOptions) => {
const {
user: { id: userId },
} = ctx;
const billingService = new StripeBillingService();
const user = await prisma.user.findUnique({
where: {
id: userId,
},
select: {
email: true,
metadata: true,
},
});
if (!user) {
throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "User not found" });
}
const metadata = userMetadata.parse(user.metadata);
let stripeCustomerId = metadata?.stripeCustomerId;
if (!stripeCustomerId) {
// Create stripe customer
const customer = await billingService.createCustomer({
email: user.email,
metadata: {
userId: userId.toString(),
},
});
await prisma.user.update({
where: {
id: userId,
},
data: {
metadata: {
...metadata,
stripeCustomerId: customer.stripeCustomerId,
},
},
});
stripeCustomerId = customer.stripeCustomerId;
}
// Fetch stripe customer
const customer = await billingService.getCustomer(stripeCustomerId);
if (customer.deleted) {
throw new TRPCError({ code: "BAD_REQUEST", message: "No stripe customer found" });
}
const username = customer?.metadata?.username || null;
return {
isPremium: !!metadata?.isPremium,
username,
};
};