import { TRPCError } from "@trpc/server"; import { z } from "zod/v4"; import OrderTypeEnum from "~/schemas/public/OrderTypeEnum"; import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc"; import { getPagamentoDataForCheckout, getRicevutaData, type PreparedPaymentData, preparePayment, previewSaldo, } from "~/server/controllers/pagamenti.controller"; import { db } from "~/server/db"; import { TypstGenerate } from "~/server/services/typst.service"; import { zOrdineId, zRinnovoId, zServizioId } from "~/server/utils/zod_types"; // Create a new ratelimiter, that allows 10 requests per 10 seconds /* const ratelimit = new RateLimiterHandler({ maxRequests: 10, windowSize: 60, analytics: false, }); */ export const pagamentiRouter = createTRPCRouter({ getPaymentFromIntent: protectedProcedure .input(z.object({ pIntentId: z.string() })) .query(async ({ input }) => { try { const ordine = await db .selectFrom("ordini") .selectAll("ordini") .where("ordini.intent_id", "=", input.pIntentId) .executeTakeFirst(); return ordine || null; } catch (error) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Errore durante il recupero del pagamento: ${(error as Error).message}`, }); } }), preparePayment: protectedProcedure .input( z.object({ servizioId: zServizioId, type: z.enum(OrderTypeEnum), }), ) .output( z.discriminatedUnion("success", [ z.object({ success: z.literal(true), data: z.custom(), }), z.object({ success: z.literal(false), message: z.string(), }), ]), ) .query(async ({ input }) => { if (input.type === OrderTypeEnum.Rinnovo) { return { success: false, message: "Use preparePaymentRinnovi for Rinnovo payments", }; } return await preparePayment({ type: input.type, servizioId: input.servizioId, }); }), previewSaldo: protectedProcedure .input( z.object({ servizioId: zServizioId, }), ) .query(async ({ input }) => { return await previewSaldo(input.servizioId); }), preparePaymentRinnovi: protectedProcedure .input( z.object({ rinnovoId: zRinnovoId, }), ) .output( z.discriminatedUnion("success", [ z.object({ success: z.literal(true), data: z.custom(), }), z.object({ success: z.literal(false), message: z.string(), }), ]), ) .query(async ({ input }) => { return await preparePayment({ type: OrderTypeEnum.Rinnovo, rinnovoId: input.rinnovoId, }); }), getPagamentoDataForCheckout: protectedProcedure .input(z.object({ ordineId: zOrdineId })) .query(async ({ input }) => { return await getPagamentoDataForCheckout(input.ordineId); }), getRicevutaCortesiaPdf: protectedProcedure .input(z.object({ ordineId: zOrdineId })) .mutation(async ({ input }) => { try { const ricData = await getRicevutaData(input.ordineId); const pdf = await TypstGenerate({ templateId: "receipt.typ", data: ricData.data, }); return { title: ricData.title, pdf: pdf.toString("base64") }; } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Errore nella generazione della ricevuta di cortesia: ${(e as Error).message}`, }); } }), getRicevutaCortesiaPdfQuery: protectedProcedure .input(z.object({ ordineId: zOrdineId })) .query(async ({ input }) => { try { const ricData = await getRicevutaData(input.ordineId); const pdf = await TypstGenerate({ templateId: "receipt.typ", data: ricData.data, }); return { title: ricData.title, pdf: pdf.toString("base64") }; } catch (e) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Errore nella generazione della ricevuta di cortesia: ${(e as Error).message}`, }); } }), });