@seatlayer/js 0.52.0 → 0.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +0,0 @@
1
- var __typeError = (msg) => {
2
- throw TypeError(msg);
3
- };
4
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
8
- var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
9
-
10
- export {
11
- __privateGet,
12
- __privateAdd,
13
- __privateSet,
14
- __privateMethod
15
- };
16
- //# sourceMappingURL=chunk-HMLY7DHA.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,370 +0,0 @@
1
- import "./chunk-HMLY7DHA.js";
2
-
3
- // src/hostedCheckout.ts
4
- var CONFIRM_TIMEOUT_MS = 9e4;
5
- var CONFIRM_POLL_MS = 2e3;
6
- var RAZORPAY_SCRIPT = "https://checkout.razorpay.com/v1/checkout.js";
7
- var STYLE_ID = "seatlayer-checkout-style";
8
- var CSS = (
9
- /* @sl-css */
10
- `
11
- .sl-hco{position:absolute;inset:0;z-index:60;display:flex;align-items:center;justify-content:center;
12
- padding:16px;background:color-mix(in srgb, var(--sl-bg) 82%, transparent);backdrop-filter:blur(3px)}
13
- .sl-hco-card{width:100%;max-width:380px;max-height:100%;overflow:auto;padding:22px;
14
- background:var(--sl-surface);color:var(--sl-text);border:1px solid var(--sl-line);
15
- border-radius:var(--sl-radius);box-shadow:0 18px 48px rgba(0,0,0,.28)}
16
- .sl-hco-title{margin:0 0 14px;font-size:19px;font-weight:650;letter-spacing:-.01em}
17
- .sl-hco-summary{margin-bottom:16px;padding-bottom:14px;border-bottom:1px solid var(--sl-line)}
18
- .sl-hco-seats{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px}
19
- .sl-hco-seat{padding:3px 8px;font-size:12px;font-weight:600;border-radius:calc(var(--sl-radius) * .5);
20
- background:var(--sl-bg);border:1px solid var(--sl-line)}
21
- .sl-hco-total{display:flex;justify-content:space-between;align-items:baseline;font-size:14px}
22
- .sl-hco-total strong{font-size:17px;font-weight:700}
23
- .sl-hco-label{display:block;margin:12px 0 5px;font-size:12px;font-weight:600;color:var(--sl-muted)}
24
- .sl-hco-input{width:100%;padding:10px 11px;font:inherit;font-size:15px;color:var(--sl-text);
25
- background:var(--sl-bg);border:1px solid var(--sl-line);border-radius:calc(var(--sl-radius) * .55)}
26
- .sl-hco-input:focus-visible{outline:2px solid var(--sl-accent);outline-offset:1px}
27
- .sl-hco-pay{width:100%;margin-top:16px;padding:12px;font:inherit;font-size:15px;font-weight:650;
28
- color:var(--sl-accent-ink);background:var(--sl-accent);border:0;
29
- border-radius:calc(var(--sl-radius) * .55);cursor:pointer}
30
- .sl-hco-pay[disabled]{opacity:.5;cursor:default}
31
- .sl-hco-back{width:100%;margin-top:8px;padding:10px;font:inherit;font-size:14px;color:var(--sl-muted);
32
- background:none;border:0;cursor:pointer;text-decoration:underline}
33
- .sl-hco-note{margin:12px 0 0;font-size:12px;line-height:1.5;color:var(--sl-muted)}
34
- .sl-hco-note a{color:inherit;text-decoration:underline;text-underline-offset:2px}
35
- .sl-hco-status{margin:8px 0 0;font-size:14px;line-height:1.55}
36
- .sl-hco-error{color:var(--sl-danger, #c0392b)}
37
- .sl-hco-receipt{display:grid;grid-template-columns:auto 1fr;gap:4px 14px;margin:14px 0 0;font-size:13px}
38
- .sl-hco-receipt dt{color:var(--sl-muted)}
39
- .sl-hco-receipt dd{margin:0;text-align:right}
40
- .sl-hco-ref{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;word-break:break-all}
41
- .sl-hco-tickets{display:block;width:100%;margin-top:14px;padding:12px;font:inherit;font-size:15px;
42
- font-weight:650;text-align:center;text-decoration:none;color:var(--sl-accent-ink);
43
- background:var(--sl-accent);border-radius:calc(var(--sl-radius) * .55)}
44
- `
45
- );
46
- function ensureStyle() {
47
- if (typeof document === "undefined" || document.getElementById(STYLE_ID)) return;
48
- const el2 = document.createElement("style");
49
- el2.id = STYLE_ID;
50
- el2.textContent = CSS;
51
- document.head.appendChild(el2);
52
- }
53
- function formatMoney(amount, currency) {
54
- try {
55
- return new Intl.NumberFormat(void 0, { style: "currency", currency }).format(amount);
56
- } catch {
57
- return `${amount.toFixed(2)} ${currency}`;
58
- }
59
- }
60
- function unavailableCopy(reason, seatCount) {
61
- const held = `${seatCount} ${seatCount === 1 ? "seat is" : "seats are"} held for a limited time.`;
62
- if (reason === "payments_off_for_event") {
63
- return {
64
- title: "This event isn\u2019t sold online",
65
- body: `${held} The organiser isn\u2019t taking payment for this event here.`,
66
- detail: "Nothing has been charged. Check where you found this event for how to get tickets."
67
- };
68
- }
69
- if (reason === "unavailable_for_event") {
70
- return {
71
- title: "This event isn\u2019t taking payment yet",
72
- body: `${held} Online payment is not switched on for this event.`,
73
- detail: "Nothing has been charged. If you were sent here to pay, let the organiser know \u2014 only they can turn payment on for this event."
74
- };
75
- }
76
- return {
77
- title: "Finish in the ticketing checkout",
78
- body: `${held} Payment for this event is taken elsewhere.`,
79
- detail: "Nothing has been charged. Continue in the checkout on this page to pay for your seats."
80
- };
81
- }
82
- function errorCopy(code) {
83
- switch (code) {
84
- case "gateway_not_connected":
85
- case "payments_not_enabled_for_event":
86
- return "This event is not taking online payments. Contact the organiser to buy these seats.";
87
- case "provider_mismatch":
88
- return "This event\u2019s payment setup changed while you were choosing. Nothing was charged \u2014 please try again.";
89
- case "hold_not_active":
90
- case "hold_not_found":
91
- return "Your seats were released before checkout started. Nothing was charged \u2014 please pick again.";
92
- case "checkout_already_started":
93
- return "A payment for these seats is already in progress. Finish that one, or wait for it to time out before starting again.";
94
- case "event_closed":
95
- return "Sales for this event have closed.";
96
- case "insufficient_hosted_credits":
97
- return "Ticket sales are temporarily paused while the organiser updates their SeatLayer balance. Nothing was charged \u2014 please try again later or contact the organiser.";
98
- case "gateway_currency_mismatch":
99
- case "unsupported_currency":
100
- case "mixed_currency_hold":
101
- case "price_unusable":
102
- return "These seats cannot be checked out right now because of a pricing configuration problem. Nothing was charged \u2014 please contact the organiser.";
103
- case "rate_limited":
104
- return "Too many attempts. Wait a moment and try again.";
105
- default:
106
- return "We could not start the payment. Nothing was charged \u2014 please try again.";
107
- }
108
- }
109
- function loadRazorpay() {
110
- const existing = window.Razorpay;
111
- if (existing) return Promise.resolve(existing);
112
- return new Promise((resolve, reject) => {
113
- const previous = document.querySelector(`script[src="${RAZORPAY_SCRIPT}"]`);
114
- const tag = previous ?? document.createElement("script");
115
- const done = () => {
116
- const ctor = window.Razorpay;
117
- if (ctor) resolve(ctor);
118
- else reject(new Error("razorpay_unavailable"));
119
- };
120
- tag.addEventListener("load", done, { once: true });
121
- tag.addEventListener("error", () => reject(new Error("razorpay_script_failed")), { once: true });
122
- if (previous) return;
123
- tag.src = RAZORPAY_SCRIPT;
124
- tag.async = true;
125
- document.head.appendChild(tag);
126
- });
127
- }
128
- function el(tag, className, text) {
129
- const node = document.createElement(tag);
130
- if (className) node.className = className;
131
- if (text !== void 0) node.textContent = text;
132
- return node;
133
- }
134
- function mountCheckout(mount) {
135
- ensureStyle();
136
- let live = true;
137
- let confirmed = false;
138
- const scrim = el("div", "sl-hco");
139
- scrim.setAttribute("role", "dialog");
140
- scrim.setAttribute("aria-modal", "true");
141
- const card = el("div", "sl-hco-card");
142
- scrim.appendChild(card);
143
- const destroy = () => {
144
- live = false;
145
- scrim.remove();
146
- document.removeEventListener("keydown", onKey, true);
147
- };
148
- const cancel = () => {
149
- destroy();
150
- mount.onCancel();
151
- };
152
- function onKey(event) {
153
- if (event.key !== "Escape" || !scrim.isConnected) return;
154
- event.stopPropagation();
155
- event.preventDefault();
156
- cancel();
157
- }
158
- document.addEventListener("keydown", onKey, true);
159
- const title = el("h2", "sl-hco-title", "Checkout");
160
- const titleId = `sl-hco-t-${Math.random().toString(36).slice(2, 8)}`;
161
- title.id = titleId;
162
- scrim.setAttribute("aria-labelledby", titleId);
163
- const show = (...nodes) => {
164
- card.replaceChildren(title, ...nodes);
165
- };
166
- const fail = (message) => {
167
- if (!live) return;
168
- const status = el("p", "sl-hco-status sl-hco-error", message);
169
- status.setAttribute("role", "alert");
170
- const back2 = el("button", "sl-hco-back", "Back to seats");
171
- back2.type = "button";
172
- back2.addEventListener("click", cancel);
173
- show(status, back2);
174
- };
175
- const waiting = (message) => {
176
- if (!live) return;
177
- const status = el("p", "sl-hco-status", message);
178
- status.setAttribute("role", "status");
179
- show(status);
180
- };
181
- const awaitConfirmation = async (orderId) => {
182
- waiting("Payment received \u2014 confirming your seats\u2026");
183
- const deadline = Date.now() + CONFIRM_TIMEOUT_MS;
184
- while (live && Date.now() < deadline) {
185
- try {
186
- const body = await mount.orderStatus(orderId);
187
- if (!live) return;
188
- if (body.status === "confirmed") {
189
- confirmed = true;
190
- title.textContent = "Your tickets are confirmed";
191
- const status = el(
192
- "p",
193
- "sl-hco-status",
194
- `${body.seatCount} ${body.seatCount === 1 ? "seat" : "seats"} confirmed. Your tickets \u2014 with their door QR codes \u2014 are in your email.`
195
- );
196
- const receipt = el("dl", "sl-hco-receipt");
197
- const seatLabels = (body.tickets ?? []).map((t) => t.label);
198
- if (seatLabels.length) {
199
- receipt.append(el("dt", void 0, "Seats"), el("dd", void 0, seatLabels.join(", ")));
200
- }
201
- receipt.append(
202
- el("dt", void 0, "Paid"),
203
- el("dd", void 0, `${body.amountFormatted} ${body.currency}`),
204
- el("dt", void 0, "Order"),
205
- el("dd", "sl-hco-ref", body.orderId)
206
- );
207
- const close = el("button", "sl-hco-back", "Close");
208
- close.type = "button";
209
- close.addEventListener("click", cancel);
210
- if (body.ticketUrl) {
211
- const view = el("a", "sl-hco-tickets", "View tickets & QR codes");
212
- view.href = body.ticketUrl;
213
- view.target = "_blank";
214
- view.rel = "noreferrer";
215
- show(status, receipt, view, close);
216
- } else {
217
- show(status, receipt, close);
218
- }
219
- mount.onConfirmed(body);
220
- return;
221
- }
222
- if (body.status === "failed" || body.status === "expired") {
223
- fail(body.status === "expired" ? "Your seats were released before payment completed. Nothing was charged \u2014 please pick again." : "The payment did not complete. If you were charged, it has been refunded automatically.");
224
- return;
225
- }
226
- } catch {
227
- }
228
- await new Promise((resolve) => setTimeout(resolve, CONFIRM_POLL_MS));
229
- }
230
- if (!live || confirmed) return;
231
- fail("Still confirming with the payment provider. If your payment went through, your tickets will arrive by email shortly \u2014 you do not need to pay again.");
232
- };
233
- if (mount.state.kind === "unavailable") {
234
- const copy = unavailableCopy(mount.state.reason, mount.state.seatCount);
235
- title.textContent = copy.title;
236
- const kicker = el("p", "sl-hco-label", "Seats held");
237
- const back2 = el("button", "sl-hco-back", "Back to seat map");
238
- back2.type = "button";
239
- back2.addEventListener("click", cancel);
240
- card.replaceChildren(
241
- kicker,
242
- title,
243
- el("p", "sl-hco-status", copy.body),
244
- el("p", "sl-hco-note", copy.detail),
245
- back2
246
- );
247
- mount.root.appendChild(scrim);
248
- back2.focus();
249
- return { destroy };
250
- }
251
- if (mount.state.kind === "resume") {
252
- mount.root.appendChild(scrim);
253
- void awaitConfirmation(mount.state.orderId);
254
- return { destroy };
255
- }
256
- const { order, provider } = mount.state;
257
- const summary = el("div", "sl-hco-summary");
258
- const seats = el("div", "sl-hco-seats");
259
- for (const label of order.labels) seats.appendChild(el("span", "sl-hco-seat", label));
260
- const totalText = formatMoney(order.total, order.currency);
261
- const totalRow = el("div", "sl-hco-total");
262
- totalRow.append(el("span", void 0, "Total"), el("strong", void 0, totalText));
263
- summary.append(seats, totalRow);
264
- const form = el("form", "sl-hco-form");
265
- const emailLabel = el("label", "sl-hco-label", "Email \u2014 your tickets go here");
266
- const email = el("input", "sl-hco-input");
267
- email.type = "email";
268
- email.required = true;
269
- email.autocomplete = "email";
270
- email.placeholder = "you@example.com";
271
- email.id = `${titleId}-email`;
272
- emailLabel.htmlFor = email.id;
273
- const nameLabel = el("label", "sl-hco-label", "Name (optional)");
274
- const name = el("input", "sl-hco-input");
275
- name.type = "text";
276
- name.autocomplete = "name";
277
- name.placeholder = "Your name";
278
- name.id = `${titleId}-name`;
279
- nameLabel.htmlFor = name.id;
280
- const pay = el("button", "sl-hco-pay", `Pay ${totalText}`);
281
- pay.type = "submit";
282
- pay.disabled = true;
283
- const back = el("button", "sl-hco-back", "Back to seats");
284
- back.type = "button";
285
- back.addEventListener("click", cancel);
286
- const until = new Date(order.expiresAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
287
- const note = el(
288
- "p",
289
- "sl-hco-note",
290
- `Your seats are held until ${until}. Payment is handled by ${provider === "razorpay" ? "Razorpay" : "Stripe"} \u2014 we never see your card details.`
291
- );
292
- const privacy = el("p", "sl-hco-note");
293
- privacy.append("The event organizer and SeatLayer use your email to issue and manage your tickets. ");
294
- const privacyLink = el("a", void 0, "Privacy Policy");
295
- privacyLink.href = "https://seatlayer.io/privacy/";
296
- privacyLink.target = "_blank";
297
- privacyLink.rel = "noreferrer";
298
- privacy.appendChild(privacyLink);
299
- const emailValid = () => /.+@.+\..+/.test(email.value.trim());
300
- email.addEventListener("input", () => {
301
- pay.disabled = !emailValid();
302
- });
303
- const start = async () => {
304
- waiting("Opening secure payment\u2026");
305
- try {
306
- const body = await mount.startSession({
307
- holdId: order.holdId,
308
- buyerEmail: email.value.trim(),
309
- // Deliberately no `provider`: since W2 the EVENT row decides which
310
- // gateway charges, and naming one here can only ever 409 on a mismatch
311
- // the buyer cannot do anything about.
312
- ...name.value.trim() ? { buyerName: name.value.trim() } : {}
313
- });
314
- if (!live) return;
315
- if (body.redirectUrl) {
316
- waiting("Taking you to secure payment\u2026");
317
- window.location.assign(body.redirectUrl);
318
- return;
319
- }
320
- if (body.clientPayload) {
321
- const payload = body.clientPayload;
322
- const Razorpay = await loadRazorpay();
323
- if (!live) return;
324
- waiting("Waiting for payment\u2026");
325
- new Razorpay({
326
- key: payload.key,
327
- order_id: payload.orderId,
328
- amount: payload.amount,
329
- currency: payload.currency,
330
- name: payload.name,
331
- prefill: payload.prefill,
332
- // The handler fires on the browser's word alone, so it only starts the
333
- // wait — the webhook is what actually confirms the order.
334
- handler: () => {
335
- void awaitConfirmation(body.orderId);
336
- },
337
- modal: { ondismiss: () => {
338
- if (live) details();
339
- } }
340
- }).open();
341
- return;
342
- }
343
- fail(errorCopy("gateway_unavailable"));
344
- } catch (err) {
345
- mount.onError?.(err);
346
- fail(errorCopy(err?.code));
347
- }
348
- };
349
- form.addEventListener("submit", (event) => {
350
- event.preventDefault();
351
- if (emailValid()) void start();
352
- });
353
- form.append(emailLabel, email, nameLabel, name, privacy, pay, back, note);
354
- const details = () => {
355
- title.textContent = "Checkout";
356
- show(summary, form);
357
- pay.disabled = !emailValid();
358
- };
359
- details();
360
- mount.root.appendChild(scrim);
361
- email.focus();
362
- return { destroy };
363
- }
364
- export {
365
- errorCopy,
366
- formatMoney,
367
- mountCheckout,
368
- unavailableCopy
369
- };
370
- //# sourceMappingURL=hostedCheckout-GVS6UKYA.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hostedCheckout.ts"],"sourcesContent":["/**\n * Hosted checkout — the payment step, as a module nobody downloads until a\n * buyer actually asks to pay.\n *\n * This is the whole of what `checkout: 'hosted'` adds to SeatPicker: a card\n * that collects an email, starts a payment against `POST /pub/events/:key/\n * checkout`, hands off to the gateway, and waits for the webhook to land. It is\n * a straight port of the panel our own buyer page has shipped since hosted\n * checkout existed (`src/pages/CheckoutPanel.tsx`), with React and the app's\n * shared api client taken out.\n *\n * IT IMPORTS NOTHING AT RUNTIME. Not `@seatlayer/core`, not `./api`, not even a\n * type from `./SeatPicker` — every input arrives through {@link CheckoutMount},\n * including the two API calls, which arrive as functions. That is not\n * fastidiousness: this file is built as a standalone CDN asset\n * (`seatlayer-checkout.mjs`), and a single value import from the engine would\n * pull a second copy of it into that asset and undo the point of splitting.\n *\n * Three states, one card, because they are the same moment in the buyer's\n * journey and share every pixel of chrome:\n *\n * pay a live hold — collect an email and START a payment\n * resume back from a hosted gateway page — the hold and its line items\n * are gone with the old document, so this can only WAIT on the\n * order id that survived in the return URL. It must never offer\n * to start a second payment for a purchase that may have already\n * succeeded.\n * unavailable the event cannot take money here, and the buyer is holding\n * seats. Say which of the three reasons it is, because two of\n * them give opposite advice.\n */\n\n/** The gateways `payment-options` can name. */\nexport type CheckoutProviderName = 'stripe' | 'razorpay';\n\n/**\n * Why `payment-options` came back with an empty list. Mirrors the server enum\n * (`workers/api/src/checkout.ts`); see {@link unavailableCopy} for what each one\n * is allowed to say.\n */\nexport type CheckoutUnavailableReason =\n | 'not_configured'\n | 'payments_off_for_event'\n | 'unavailable_for_event';\n\n/** What `POST /pub/events/:key/checkout` returns. Exactly one handoff is set. */\nexport interface CheckoutSessionResult {\n orderId: string;\n totalMinor: number;\n currency: string;\n expiresAt: number;\n /** Hosted gateway page (Stripe) — leave for it. */\n redirectUrl?: string;\n /** In-page modal gateway (Razorpay) — open it here. */\n clientPayload?: Record<string, unknown>;\n}\n\n/** What `GET /pub/orders/:id/status` returns while the webhook is in flight. */\nexport interface CheckoutOrderStatus {\n orderId: string;\n status: string;\n totalMinor: number;\n currency: string;\n amountFormatted: string;\n seatCount: number;\n // Present once the order is settled: the confirmed card names the seats it\n // just sold and points at the hosted ticket page that outlives this modal.\n tickets?: Array<{\n label: string;\n token: string;\n status: 'issued' | 'checked_in' | 'void';\n checkedInAt: number | null;\n }>;\n /** Hosted ticket page — the durable re-entry point after the card closes. */\n ticketUrl?: string;\n /** Printable A4 PDF, up to three ticket cards per page. */\n pdfUrl?: string;\n}\n\n/** The buyer's held order, flattened out of the widget's CheckoutHandoff. */\nexport interface CheckoutOrderSummary {\n holdId: string;\n /** Epoch ms the hold expires — shown so the buyer knows their deadline. */\n expiresAt: number;\n currency: string;\n /** Total in MAJOR units, already carrying any host `pricing` overrides. */\n total: number;\n /** Buyer-facing unit labels (displayLabel where the designer set one). */\n labels: string[];\n}\n\nexport type CheckoutState =\n | { kind: 'pay'; order: CheckoutOrderSummary; provider: CheckoutProviderName | null }\n | { kind: 'resume'; orderId: string }\n | { kind: 'unavailable'; reason: CheckoutUnavailableReason; seatCount: number };\n\nexport interface CheckoutMount {\n /** Where the card mounts — the widget root, so every `--sl-*` token inherits. */\n root: HTMLElement;\n state: CheckoutState;\n /** `POST /pub/events/:key/checkout`, already bound to the event and client. */\n startSession(input: {\n holdId: string; buyerEmail: string; buyerName?: string;\n }): Promise<CheckoutSessionResult>;\n /** `GET /pub/orders/:id/status`. */\n orderStatus(orderId: string): Promise<CheckoutOrderStatus>;\n /** Buyer backed out, or closed a finished card. The hold is NOT touched. */\n onCancel(): void;\n /** The webhook landed and the order is paid. Fires at most once. */\n onConfirmed(order: CheckoutOrderStatus): void;\n /** Anything the buyer was already told about, forwarded to the host. */\n onError?(err: unknown): void;\n}\n\nexport interface CheckoutHandle {\n destroy(): void;\n}\n\n/** How long to wait on the webhook before telling the buyer to watch their email. */\nconst CONFIRM_TIMEOUT_MS = 90_000;\nconst CONFIRM_POLL_MS = 2_000;\nconst RAZORPAY_SCRIPT = 'https://checkout.razorpay.com/v1/checkout.js';\nconst STYLE_ID = 'seatlayer-checkout-style';\n\n/**\n * The card's stylesheet. Every colour, font and radius is a `--sl-*` token the\n * widget root already defines, so an organizer's accent and a host's `theme`\n * overrides reach the payment step without this module knowing either exists.\n *\n * The `@sl-css` marker opts it into build-time minification — see\n * cdn/minifyCssLiterals.ts. Keep writing it long-hand.\n */\nconst CSS = /* @sl-css */ `\n.sl-hco{position:absolute;inset:0;z-index:60;display:flex;align-items:center;justify-content:center;\n padding:16px;background:color-mix(in srgb, var(--sl-bg) 82%, transparent);backdrop-filter:blur(3px)}\n.sl-hco-card{width:100%;max-width:380px;max-height:100%;overflow:auto;padding:22px;\n background:var(--sl-surface);color:var(--sl-text);border:1px solid var(--sl-line);\n border-radius:var(--sl-radius);box-shadow:0 18px 48px rgba(0,0,0,.28)}\n.sl-hco-title{margin:0 0 14px;font-size:19px;font-weight:650;letter-spacing:-.01em}\n.sl-hco-summary{margin-bottom:16px;padding-bottom:14px;border-bottom:1px solid var(--sl-line)}\n.sl-hco-seats{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px}\n.sl-hco-seat{padding:3px 8px;font-size:12px;font-weight:600;border-radius:calc(var(--sl-radius) * .5);\n background:var(--sl-bg);border:1px solid var(--sl-line)}\n.sl-hco-total{display:flex;justify-content:space-between;align-items:baseline;font-size:14px}\n.sl-hco-total strong{font-size:17px;font-weight:700}\n.sl-hco-label{display:block;margin:12px 0 5px;font-size:12px;font-weight:600;color:var(--sl-muted)}\n.sl-hco-input{width:100%;padding:10px 11px;font:inherit;font-size:15px;color:var(--sl-text);\n background:var(--sl-bg);border:1px solid var(--sl-line);border-radius:calc(var(--sl-radius) * .55)}\n.sl-hco-input:focus-visible{outline:2px solid var(--sl-accent);outline-offset:1px}\n.sl-hco-pay{width:100%;margin-top:16px;padding:12px;font:inherit;font-size:15px;font-weight:650;\n color:var(--sl-accent-ink);background:var(--sl-accent);border:0;\n border-radius:calc(var(--sl-radius) * .55);cursor:pointer}\n.sl-hco-pay[disabled]{opacity:.5;cursor:default}\n.sl-hco-back{width:100%;margin-top:8px;padding:10px;font:inherit;font-size:14px;color:var(--sl-muted);\n background:none;border:0;cursor:pointer;text-decoration:underline}\n.sl-hco-note{margin:12px 0 0;font-size:12px;line-height:1.5;color:var(--sl-muted)}\n.sl-hco-note a{color:inherit;text-decoration:underline;text-underline-offset:2px}\n.sl-hco-status{margin:8px 0 0;font-size:14px;line-height:1.55}\n.sl-hco-error{color:var(--sl-danger, #c0392b)}\n.sl-hco-receipt{display:grid;grid-template-columns:auto 1fr;gap:4px 14px;margin:14px 0 0;font-size:13px}\n.sl-hco-receipt dt{color:var(--sl-muted)}\n.sl-hco-receipt dd{margin:0;text-align:right}\n.sl-hco-ref{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;word-break:break-all}\n.sl-hco-tickets{display:block;width:100%;margin-top:14px;padding:12px;font:inherit;font-size:15px;\n font-weight:650;text-align:center;text-decoration:none;color:var(--sl-accent-ink);\n background:var(--sl-accent);border-radius:calc(var(--sl-radius) * .55)}\n`;\n\nfunction ensureStyle(): void {\n if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return;\n const el = document.createElement('style');\n el.id = STYLE_ID;\n el.textContent = CSS;\n document.head.appendChild(el);\n}\n\n/**\n * Money for the buyer's eye. `Intl` is the right answer everywhere it exists;\n * the fallback is a plain amount and a code, which is never wrong — only plain.\n */\nexport function formatMoney(amount: number, currency: string): string {\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(amount);\n } catch {\n return `${amount.toFixed(2)} ${currency}`;\n }\n}\n\n/**\n * What a buyer holding seats is told when the event cannot take their money,\n * and why the three differ. Pure, so the wording is unit-tested rather than\n * eyeballed.\n *\n * not_configured The organizer integrates by API and owns payment.\n * SeatLayer holds the inventory; their host takes the\n * money. Nothing is wrong and the buyer's checkout is\n * somewhere else on this very page.\n * payments_off_for_event The organizer sells other events through us and chose\n * not to sell this one online. NOTHING IS WRONG.\n * Telling this buyer to \"let the organiser know\" would\n * send them to complain about a deliberate decision.\n * unavailable_for_event The organizer switched this event on and it still\n * cannot charge — a test key against a live event, or a\n * gateway disconnected after assignment. Something IS\n * wrong and only they can fix it.\n *\n * None of them names a provider, a mode or an account: the buyer is anonymous\n * and the reason enum is the entire disclosure budget.\n */\nexport function unavailableCopy(reason: CheckoutUnavailableReason, seatCount: number): {\n title: string; body: string; detail: string;\n} {\n const held = `${seatCount} ${seatCount === 1 ? 'seat is' : 'seats are'} held for a limited time.`;\n if (reason === 'payments_off_for_event') {\n return {\n title: 'This event isn’t sold online',\n body: `${held} The organiser isn’t taking payment for this event here.`,\n detail: 'Nothing has been charged. Check where you found this event for how to get tickets.',\n };\n }\n if (reason === 'unavailable_for_event') {\n return {\n title: 'This event isn’t taking payment yet',\n body: `${held} Online payment is not switched on for this event.`,\n detail: 'Nothing has been charged. If you were sent here to pay, let the organiser know — '\n + 'only they can turn payment on for this event.',\n };\n }\n return {\n title: 'Finish in the ticketing checkout',\n body: `${held} Payment for this event is taken elsewhere.`,\n detail: 'Nothing has been charged. Continue in the checkout on this page to pay for your seats.',\n };\n}\n\n/**\n * Buyer-facing text for a server error code.\n *\n * Each one says what happened to their MONEY, because that is the only question\n * a buyer has at this moment. None of these paths can have charged them — the\n * charge does not exist until the gateway page — so every message says so.\n */\nexport function errorCopy(code: string | undefined): string {\n switch (code) {\n case 'gateway_not_connected':\n case 'payments_not_enabled_for_event':\n return 'This event is not taking online payments. Contact the organiser to buy these seats.';\n case 'provider_mismatch':\n // Only reachable if a caller sent a provider of its own. The widget never\n // does — it lets the event row decide — so this is a host integration bug,\n // and the buyer is told the one thing that is true for them.\n return 'This event’s payment setup changed while you were choosing. Nothing was charged — '\n + 'please try again.';\n case 'hold_not_active':\n case 'hold_not_found':\n return 'Your seats were released before checkout started. Nothing was charged — please pick again.';\n case 'checkout_already_started':\n return 'A payment for these seats is already in progress. Finish that one, or wait for it to '\n + 'time out before starting again.';\n case 'event_closed':\n return 'Sales for this event have closed.';\n case 'insufficient_hosted_credits':\n return 'Ticket sales are temporarily paused while the organiser updates their SeatLayer balance. '\n + 'Nothing was charged — please try again later or contact the organiser.';\n case 'gateway_currency_mismatch':\n case 'unsupported_currency':\n case 'mixed_currency_hold':\n case 'price_unusable':\n return 'These seats cannot be checked out right now because of a pricing configuration '\n + 'problem. Nothing was charged — please contact the organiser.';\n case 'rate_limited':\n return 'Too many attempts. Wait a moment and try again.';\n default:\n return 'We could not start the payment. Nothing was charged — please try again.';\n }\n}\n\n/** Razorpay's script attaches this constructor; typed narrowly at the call site. */\ninterface RazorpayCheckout { open(): void }\ntype RazorpayConstructor = new (options: Record<string, unknown>) => RazorpayCheckout;\n\nfunction loadRazorpay(): Promise<RazorpayConstructor> {\n const existing = (window as unknown as { Razorpay?: RazorpayConstructor }).Razorpay;\n if (existing) return Promise.resolve(existing);\n return new Promise((resolve, reject) => {\n // Reuse an in-flight tag if the buyer retries before the first load settles.\n const previous = document.querySelector<HTMLScriptElement>(`script[src=\"${RAZORPAY_SCRIPT}\"]`);\n const tag = previous ?? document.createElement('script');\n const done = (): void => {\n const ctor = (window as unknown as { Razorpay?: RazorpayConstructor }).Razorpay;\n if (ctor) resolve(ctor);\n else reject(new Error('razorpay_unavailable'));\n };\n tag.addEventListener('load', done, { once: true });\n tag.addEventListener('error', () => reject(new Error('razorpay_script_failed')), { once: true });\n if (previous) return;\n tag.src = RAZORPAY_SCRIPT;\n tag.async = true;\n document.head.appendChild(tag);\n });\n}\n\nfunction el<K extends keyof HTMLElementTagNameMap>(\n tag: K, className?: string, text?: string,\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n if (className) node.className = className;\n // textContent, never innerHTML: an event name, a seat label and a server\n // message all reach this card, and none of them is trusted markup.\n if (text !== undefined) node.textContent = text;\n return node;\n}\n\n/**\n * Mount the payment card.\n *\n * Returns a handle rather than a promise: the card outlives the call (the buyer\n * types, pays, waits), and the widget needs a way to tear it down if the host\n * destroys the picker mid-payment.\n */\nexport function mountCheckout(mount: CheckoutMount): CheckoutHandle {\n ensureStyle();\n\n let live = true;\n let confirmed = false;\n const scrim = el('div', 'sl-hco');\n scrim.setAttribute('role', 'dialog');\n scrim.setAttribute('aria-modal', 'true');\n const card = el('div', 'sl-hco-card');\n scrim.appendChild(card);\n\n const destroy = (): void => {\n live = false;\n scrim.remove();\n document.removeEventListener('keydown', onKey, true);\n };\n const cancel = (): void => {\n destroy();\n mount.onCancel();\n };\n function onKey(event: KeyboardEvent): void {\n if (event.key !== 'Escape' || !scrim.isConnected) return;\n // The picker has its own document-level ESC handler for modal mode. Stopping\n // here means one press closes the payment card, not the whole widget with a\n // payment possibly in flight.\n event.stopPropagation();\n event.preventDefault();\n cancel();\n }\n document.addEventListener('keydown', onKey, true);\n\n const title = el('h2', 'sl-hco-title', 'Checkout');\n const titleId = `sl-hco-t-${Math.random().toString(36).slice(2, 8)}`;\n title.id = titleId;\n scrim.setAttribute('aria-labelledby', titleId);\n\n /** Replace everything under the title — each phase owns the card's body. */\n const show = (...nodes: Node[]): void => {\n card.replaceChildren(title, ...nodes);\n };\n\n const fail = (message: string): void => {\n if (!live) return;\n const status = el('p', 'sl-hco-status sl-hco-error', message);\n status.setAttribute('role', 'alert');\n const back = el('button', 'sl-hco-back', 'Back to seats');\n back.type = 'button';\n back.addEventListener('click', cancel);\n show(status, back);\n };\n\n const waiting = (message: string): void => {\n if (!live) return;\n const status = el('p', 'sl-hco-status', message);\n status.setAttribute('role', 'status');\n show(status);\n };\n\n /**\n * Poll the order until the webhook lands.\n *\n * The buyer's browser is never the authority here — it is only waiting for\n * one. On timeout we tell them the truth (payment likely taken, confirmation\n * by email) rather than claiming a failure that did not happen.\n */\n const awaitConfirmation = async (orderId: string): Promise<void> => {\n waiting('Payment received — confirming your seats…');\n const deadline = Date.now() + CONFIRM_TIMEOUT_MS;\n while (live && Date.now() < deadline) {\n try {\n const body = await mount.orderStatus(orderId);\n if (!live) return;\n if (body.status === 'confirmed') {\n confirmed = true;\n title.textContent = 'Your tickets are confirmed';\n const status = el(\n 'p', 'sl-hco-status',\n `${body.seatCount} ${body.seatCount === 1 ? 'seat' : 'seats'} confirmed. `\n + 'Your tickets — with their door QR codes — are in your email.',\n );\n const receipt = el('dl', 'sl-hco-receipt');\n const seatLabels = (body.tickets ?? []).map((t) => t.label);\n if (seatLabels.length) {\n receipt.append(el('dt', undefined, 'Seats'), el('dd', undefined, seatLabels.join(', ')));\n }\n receipt.append(\n el('dt', undefined, 'Paid'),\n el('dd', undefined, `${body.amountFormatted} ${body.currency}`),\n el('dt', undefined, 'Order'),\n el('dd', 'sl-hco-ref', body.orderId),\n );\n const close = el('button', 'sl-hco-back', 'Close');\n close.type = 'button';\n close.addEventListener('click', cancel);\n if (body.ticketUrl) {\n // The durable exit: a hosted page owning the QRs and the PDF, so\n // closing this card is no longer the end of the buyer's artifacts.\n const view = el('a', 'sl-hco-tickets', 'View tickets & QR codes');\n view.href = body.ticketUrl;\n view.target = '_blank';\n view.rel = 'noreferrer';\n show(status, receipt, view, close);\n } else {\n show(status, receipt, close);\n }\n mount.onConfirmed(body);\n return;\n }\n if (body.status === 'failed' || body.status === 'expired') {\n fail(body.status === 'expired'\n ? 'Your seats were released before payment completed. Nothing was charged — please pick again.'\n : 'The payment did not complete. If you were charged, it has been refunded automatically.');\n return;\n }\n } catch {\n // A transient blip while polling is not an answer. Keep waiting.\n }\n await new Promise((resolve) => setTimeout(resolve, CONFIRM_POLL_MS));\n }\n if (!live || confirmed) return;\n // Deliberately not an error: the money may well have gone through and the\n // webhook is just slow. The confirmation email is the durable receipt.\n fail('Still confirming with the payment provider. If your payment went through, your tickets '\n + 'will arrive by email shortly — you do not need to pay again.');\n };\n\n if (mount.state.kind === 'unavailable') {\n const copy = unavailableCopy(mount.state.reason, mount.state.seatCount);\n title.textContent = copy.title;\n const kicker = el('p', 'sl-hco-label', 'Seats held');\n const back = el('button', 'sl-hco-back', 'Back to seat map');\n back.type = 'button';\n back.addEventListener('click', cancel);\n card.replaceChildren(\n kicker, title,\n el('p', 'sl-hco-status', copy.body),\n el('p', 'sl-hco-note', copy.detail),\n back,\n );\n mount.root.appendChild(scrim);\n back.focus();\n return { destroy };\n }\n\n if (mount.state.kind === 'resume') {\n // A fresh document after a hosted gateway page. Everything except the order\n // id died with the old one, so this can only wait.\n mount.root.appendChild(scrim);\n void awaitConfirmation(mount.state.orderId);\n return { destroy };\n }\n\n const { order, provider } = mount.state;\n const summary = el('div', 'sl-hco-summary');\n const seats = el('div', 'sl-hco-seats');\n for (const label of order.labels) seats.appendChild(el('span', 'sl-hco-seat', label));\n const totalText = formatMoney(order.total, order.currency);\n const totalRow = el('div', 'sl-hco-total');\n totalRow.append(el('span', undefined, 'Total'), el('strong', undefined, totalText));\n summary.append(seats, totalRow);\n\n const form = el('form', 'sl-hco-form');\n const emailLabel = el('label', 'sl-hco-label', 'Email — your tickets go here');\n const email = el('input', 'sl-hco-input');\n email.type = 'email';\n email.required = true;\n email.autocomplete = 'email';\n email.placeholder = 'you@example.com';\n email.id = `${titleId}-email`;\n emailLabel.htmlFor = email.id;\n\n const nameLabel = el('label', 'sl-hco-label', 'Name (optional)');\n const name = el('input', 'sl-hco-input');\n name.type = 'text';\n name.autocomplete = 'name';\n name.placeholder = 'Your name';\n name.id = `${titleId}-name`;\n nameLabel.htmlFor = name.id;\n\n const pay = el('button', 'sl-hco-pay', `Pay ${totalText}`);\n pay.type = 'submit';\n pay.disabled = true;\n const back = el('button', 'sl-hco-back', 'Back to seats');\n back.type = 'button';\n back.addEventListener('click', cancel);\n\n const until = new Date(order.expiresAt)\n .toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n const note = el(\n 'p', 'sl-hco-note',\n `Your seats are held until ${until}. Payment is handled by `\n + `${provider === 'razorpay' ? 'Razorpay' : 'Stripe'} — we never see your card details.`,\n );\n const privacy = el('p', 'sl-hco-note');\n privacy.append('The event organizer and SeatLayer use your email to issue and manage your tickets. ');\n const privacyLink = el('a', undefined, 'Privacy Policy');\n privacyLink.href = 'https://seatlayer.io/privacy/';\n privacyLink.target = '_blank';\n privacyLink.rel = 'noreferrer';\n privacy.appendChild(privacyLink);\n\n const emailValid = (): boolean => /.+@.+\\..+/.test(email.value.trim());\n email.addEventListener('input', () => { pay.disabled = !emailValid(); });\n\n const start = async (): Promise<void> => {\n waiting('Opening secure payment…');\n try {\n const body = await mount.startSession({\n holdId: order.holdId,\n buyerEmail: email.value.trim(),\n // Deliberately no `provider`: since W2 the EVENT row decides which\n // gateway charges, and naming one here can only ever 409 on a mismatch\n // the buyer cannot do anything about.\n ...(name.value.trim() ? { buyerName: name.value.trim() } : {}),\n });\n if (!live) return;\n\n // Hosted-page provider: leave the page. Where the gateway sends the buyer\n // back is the SERVER's choice, not ours — see the `checkout` option's note\n // in SeatPicker.\n if (body.redirectUrl) {\n waiting('Taking you to secure payment…');\n window.location.assign(body.redirectUrl);\n return;\n }\n\n // In-page modal provider — the embed never leaves the host's page.\n if (body.clientPayload) {\n const payload = body.clientPayload as {\n key: string; orderId: string; amount: number; currency: string;\n name: string; prefill?: { email?: string; name?: string };\n };\n const Razorpay = await loadRazorpay();\n if (!live) return;\n waiting('Waiting for payment…');\n new Razorpay({\n key: payload.key,\n order_id: payload.orderId,\n amount: payload.amount,\n currency: payload.currency,\n name: payload.name,\n prefill: payload.prefill,\n // The handler fires on the browser's word alone, so it only starts the\n // wait — the webhook is what actually confirms the order.\n handler: () => { void awaitConfirmation(body.orderId); },\n modal: { ondismiss: () => { if (live) details(); } },\n }).open();\n return;\n }\n\n fail(errorCopy('gateway_unavailable'));\n } catch (err) {\n mount.onError?.(err);\n fail(errorCopy((err as { code?: string } | null)?.code));\n }\n };\n\n form.addEventListener('submit', (event) => {\n event.preventDefault();\n if (emailValid()) void start();\n });\n form.append(emailLabel, email, nameLabel, name, privacy, pay, back, note);\n\n const details = (): void => {\n title.textContent = 'Checkout';\n show(summary, form);\n pay.disabled = !emailValid();\n };\n details();\n mount.root.appendChild(scrim);\n email.focus();\n\n return { destroy };\n}\n"],"mappings":"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","names":["el","back"]}