import { z } from "zod"; import { procedure, router } from "../trpc"; import { db } from "@/db/PrismaClient"; import { TRPCError } from '@trpc/server'; import Stripe from 'stripe' import { getSession } from "@/utils/planetscale/session"; const stripe = new Stripe(process.env.STRIPE_SECRET_TEST_KEY, { apiVersion: '2022-11-15' }) export const stripeRouter = router({ checkoutSession: procedure .mutation(async ({ ctx }) => { try{ const {req, res} = ctx; const sessionData = await getSession(req, res); if (!sessionData.session_valid) { throw new TRPCError({ code: 'UNAUTHORIZED', message: 'User is not signed in.' }) } const checkoutSession = await stripe.checkout.sessions.create({ mode: 'subscription', customer: sessionData.user.stripeCustomerId!, line_items: [ { price: 'price_1Ne8jiIJijgwhzBsDhsFA7VS', //hard set for testing purposes quantity: 1, } ], success_url: `http://${process.env.VERCEL_URL}/?session_id={CHECKOUT_SESSION_ID}`, cancel_url: `http://${process.env.VERCEL_URL}/?cancelledPayment=true`, subscription_data: { metadata: { payingUserId: sessionData.user.userId ?? '', "SuperFit-auth": req.cookies['SuperFit-session-token'] ?? '' } } }) if (!checkoutSession.url) { throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message: 'Stripe Error: Could not create checkout session' }) } return checkoutSession.url; } catch (error) { console.log(error) if (error instanceof TRPCError) throw error; throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message: (error as Error).message, cause: error }); } }), portal: procedure .mutation(async ({ ctx }) => { try { const {req, res} = ctx; const sessionData = await getSession(req, res); if (!sessionData.session_valid) { throw new TRPCError({ code: 'UNAUTHORIZED', message: 'User is not signed in.' }) } const session = await stripe.billingPortal.sessions.create({ customer: sessionData.user.stripeCustomerId!, return_url: `http://${process.env.VERCEL_URL}/account/dashboard` }) return { url: session.url } } catch (error) { console.log(error) if (error instanceof TRPCError) throw error; throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message: (error as Error).message, cause: error }); } }), getSubscriptionData: procedure .input(z.object({ stripeCustomerId: z.string(), session_valid: z.boolean() })) .query(async ({ ctx, input }) => { const { stripeCustomerId, session_valid } = input; if (!session_valid) { throw new TRPCError({ code: 'UNAUTHORIZED', message: 'User is not signed in.' }) } const subscriptionData = await stripe.subscriptions.list({ customer: stripeCustomerId }) const plans = []; for (const subscription of subscriptionData.data) { const planDetails = await stripe.products.retrieve(subscription.items.data[0].price.product as string); console.log(planDetails) const dataToPush = { id: planDetails.id, name: planDetails.name, description: planDetails.description != null ? planDetails.description : `${planDetails.name} plan`, // Add any other plan details you need here } plans.push(dataToPush); } console.log(plans) return { subscriptions: subscriptionData.data, plans: plans } }), cancelSubscription: procedure .input(z.object({ subscriptionId: z.string() })) .query(async ({ input, ctx }) => { const { subscriptionId } = input; const data = await stripe.subscriptions.cancel(subscriptionId) const response = { endDate: data.cancel_at, } return response }) })