Add per-quantity TPago payment links for multi-ticket checkout.

Each ticket quantity (1-5) can have its own TPago link so checkout, emails, and admin config use the correct fixed-amount URL.
This commit is contained in:
Michilis
2026-06-18 23:59:17 +00:00
parent 1b2463f4bc
commit fc4af38e8a
11 changed files with 195 additions and 21 deletions
+20
View File
@@ -18,6 +18,10 @@ const booleanOrNumber = z.union([z.boolean(), z.number()]).transform((val) => {
const updatePaymentOptionsSchema = z.object({
tpagoEnabled: booleanOrNumber.optional(),
tpagoLink: z.string().optional().nullable(),
tpagoLink2: z.string().optional().nullable(),
tpagoLink3: z.string().optional().nullable(),
tpagoLink4: z.string().optional().nullable(),
tpagoLink5: z.string().optional().nullable(),
tpagoInstructions: z.string().optional().nullable(),
tpagoInstructionsEs: z.string().optional().nullable(),
bankTransferEnabled: booleanOrNumber.optional(),
@@ -40,6 +44,10 @@ const updatePaymentOptionsSchema = z.object({
const updateEventOverridesSchema = z.object({
tpagoEnabled: booleanOrNumber.optional().nullable(),
tpagoLink: z.string().optional().nullable(),
tpagoLink2: z.string().optional().nullable(),
tpagoLink3: z.string().optional().nullable(),
tpagoLink4: z.string().optional().nullable(),
tpagoLink5: z.string().optional().nullable(),
tpagoInstructions: z.string().optional().nullable(),
tpagoInstructionsEs: z.string().optional().nullable(),
bankTransferEnabled: booleanOrNumber.optional().nullable(),
@@ -68,6 +76,10 @@ paymentOptionsRouter.get('/', requireAuth(['admin']), async (c) => {
paymentOptions: {
tpagoEnabled: false,
tpagoLink: null,
tpagoLink2: null,
tpagoLink3: null,
tpagoLink4: null,
tpagoLink5: null,
tpagoInstructions: null,
tpagoInstructionsEs: null,
bankTransferEnabled: false,
@@ -171,6 +183,10 @@ paymentOptionsRouter.get('/event/:eventId', async (c) => {
const defaults = {
tpagoEnabled: false,
tpagoLink: null,
tpagoLink2: null,
tpagoLink3: null,
tpagoLink4: null,
tpagoLink5: null,
tpagoInstructions: null,
tpagoInstructionsEs: null,
bankTransferEnabled: false,
@@ -193,6 +209,10 @@ paymentOptionsRouter.get('/event/:eventId', async (c) => {
const merged = {
tpagoEnabled: overrides?.tpagoEnabled ?? global.tpagoEnabled,
tpagoLink: overrides?.tpagoLink ?? global.tpagoLink,
tpagoLink2: overrides?.tpagoLink2 ?? global.tpagoLink2,
tpagoLink3: overrides?.tpagoLink3 ?? global.tpagoLink3,
tpagoLink4: overrides?.tpagoLink4 ?? global.tpagoLink4,
tpagoLink5: overrides?.tpagoLink5 ?? global.tpagoLink5,
tpagoInstructions: overrides?.tpagoInstructions ?? global.tpagoInstructions,
tpagoInstructionsEs: overrides?.tpagoInstructionsEs ?? global.tpagoInstructionsEs,
bankTransferEnabled: overrides?.bankTransferEnabled ?? global.bankTransferEnabled,
+10
View File
@@ -631,11 +631,21 @@ ticketsRouter.get('/:id', async (c) => {
(db as any).select().from(payments).where(eq((payments as any).ticketId, id))
);
// Count how many tickets belong to this booking (for per-quantity payment links)
let bookingTicketCount = 1;
if (ticket.bookingId) {
const bookingTickets = await dbAll<any>(
(db as any).select().from(tickets).where(eq((tickets as any).bookingId, ticket.bookingId))
);
bookingTicketCount = bookingTickets.length || 1;
}
return c.json({
ticket: {
...ticket,
event,
payment,
bookingTicketCount,
},
});
});