Skip to content

Commit 1f69b1a

Browse files
committed
feat: configure stripe portal
1 parent 8531ff2 commit 1f69b1a

File tree

2 files changed

+62
-32
lines changed

2 files changed

+62
-32
lines changed

src/trpc/routers/billing-router/procedures/stripe-portal.ts

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,58 @@ import { invariant } from "@/lib/error";
33
import { checkMembership } from "@/server/auth";
44
import { createOrRetrieveCustomer, stripe } from "@/server/stripe";
55
import { withAuth } from "@/trpc/api/trpc";
6+
import { ZodStripePortalMutationSchema } from "../schema";
67

7-
export const stripePortalProcedure = withAuth.mutation(async ({ ctx }) => {
8-
const { db, session } = ctx;
9-
10-
const { url } = await db.$transaction(async (tx) => {
11-
const { companyId } = await checkMembership({ session, tx });
12-
13-
let customer: string;
14-
try {
15-
customer = await createOrRetrieveCustomer({
16-
tx,
17-
companyId,
18-
email: "",
19-
});
20-
} catch (_error) {
21-
throw new Error("Unable to access customer record.");
22-
}
23-
24-
invariant(customer, "Could not get customer.");
25-
26-
try {
27-
const { url } = await stripe.billingPortal.sessions.create({
28-
customer,
29-
return_url: `${env.NEXT_PUBLIC_BASE_URL}/${session.user.companyPublicId}/settings/billing`,
30-
});
31-
32-
return { url };
33-
} catch (_error) {
34-
throw new Error("Could not create billing portal.");
35-
}
36-
});
8+
export const stripePortalProcedure = withAuth
9+
.input(ZodStripePortalMutationSchema)
10+
.mutation(async ({ ctx, input }) => {
11+
const { db, session } = ctx;
12+
13+
const { url } = await db.$transaction(async (tx) => {
14+
const { companyId } = await checkMembership({ session, tx });
15+
16+
let customer: string;
17+
try {
18+
customer = await createOrRetrieveCustomer({
19+
tx,
20+
companyId,
21+
email: "",
22+
});
23+
} catch (_error) {
24+
throw new Error("Unable to access customer record.");
25+
}
26+
27+
invariant(customer, "Could not get customer.");
28+
console.log({ input });
3729

38-
return { url };
39-
});
30+
try {
31+
const { url } = await stripe.billingPortal.sessions.create({
32+
customer,
33+
return_url: `${env.NEXT_PUBLIC_BASE_URL}/${session.user.companyPublicId}/settings/billing`,
34+
flow_data: {
35+
...(input.type === "cancel"
36+
? {
37+
type: "subscription_cancel",
38+
subscription_cancel: {
39+
subscription: input.subscription,
40+
},
41+
}
42+
: {
43+
type: "subscription_update",
44+
subscription_update: {
45+
subscription: input.subscription,
46+
},
47+
}),
48+
},
49+
});
50+
51+
return { url };
52+
} catch (_error) {
53+
console.log({ _error });
54+
55+
throw new Error("Could not create billing portal.");
56+
}
57+
});
58+
59+
return { url };
60+
});

src/trpc/routers/billing-router/schema.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,12 @@ export const ZodCheckoutMutationSchema = z.object({
99
export type TypeZodCheckoutMutationSchema = z.infer<
1010
typeof ZodCheckoutMutationSchema
1111
>;
12+
13+
export const ZodStripePortalMutationSchema = z.object({
14+
type: z.enum(["cancel", "update"]),
15+
subscription: z.string(),
16+
});
17+
18+
export type TypeZodStripePortalMutationSchema = z.infer<
19+
typeof ZodStripePortalMutationSchema
20+
>;

0 commit comments

Comments
 (0)