Create & delete Stripe customers
This commit is contained in:
parent
d968b37e4c
commit
4dbcc62152
|
@ -73,7 +73,7 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps)
|
|||
description={
|
||||
<span className=" text-sm leading-tight text-gray-500">
|
||||
Note: This will <span className="font-medium text-gray-900">cost an extra seat ($12/m)</span> on
|
||||
your subscription if this invitee does not have a TEAM account.
|
||||
your subscription once this member accepts your invite.
|
||||
</span>
|
||||
}>
|
||||
<form onSubmit={inviteMember}>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { useForm, Controller } from "react-hook-form";
|
||||
|
||||
import { classNames } from "@calcom/lib";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
|
@ -7,7 +8,7 @@ import { trpc } from "@calcom/trpc/react";
|
|||
import { Icon } from "@calcom/ui";
|
||||
import { Button, Avatar } from "@calcom/ui/v2";
|
||||
import ImageUploader from "@calcom/ui/v2/core/ImageUploader";
|
||||
import { Form, TextField } from "@calcom/ui/v2/core/form/fields";
|
||||
import { Form, TextField, Label } from "@calcom/ui/v2/core/form/fields";
|
||||
|
||||
const CreateANewTeamForm = (props: { nextStep: () => void; setTeamId: (teamId: number) => void }) => {
|
||||
const { t } = useLocale();
|
||||
|
@ -31,6 +32,7 @@ const CreateANewTeamForm = (props: { nextStep: () => void; setTeamId: (teamId: n
|
|||
name: values.name,
|
||||
slug: values.slug || null,
|
||||
logo: values.logo || null,
|
||||
billingFrequency: values.billingFrequency,
|
||||
});
|
||||
}}>
|
||||
<div className="mb-8">
|
||||
|
@ -96,6 +98,42 @@ const CreateANewTeamForm = (props: { nextStep: () => void; setTeamId: (teamId: n
|
|||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-8">
|
||||
<Controller
|
||||
control={formMethods.control}
|
||||
name="billingFrequency"
|
||||
defaultValue="monthly"
|
||||
render={({ field: { value } }) => (
|
||||
<>
|
||||
<Label className="font-sm mt-8 text-gray-900">
|
||||
<>{t("event_triggers")}</>
|
||||
</Label>
|
||||
<div className="flex rounded-md border">
|
||||
<div
|
||||
className={classNames(
|
||||
"px-1/2 w-1/2 rounded-md py-2.5 text-center font-medium text-gray-900",
|
||||
value === "monthly" && "bg-gray-200"
|
||||
)}
|
||||
onClick={() => {
|
||||
formMethods.setValue("billingFrequency", "monthly");
|
||||
}}>
|
||||
<p>{t("monthly")}</p>
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
"px-1/2 w-1/2 rounded-md py-2.5 text-center font-medium text-gray-900",
|
||||
value === "yearly" && "bg-gray-200"
|
||||
)}
|
||||
onClick={() => {
|
||||
formMethods.setValue("billingFrequency", "yearly");
|
||||
}}>
|
||||
<p>{t("yearly")}</p>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex space-x-2">
|
||||
<Button color="secondary" href="/settings" className="w-full justify-center">
|
||||
{t("cancel")}
|
||||
|
|
|
@ -538,6 +538,9 @@ async function main() {
|
|||
],
|
||||
},
|
||||
},
|
||||
// Teams need a stripe id
|
||||
stripeCustomerId: "testId",
|
||||
stripeSubscriptionId: "testId",
|
||||
},
|
||||
[
|
||||
{
|
||||
|
|
|
@ -82,6 +82,7 @@ export const viewerTeamsRouter = createProtectedRouter()
|
|||
name: z.string(),
|
||||
slug: z.string().optional().nullable(),
|
||||
logo: z.string().optional().nullable(),
|
||||
billingFrequency: z.union([z.literal("monthly"), z.literal("yearly")]),
|
||||
}),
|
||||
async resolve({ ctx, input }) {
|
||||
const slug = input.slug || slugify(input.name);
|
||||
|
@ -94,11 +95,32 @@ export const viewerTeamsRouter = createProtectedRouter()
|
|||
|
||||
if (nameCollisions) throw new TRPCError({ code: "BAD_REQUEST", message: "Team name already taken." });
|
||||
|
||||
// Create Stripe customer
|
||||
const customer = await stripe.customers.create({
|
||||
name: input.name,
|
||||
});
|
||||
|
||||
if (!customer) throw new TRPCError({ code: "BAD_REQUEST", message: "Can not create Stripe customer" });
|
||||
|
||||
const subscription = await stripe.subscriptions.create({
|
||||
customer: customer.id,
|
||||
items: [
|
||||
{
|
||||
price:
|
||||
input.billingFrequency === "monthly"
|
||||
? process.env.STRIPE_TEAM_MONTHLY_PRICE_ID
|
||||
: process.env.STRIPE_TEAM_YEARLY_PRICE_ID,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const createTeam = await ctx.prisma.team.create({
|
||||
data: {
|
||||
name: input.name,
|
||||
slug: slug,
|
||||
logo: input.logo || null,
|
||||
stripeCustomerId: customer.id,
|
||||
stripeSubscriptionId: subscription.id,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -111,12 +133,6 @@ export const viewerTeamsRouter = createProtectedRouter()
|
|||
},
|
||||
});
|
||||
|
||||
// Create Stripe customer
|
||||
const customer = await stripe.customers.create({
|
||||
name: createTeam.name,
|
||||
metadata: { teamId: createTeam.id },
|
||||
});
|
||||
|
||||
// Sync Services: Close.com
|
||||
closeComUpsertTeamUser(createTeam, ctx.user, MembershipRole.OWNER);
|
||||
|
||||
|
@ -175,9 +191,9 @@ export const viewerTeamsRouter = createProtectedRouter()
|
|||
async resolve({ ctx, input }) {
|
||||
if (!(await isTeamOwner(ctx.user?.id, input.teamId))) throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||
|
||||
if (process.env.STRIPE_PRIVATE_KEY) {
|
||||
await downgradeTeamMembers(input.teamId);
|
||||
}
|
||||
// if (process.env.STRIPE_PRIVATE_KEY) {
|
||||
// await downgradeTeamMembers(input.teamId);
|
||||
// }
|
||||
|
||||
// delete all memberships
|
||||
await ctx.prisma.membership.deleteMany({
|
||||
|
@ -186,6 +202,21 @@ export const viewerTeamsRouter = createProtectedRouter()
|
|||
},
|
||||
});
|
||||
|
||||
// Delete customer from Stripe
|
||||
try {
|
||||
const stripeCustomerId = await ctx.prisma.team.findFirst({
|
||||
where: {
|
||||
id: input.teamId,
|
||||
},
|
||||
select: { stripeCustomerId: true },
|
||||
});
|
||||
console.log("🚀 ~ file: teams.tsx ~ line 213 ~ resolve ~ teamStripeCustomerId", stripeCustomerId);
|
||||
const response = await stripe.customers.del(stripeCustomerId.stripeCustomerId);
|
||||
console.log("🚀 ~ file: teams.tsx ~ line 214 ~ resolve ~ response", response);
|
||||
} catch {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED", message: "Could not delete customer from Stripe" });
|
||||
}
|
||||
|
||||
const deletedTeam = await ctx.prisma.team.delete({
|
||||
where: {
|
||||
id: input.teamId,
|
||||
|
|
Loading…
Reference in New Issue
Block a user