snapify-authentik/src/server/api/routers/stripe.ts
2023-07-13 00:24:10 +02:00

120 lines
3.7 KiB
TypeScript

import { env } from "~/env.mjs";
import { getOrCreateStripeCustomerIdForUser } from "~/server/stripe-webhook-handlers";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
import { z } from "zod";
export const stripeRouter = createTRPCRouter({
createCheckoutSession: protectedProcedure
.input(
z.object({ billedAnnually: z.boolean(), recordModalOpen: z.boolean() })
)
.mutation(
async ({ ctx: { prisma, stripe, session, req, posthog }, input }) => {
if (
!stripe ||
!env.STRIPE_ANNUAL_PRICE_ID ||
!env.STRIPE_MONTHLY_PRICE_ID
) {
throw new Error("Stripe env variables not set");
}
const customerId = await getOrCreateStripeCustomerIdForUser({
prisma,
stripe,
userId: session.user?.id,
});
if (!customerId) {
throw new Error("Could not create customer");
}
const baseUrl =
env.NODE_ENV === "development"
? `http://${req.headers.host ?? "localhost:3000"}`
: `https://${req.headers.host ?? env.NEXTAUTH_URL}`;
const checkoutSession = await stripe.checkout.sessions.create({
customer: customerId,
client_reference_id: session.user?.id,
payment_method_types: ["card"],
allow_promotion_codes: true,
mode: "subscription",
line_items: [
{
price: input.billedAnnually
? env.STRIPE_ANNUAL_PRICE_ID
: env.STRIPE_MONTHLY_PRICE_ID,
quantity: 1,
},
],
success_url: input.recordModalOpen
? `${baseUrl}/videos?checkoutCanceled=false&close=true`
: `${baseUrl}/videos?checkoutCanceled=false&close=false`,
cancel_url: `${baseUrl}/videos?checkoutCanceled=true`,
subscription_data: {
metadata: {
userId: session.user?.id,
},
},
});
if (!checkoutSession) {
throw new Error("Could not create checkout session");
}
posthog?.capture({
distinctId: session.user.id,
event: "visiting checkout page",
properties: {
billingCycle: input.billedAnnually ? "annual" : "monthly",
},
});
void posthog?.shutdownAsync();
return { checkoutUrl: checkoutSession.url };
}
),
createBillingPortalSession: protectedProcedure.mutation(
async ({ ctx: { stripe, session, prisma, req, posthog } }) => {
if (!stripe) {
throw new Error("Stripe env variables not set");
}
const customerId = await getOrCreateStripeCustomerIdForUser({
prisma,
stripe,
userId: session.user?.id,
});
if (!customerId) {
throw new Error("Could not create customer");
}
const baseUrl =
env.NODE_ENV === "development"
? `http://${req.headers.host ?? "localhost:3000"}`
: `https://${req.headers.host ?? env.NEXTAUTH_URL}`;
const stripeBillingPortalSession =
await stripe.billingPortal.sessions.create({
customer: customerId,
return_url: `${baseUrl}/videos`,
});
if (!stripeBillingPortalSession) {
throw new Error("Could not create billing portal session");
}
posthog?.capture({
distinctId: session.user.id,
event: "visiting billing portal page",
properties: {
stripeSubscriptionStatus: session.user.stripeSubscriptionStatus,
},
});
void posthog?.shutdownAsync();
return { billingPortalUrl: stripeBillingPortalSession.url };
}
),
});