Files
fotospiel-app/resources/js/admin/mobile/lib/billingCheckout.ts
Codex Agent 24f053d4c4
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Add photobooth connect codes and uploader pipeline
2026-01-12 17:02:50 +01:00

83 lines
2.0 KiB
TypeScript

export type PendingCheckout = {
packageId: number | null;
checkoutSessionId?: string | null;
startedAt: number;
};
export const PENDING_CHECKOUT_TTL_MS = 1000 * 60 * 30;
export const CHECKOUT_STORAGE_KEY = 'admin.billing.checkout.pending.v1';
export function isCheckoutExpired(
pending: PendingCheckout,
now = Date.now(),
ttl = PENDING_CHECKOUT_TTL_MS,
): boolean {
return now - pending.startedAt > ttl;
}
export function loadPendingCheckout(
now = Date.now(),
ttl = PENDING_CHECKOUT_TTL_MS,
): PendingCheckout | null {
if (typeof window === 'undefined') {
return null;
}
try {
const raw = window.sessionStorage.getItem(CHECKOUT_STORAGE_KEY);
if (! raw) {
return null;
}
const parsed = JSON.parse(raw) as PendingCheckout;
if (typeof parsed?.startedAt !== 'number') {
return null;
}
const packageId =
typeof parsed.packageId === 'number' && Number.isFinite(parsed.packageId)
? parsed.packageId
: null;
const checkoutSessionId = typeof parsed.checkoutSessionId === 'string' ? parsed.checkoutSessionId : null;
if (now - parsed.startedAt > ttl) {
return null;
}
return {
packageId,
checkoutSessionId,
startedAt: parsed.startedAt,
};
} catch {
return null;
}
}
export function storePendingCheckout(next: PendingCheckout | null): void {
if (typeof window === 'undefined') {
return;
}
try {
if (! next) {
window.sessionStorage.removeItem(CHECKOUT_STORAGE_KEY);
} else {
window.sessionStorage.setItem(CHECKOUT_STORAGE_KEY, JSON.stringify(next));
}
} catch {
// Ignore storage errors.
}
}
export function shouldClearPendingCheckout(
pending: PendingCheckout,
activePackageId: number | null,
now = Date.now(),
ttl = PENDING_CHECKOUT_TTL_MS,
): boolean {
if (isCheckoutExpired(pending, now, ttl)) {
return true;
}
if (pending.packageId && activePackageId && pending.packageId === activePackageId) {
return true;
}
return false;
}