refactor(launch): collapse helcim-pay duplication and use setAuthCookie helper
Some checks failed
Test / vitest (push) Successful in 11m49s
Test / playwright (push) Failing after 9m43s
Test / visual (push) Failing after 9m24s
Test / Notify on failure (push) Successful in 2s

Follow-up to 51230e5. /simplify review surfaced residual duplication
and a timer leak.

- useHelcimPay: extract _initializeTicket(metadata, errorPrefix) to
  collapse initializeTicketPayment + initializeSeriesTicketPayment
  (95% identical bodies). Drop the dead `amount` arg from initialize-
  TicketPayment — server re-derives ticket amounts in initialize-
  payment.post.js and never reads body.amount for ticket types.
  Capture timer ids and clearTimeout on resolve/reject so the 10-min
  payment timer and 5-second observer timer stop leaking after every
  payment.
- EventTicketPurchase: caller updated for the dropped arg.
- verify.post.js: replace inline jwt.sign + setCookie block with the
  setAuthCookie(event, member) helper. verify was the last hand-rolled
  caller after the helper was extracted in 208638e.
- LAUNCH_READINESS: add simplify-pass-followups bullet pointing to the
  six deferred items in docs/TODO.md.

Tests: 758 passing, 2 skipped, 0 failing.
This commit is contained in:
Jennie Robinson Faber 2026-04-25 22:13:24 +01:00
parent 51230e5151
commit 8e76ce9366
4 changed files with 24 additions and 70 deletions

View file

@ -29,26 +29,14 @@ export const useHelcimPay = () => {
}
};
// Initialize payment for event ticket purchase
const initializeTicketPayment = async (
eventId,
email,
amount,
eventTitle = null,
) => {
const _initializeTicket = async (metadata, errorPrefix) => {
try {
const response = await $fetch("/api/helcim/initialize-payment", {
method: "POST",
body: {
customerId: null,
customerCode: email, // Use email as customer code for event tickets
amount,
metadata: {
type: "event_ticket",
eventId,
email,
eventTitle,
},
customerCode: metadata.email,
metadata,
},
});
@ -62,50 +50,24 @@ export const useHelcimPay = () => {
};
}
throw new Error("Failed to initialize ticket payment session");
throw new Error(`Failed to initialize ${errorPrefix} session`);
} catch (error) {
console.error("Ticket payment initialization error:", error);
console.error(`${errorPrefix} initialization error:`, error);
throw error;
}
};
// Initialize payment for series pass purchase
const initializeSeriesTicketPayment = async (
seriesId,
email,
seriesTitle = null,
) => {
try {
const response = await $fetch("/api/helcim/initialize-payment", {
method: "POST",
body: {
customerId: null,
customerCode: email,
metadata: {
type: "series_ticket",
seriesId,
email,
eventTitle: seriesTitle,
},
},
});
const initializeTicketPayment = (eventId, email, eventTitle = null) =>
_initializeTicket(
{ type: "event_ticket", eventId, email, eventTitle },
"ticket payment",
);
if (response.success) {
checkoutToken = response.checkoutToken;
secretToken = response.secretToken;
return {
success: true,
checkoutToken: response.checkoutToken,
amount: response.amount,
};
}
throw new Error("Failed to initialize series payment session");
} catch (error) {
console.error("Series payment initialization error:", error);
throw error;
}
};
const initializeSeriesTicketPayment = (seriesId, email, seriesTitle = null) =>
_initializeTicket(
{ type: "series_ticket", seriesId, email, eventTitle: seriesTitle },
"series payment",
);
// Show payment modal
const showPaymentModal = () => {
@ -179,6 +141,7 @@ export const useHelcimPay = () => {
if (typeof window.appendHelcimPayIframe === "function") {
// Set up event listener for HelcimPay.js responses
const helcimPayJsIdentifierKey = "helcim-pay-js-" + checkoutToken;
let observerTimer, paymentTimer;
const handleHelcimPayEvent = (event) => {
console.log("Received window message:", event.data);
@ -188,6 +151,8 @@ export const useHelcimPay = () => {
// Remove event listener to prevent multiple responses
window.removeEventListener("message", handleHelcimPayEvent);
clearTimeout(observerTimer);
clearTimeout(paymentTimer);
// Close the Helcim modal
if (typeof window.removeHelcimPayIframe === "function") {
@ -277,10 +242,10 @@ export const useHelcimPay = () => {
);
// Clean up observer after a timeout
setTimeout(() => observer.disconnect(), 5000);
observerTimer = setTimeout(() => observer.disconnect(), 5000);
// Add timeout to clean up if no response (10 minutes for manual card entry)
setTimeout(() => {
paymentTimer = setTimeout(() => {
console.log("Payment timeout reached, cleaning up event listener...");
window.removeEventListener("message", handleHelcimPayEvent);
reject(new Error("Payment timeout - no response received"));