@funnelsgrove/payments 0.26.0 → 0.28.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.
package/README.md CHANGED
@@ -181,6 +181,7 @@ conversion event is introduced.
181
181
  - Do not call `publicAnalyticsSdk.trackCheckoutStarted`, `trackPaymentInfoSubmitted`, or `trackCheckoutCompleted` directly from funnel checkout components.
182
182
  - Funnel paywalls should style wallet buttons through the shared slot API: `className` for the Stripe button/placeholder, `slotClassName` for the outer slot, `appearance` for Stripe Elements appearance, and `options` for Stripe Express Checkout options.
183
183
  - Keep discount math reusable here, but keep offer activation timing in funnel code.
184
+ - `SharedStripeCheckoutV2Dialog` forwards wallet-sheet cancellation to `onClose` by default; `onWalletCancel` may override that callback. Standalone wallet surfaces call their `onCancel` callback. Funnel code chooses whether either callback opens a discount offer.
184
185
  - Checkout metadata must avoid sensitive raw query params and use `@funnelsgrove/analytics` metadata helpers.
185
186
 
186
187
  ## Build, Test, Publish
@@ -1 +1 @@
1
- export declare const PAYMENTS_PACKAGE_VERSION = "0.26.0";
1
+ export declare const PAYMENTS_PACKAGE_VERSION = "0.28.0";
@@ -1,2 +1,2 @@
1
1
  // Generated by scripts/generate-package-version.mjs.
2
- export const PAYMENTS_PACKAGE_VERSION = "0.26.0";
2
+ export const PAYMENTS_PACKAGE_VERSION = "0.28.0";
@@ -1,3 +1,3 @@
1
1
  import type { SolidgateCheckoutDialogProps } from './SolidgateCheckoutDialog.types.js';
2
2
  export type { SolidgateCheckoutDialogState, SolidgateCheckoutDialogContent, SolidgateCheckoutDialogPresentation, SolidgateCheckoutDialogProps, SolidgateCheckoutAnalyticsContext, } from './SolidgateCheckoutDialog.types.js';
3
- export declare function SolidgateCheckoutDialog({ open, request, customerEmail, checkoutAnalytics, content, presentation, onClose, onCustomerEmailCommit, onSuccess, onRetry, onError, onPreparationStart, onStateChange, }: SolidgateCheckoutDialogProps): import("react/jsx-runtime").JSX.Element | null;
3
+ export declare function SolidgateCheckoutDialog({ open, layout, request, customerEmail, checkoutAnalytics, content, presentation, onClose, onCustomerEmailCommit, onSuccess, onRetry, onError, onPreparationStart, onStateChange, onPaymentPendingChange, }: SolidgateCheckoutDialogProps): import("react/jsx-runtime").JSX.Element | null;
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { completePaywallCheckout } from '@funnelsgrove/runtime';
4
4
  import { publicAnalyticsSdk } from '@funnelsgrove/analytics';
5
5
  import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
@@ -65,7 +65,7 @@ const trackSolidgateCheckoutEvent = async (eventName, attemptId, context) => {
65
65
  }
66
66
  };
67
67
  const isAbortError = (error) => (error instanceof DOMException && error.name === 'AbortError');
68
- export function SolidgateCheckoutDialog({ open, request, customerEmail, checkoutAnalytics, content, presentation, onClose, onCustomerEmailCommit, onSuccess, onRetry, onError, onPreparationStart, onStateChange, }) {
68
+ export function SolidgateCheckoutDialog({ open, layout = 'dialog', request, customerEmail, checkoutAnalytics, content, presentation, onClose, onCustomerEmailCommit, onSuccess, onRetry, onError, onPreparationStart, onStateChange, onPaymentPendingChange, }) {
69
69
  const copy = useMemo(() => (Object.assign(Object.assign({}, defaultContent), content)), [content]);
70
70
  const [view, setView] = useState(initialView);
71
71
  const [retryRequest, setRetryRequest] = useState(null);
@@ -85,6 +85,7 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
85
85
  const copyRef = useRef(copy);
86
86
  const onCloseRef = useRef(onClose);
87
87
  const onErrorRef = useRef(onError);
88
+ const onPaymentPendingChangeRef = useRef(onPaymentPendingChange);
88
89
  const onStateChangeRef = useRef(onStateChange);
89
90
  const onSuccessRef = useRef(onSuccess);
90
91
  useEffect(() => {
@@ -93,8 +94,9 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
93
94
  onCloseRef.current = onClose;
94
95
  onErrorRef.current = onError;
95
96
  onStateChangeRef.current = onStateChange;
97
+ onPaymentPendingChangeRef.current = onPaymentPendingChange;
96
98
  onSuccessRef.current = onSuccess;
97
- }, [checkoutAnalytics, copy, onClose, onError, onStateChange, onSuccess]);
99
+ }, [checkoutAnalytics, copy, onClose, onError, onStateChange, onSuccess, onPaymentPendingChange]);
98
100
  useEffect(() => {
99
101
  setEmailInput((customerEmail === null || customerEmail === void 0 ? void 0 : customerEmail.trim()) || '');
100
102
  setCommittedEmail(normalizedCustomerEmail);
@@ -150,9 +152,11 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
150
152
  const latestRequestRef = useRef(normalizedRequest);
151
153
  latestRequestRef.current = normalizedRequest;
152
154
  const setState = useCallback((nextView) => {
153
- var _a;
155
+ var _a, _b;
154
156
  setView(nextView);
155
157
  (_a = onStateChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onStateChangeRef, nextView.state);
158
+ (_b = onPaymentPendingChangeRef.current) === null || _b === void 0 ? void 0 : _b.call(onPaymentPendingChangeRef, nextView.state === 'submitting'
159
+ || nextView.state === 'verifying' || nextView.state === 'success' || nextView.canResumeVerification);
156
160
  }, []);
157
161
  const trackFailure = useCallback((message, failureStage, attemptId) => {
158
162
  const analytics = checkoutAnalyticsRef.current;
@@ -169,9 +173,11 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
169
173
  });
170
174
  }, []);
171
175
  const requiresEmailCommit = Boolean(onCustomerEmailCommit);
176
+ const startedAttemptRef = useRef(null);
177
+ const active = open && (layout !== 'wallet' || Boolean(normalizedCustomerEmail));
172
178
  useEffect(() => {
173
179
  var _a, _b, _c, _d, _e, _f, _g;
174
- if (!open) {
180
+ if (!active) {
175
181
  preparedRequestRef.current = null;
176
182
  (_a = prepareAbortRef.current) === null || _a === void 0 ? void 0 : _a.abort();
177
183
  (_b = statusAbortRef.current) === null || _b === void 0 ? void 0 : _b.abort();
@@ -205,7 +211,9 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
205
211
  .then((checkout) => {
206
212
  if (!controller.signal.aborted) {
207
213
  setState({ state: 'ready', checkout, canResumeVerification: false });
208
- void trackSolidgateCheckoutEvent('checkout_started', checkout.attemptId, checkoutAnalyticsRef.current);
214
+ if (layout !== 'wallet') {
215
+ void trackSolidgateCheckoutEvent('checkout_started', checkout.attemptId, checkoutAnalyticsRef.current);
216
+ }
209
217
  }
210
218
  })
211
219
  .catch((error) => {
@@ -217,13 +225,13 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
217
225
  }
218
226
  });
219
227
  return () => controller.abort();
220
- }, [checkoutKey, committedEmail, onPreparationStart, open, requiresEmailCommit, setState, trackFailure]);
228
+ }, [checkoutKey, committedEmail, layout, onPreparationStart, active, requiresEmailCommit, setState, trackFailure]);
221
229
  const paymentFormMounted = Boolean(view.checkout && mountedPaymentAttemptId === view.checkout.attemptId);
222
230
  const showPreparingLoader = view.state === 'loading'
223
231
  || (view.state === 'ready' && !paymentFormMounted);
224
232
  useEffect(() => {
225
233
  var _a;
226
- if (!open) {
234
+ if (!open || layout === 'wallet') {
227
235
  return;
228
236
  }
229
237
  const previouslyFocused = document.activeElement instanceof HTMLElement
@@ -253,7 +261,7 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
253
261
  window.removeEventListener('keydown', handleKeyDown);
254
262
  previouslyFocused === null || previouslyFocused === void 0 ? void 0 : previouslyFocused.focus();
255
263
  };
256
- }, [open, showPreparingLoader, view.checkout]);
264
+ }, [layout, open, showPreparingLoader, view.checkout]);
257
265
  useEffect(() => () => {
258
266
  var _a, _b;
259
267
  (_a = prepareAbortRef.current) === null || _a === void 0 ? void 0 : _a.abort();
@@ -356,7 +364,7 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
356
364
  }
357
365
  onCloseRef.current();
358
366
  };
359
- if (!open) {
367
+ if (!active) {
360
368
  return null;
361
369
  }
362
370
  const showForm = view.state === 'ready'
@@ -379,6 +387,40 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
379
387
  '--solidgate-checkout-theme-color': presentation.themeColor,
380
388
  }
381
389
  : undefined;
390
+ const recoveryActions = (_jsxs(_Fragment, { children: [view.canResumeVerification ? (_jsx("button", { type: 'button', onClick: () => void verifyCanonicalStatus(), className: 'solidgate-checkout-action solidgate-checkout-action--spaced', children: copy.resumeVerification })) : null, (view.state === 'recoverable_error' || view.state === 'expired') && !view.canResumeVerification ? (_jsx("button", { type: 'button', onClick: onRetry || (() => {
391
+ preparedRequestRef.current = null;
392
+ setRetryRequest({
393
+ originalKey: idempotencyKey,
394
+ key: crypto.randomUUID(),
395
+ });
396
+ }), className: 'solidgate-checkout-action solidgate-checkout-action--spaced', children: copy.retry })) : null] }));
397
+ const paymentForm = view.checkout ? (_jsx(SolidgatePaymentForm, { walletOnly: layout === 'wallet', secureLabel: presentation === null || presentation === void 0 ? void 0 : presentation.secureLabel, cardLabel: presentation === null || presentation === void 0 ? void 0 : presentation.cardLabel, paymentMethodLabel: presentation === null || presentation === void 0 ? void 0 : presentation.paymentMethodLabel, buttonColor: (presentation === null || presentation === void 0 ? void 0 : presentation.buttonColor) || '#3f51b5', cardSubmitLabel: (presentation === null || presentation === void 0 ? void 0 : presentation.cardSubmitLabel) || 'Pay securely', checkout: view.checkout, hidden: !showForm, loadingLabel: copy.loading, onMounted: () => {
398
+ var _a;
399
+ setMountedPaymentAttemptId(((_a = view.checkout) === null || _a === void 0 ? void 0 : _a.attemptId) || null);
400
+ }, onSubmit: () => {
401
+ var _a, _b, _c;
402
+ if (paymentInfoAttemptRef.current !== ((_a = view.checkout) === null || _a === void 0 ? void 0 : _a.attemptId)) {
403
+ paymentInfoAttemptRef.current = ((_b = view.checkout) === null || _b === void 0 ? void 0 : _b.attemptId) || null;
404
+ void trackSolidgateCheckoutEvent('add_payment_info', ((_c = view.checkout) === null || _c === void 0 ? void 0 : _c.attemptId) || '', checkoutAnalyticsRef.current);
405
+ }
406
+ setState(Object.assign(Object.assign({}, view), { state: 'submitting' }));
407
+ }, onVerify: () => void verifyCanonicalStatus(), onError: () => {
408
+ var _a, _b;
409
+ setState(Object.assign(Object.assign({}, view), { state: 'recoverable_error', canResumeVerification: false }));
410
+ trackFailure(copyRef.current.error, 'payment_form', (_a = view.checkout) === null || _a === void 0 ? void 0 : _a.attemptId);
411
+ (_b = onErrorRef.current) === null || _b === void 0 ? void 0 : _b.call(onErrorRef, copyRef.current.error);
412
+ } }, view.checkout.attemptId)) : null;
413
+ if (layout === 'wallet') {
414
+ return (_jsxs("div", { className: 'solidgate-inline-wallet', onClick: (event) => {
415
+ var _a;
416
+ const attemptId = (_a = view.checkout) === null || _a === void 0 ? void 0 : _a.attemptId;
417
+ if (attemptId && startedAttemptRef.current !== attemptId
418
+ && event.target instanceof Element && event.target.closest('[data-solidgate-wallet]')) {
419
+ startedAttemptRef.current = attemptId;
420
+ void trackSolidgateCheckoutEvent('checkout_started', attemptId, checkoutAnalyticsRef.current);
421
+ }
422
+ }, children: [paymentForm, statusMessage && !showPreparingLoader ? _jsx("p", { role: 'status', children: statusMessage }) : null, recoveryActions, _jsx("style", { children: solidgateCheckoutDialogStyles })] }));
423
+ }
382
424
  return (_jsxs(_Fragment, { children: [_jsxs("div", { className: `solidgate-checkout-overlay${presentation ? ' is-branded' : ''}`, style: presentationStyle, children: [showPreparingLoader ? (_jsxs("div", { className: 'solidgate-checkout-loader', role: 'status', "aria-live": 'polite', children: [_jsx("span", { className: 'solidgate-checkout-spinner', "aria-hidden": 'true' }), _jsx("span", { className: 'solidgate-checkout-visually-hidden', children: copy.loading })] })) : null, view.state !== 'loading' || view.checkout ? (_jsxs("div", { role: 'dialog', "aria-modal": 'true', "aria-hidden": showPreparingLoader || undefined, "aria-labelledby": 'solidgate-checkout-title', "data-checkout-state": view.state, className: [
383
425
  'solidgate-checkout-dialog',
384
426
  showPreparingLoader ? 'is-preparing' : '',
@@ -386,26 +428,5 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
386
428
  ].filter(Boolean).join(' '), children: [_jsxs("div", { className: 'solidgate-checkout-header', children: [_jsx("button", { ref: closeButtonRef, type: 'button', onClick: handleClose, "aria-label": copy.closeAriaLabel, className: 'solidgate-checkout-close', children: _jsx("span", { "aria-hidden": 'true' }) }), _jsx("h2", { id: 'solidgate-checkout-title', className: 'solidgate-checkout-title', children: (presentation === null || presentation === void 0 ? void 0 : presentation.title) || copy.title })] }), presentation ? _jsx(SolidgateCheckoutSummary, { presentation: presentation }) : null, view.state === 'collecting_email' ? (_jsxs("form", { className: 'solidgate-checkout-email-form', onSubmit: (event) => void commitCustomerEmail(event), children: [_jsxs("label", { className: 'solidgate-checkout-email-label', children: [copy.customerEmailLabel, _jsx("input", { type: 'email', autoComplete: 'email', inputMode: 'email', maxLength: 320, required: true, value: emailInput, onChange: (event) => {
387
429
  setEmailInput(event.target.value);
388
430
  setEmailError(null);
389
- }, placeholder: copy.customerEmailPlaceholder, "aria-invalid": Boolean(emailError), className: 'solidgate-checkout-email-input' })] }), emailError ? (_jsx("p", { role: 'alert', className: 'solidgate-checkout-alert', children: emailError })) : null, _jsx("button", { type: 'submit', disabled: emailSubmitting, className: 'solidgate-checkout-action', children: copy.customerEmailContinue })] })) : null, view.checkout ? (_jsx(SolidgatePaymentForm, { buttonColor: (presentation === null || presentation === void 0 ? void 0 : presentation.buttonColor) || '#3f51b5', cardSubmitLabel: (presentation === null || presentation === void 0 ? void 0 : presentation.cardSubmitLabel) || 'Pay securely', checkout: view.checkout, hidden: !showForm, loadingLabel: copy.loading, onMounted: () => {
390
- var _a;
391
- setMountedPaymentAttemptId(((_a = view.checkout) === null || _a === void 0 ? void 0 : _a.attemptId) || null);
392
- }, onSubmit: () => {
393
- var _a, _b, _c;
394
- if (paymentInfoAttemptRef.current !== ((_a = view.checkout) === null || _a === void 0 ? void 0 : _a.attemptId)) {
395
- paymentInfoAttemptRef.current = ((_b = view.checkout) === null || _b === void 0 ? void 0 : _b.attemptId) || null;
396
- void trackSolidgateCheckoutEvent('add_payment_info', ((_c = view.checkout) === null || _c === void 0 ? void 0 : _c.attemptId) || '', checkoutAnalyticsRef.current);
397
- }
398
- setState(Object.assign(Object.assign({}, view), { state: 'submitting' }));
399
- }, onVerify: () => void verifyCanonicalStatus(), onError: () => {
400
- var _a, _b;
401
- setState(Object.assign(Object.assign({}, view), { state: 'recoverable_error', canResumeVerification: false }));
402
- trackFailure(copyRef.current.error, 'payment_form', (_a = view.checkout) === null || _a === void 0 ? void 0 : _a.attemptId);
403
- (_b = onErrorRef.current) === null || _b === void 0 ? void 0 : _b.call(onErrorRef, copyRef.current.error);
404
- } }, view.checkout.attemptId)) : null, presentation && view.checkout && showForm ? (_jsx("p", { className: 'solidgate-checkout-secure', children: presentation.secureLabel })) : null, statusMessage && view.state !== 'ready' ? (_jsx("div", { className: 'solidgate-checkout-status', children: _jsx("p", { role: 'status', "aria-live": 'polite', children: statusMessage }) })) : null, view.canResumeVerification ? (_jsx("button", { type: 'button', onClick: () => void verifyCanonicalStatus(), className: 'solidgate-checkout-action solidgate-checkout-action--spaced', children: copy.resumeVerification })) : null, (view.state === 'recoverable_error' || view.state === 'expired') && !view.canResumeVerification ? (_jsx("button", { type: 'button', onClick: onRetry || (() => {
405
- preparedRequestRef.current = null;
406
- setRetryRequest({
407
- originalKey: idempotencyKey,
408
- key: crypto.randomUUID(),
409
- });
410
- }), className: 'solidgate-checkout-action solidgate-checkout-action--spaced', children: copy.retry })) : null] })) : null] }), _jsx("style", { children: solidgateCheckoutDialogStyles })] }));
431
+ }, placeholder: copy.customerEmailPlaceholder, "aria-invalid": Boolean(emailError), className: 'solidgate-checkout-email-input' })] }), emailError ? (_jsx("p", { role: 'alert', className: 'solidgate-checkout-alert', children: emailError })) : null, _jsx("button", { type: 'submit', disabled: emailSubmitting, className: 'solidgate-checkout-action', children: copy.customerEmailContinue })] })) : null, paymentForm, statusMessage && view.state !== 'ready' ? (_jsx("div", { className: 'solidgate-checkout-status', children: _jsx("p", { role: 'status', "aria-live": 'polite', children: statusMessage }) })) : null, recoveryActions] })) : null] }), _jsx("style", { children: solidgateCheckoutDialogStyles })] }));
411
432
  }
@@ -1 +1 @@
1
- export declare const solidgateCheckoutDialogStyles = "\n.solidgate-checkout-overlay {\n position: fixed;\n inset: 0;\n z-index: 100;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n padding: 16px;\n background: rgb(17 24 39 / 60%);\n backdrop-filter: blur(4px);\n}\n\n.solidgate-checkout-overlay.is-branded {\n z-index: 110;\n align-items: stretch;\n padding: 0;\n background: #fff;\n backdrop-filter: none;\n}\n\n.solidgate-checkout-dialog {\n box-sizing: border-box;\n width: min(100%, 512px);\n max-height: calc(100svh - 32px);\n overflow-y: auto;\n border: 1px solid var(--color-border, #d1d5db);\n border-radius: 16px;\n background: var(--color-surface, #fff);\n padding: 20px;\n color: var(--color-text, #111827);\n box-shadow: 0 24px 80px rgb(17 24 39 / 22%);\n}\n\n.solidgate-checkout-dialog.is-branded {\n width: min(100%, 430px);\n height: 100svh;\n max-height: 100svh;\n border: 0;\n border-radius: 0;\n background: #fff;\n padding: 0 17px 28px;\n color: #303136;\n box-shadow: none;\n font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n\n.solidgate-checkout-dialog.is-preparing {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n}\n\n.solidgate-checkout-loader {\n display: grid;\n place-items: center;\n}\n\n.solidgate-checkout-spinner {\n box-sizing: border-box;\n width: 44px;\n height: 44px;\n border: 4px solid var(--color-border, #d1d5db);\n border-top-color: var(--color-primary, #22c55e);\n border-radius: 50%;\n animation: solidgate-checkout-spin 720ms linear infinite;\n}\n\n.solidgate-checkout-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n@keyframes solidgate-checkout-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .solidgate-checkout-spinner {\n animation-duration: 1.6s;\n }\n}\n\n.solidgate-checkout-header {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 16px;\n margin-bottom: 16px;\n}\n\n.solidgate-checkout-dialog.is-branded .solidgate-checkout-header {\n min-height: 70px;\n margin: 0 -17px;\n padding: 0 56px;\n}\n\n.solidgate-checkout-title {\n margin: 0;\n color: var(--color-text, #111827);\n font-size: 18px;\n font-weight: 600;\n line-height: 1.3;\n}\n\n.solidgate-checkout-dialog.is-branded .solidgate-checkout-title {\n color: #020203;\n font-size: 24px;\n font-weight: 900;\n line-height: 1.15;\n text-align: center;\n}\n\n.solidgate-checkout-close {\n position: absolute;\n left: 0;\n top: 50%;\n width: 36px;\n height: 36px;\n flex: none;\n border: 1px solid var(--color-border, #d1d5db);\n border-radius: 8px;\n background: var(--color-bg, #f9fafb);\n color: var(--color-text, #111827);\n font-size: 22px;\n transform: translateY(-50%);\n cursor: pointer;\n}\n\n.solidgate-checkout-dialog.is-branded .solidgate-checkout-close {\n left: 16px;\n width: 40px;\n height: 40px;\n border: 0;\n border-radius: 999px;\n background: #f2f2f3;\n color: #aaa;\n}\n\n.solidgate-checkout-close span,\n.solidgate-checkout-close span::after {\n position: absolute;\n left: 50%;\n top: 50%;\n width: 22px;\n height: 3px;\n border-radius: 999px;\n background: currentColor;\n content: '';\n}\n\n.solidgate-checkout-close span {\n transform: translate(-50%, -50%) rotate(45deg);\n}\n\n.solidgate-checkout-close span::after {\n transform: translate(-50%, -50%) rotate(90deg);\n}\n\n.solidgate-checkout-close:hover {\n background: var(--color-accent-soft, #eef2ff);\n}\n\n.solidgate-checkout-summary {\n color: #303136;\n}\n\n.solidgate-checkout-countdown {\n min-height: 37px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0;\n border-radius: 12px;\n background: color-mix(in srgb, var(--solidgate-checkout-theme-color) 10%, #fff);\n color: var(--solidgate-checkout-theme-color);\n font-size: 16px;\n font-weight: 900;\n text-align: center;\n}\n\n.solidgate-checkout-satisfaction {\n margin: 17px 0 21px;\n color: #2f3034;\n font-size: 19px;\n font-weight: 800;\n line-height: 1.15;\n text-align: center;\n}\n\n.solidgate-checkout-satisfaction strong {\n color: var(--solidgate-checkout-theme-color);\n}\n\n.solidgate-checkout-price-stack {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.solidgate-checkout-price-row,\n.solidgate-checkout-promo,\n.solidgate-checkout-total {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.solidgate-checkout-price-row {\n font-size: 17px;\n}\n\n.solidgate-checkout-price-row.is-muted {\n color: #9d9d9f;\n font-weight: 500;\n}\n\n.solidgate-checkout-strike {\n text-decoration: line-through 2px;\n}\n\n.solidgate-checkout-price-row.is-discount {\n color: #040508;\n font-weight: 900;\n}\n\n.solidgate-checkout-price-row.is-discount strong:last-child {\n color: #ff2544;\n}\n\n.solidgate-checkout-promo {\n min-height: 42px;\n border-radius: 13px;\n background: #f0f0f0;\n padding: 0 14px;\n color: #8d8d90;\n font-size: 16px;\n}\n\n.solidgate-checkout-promo strong {\n color: #050609;\n font-weight: 900;\n}\n\n.solidgate-checkout-total {\n min-height: 76px;\n margin-top: 20px;\n border-top: 1px solid #dedede;\n font-size: 23px;\n font-weight: 800;\n}\n\n.solidgate-checkout-total.is-plain {\n margin-top: 0;\n}\n\n.solidgate-checkout-total strong {\n font-size: 25px;\n font-weight: 900;\n}\n\n.solidgate-checkout-saved {\n width: fit-content;\n min-height: 36px;\n display: flex;\n align-items: center;\n gap: 7px;\n margin: 0 auto 12px;\n border-radius: 999px;\n background: #fff3cf;\n padding: 0 13px;\n color: #2e3034;\n font-size: 14px;\n font-weight: 800;\n}\n\n.solidgate-checkout-email-form,\n.solidgate-checkout-email-label,\n.solidgate-checkout-wallets {\n display: grid;\n}\n\n.solidgate-checkout-email-form {\n gap: 16px;\n}\n\n.solidgate-checkout-email-label {\n gap: 8px;\n color: var(--color-text, #111827);\n font-size: 14px;\n font-weight: 500;\n}\n\n.solidgate-checkout-email-input {\n box-sizing: border-box;\n width: 100%;\n min-height: 44px;\n border: 1px solid var(--color-border, #d1d5db);\n border-radius: 8px;\n background: var(--color-bg, #fff);\n padding: 8px 12px;\n color: var(--color-text, #111827);\n font: inherit;\n}\n\n.solidgate-checkout-email-input::placeholder,\n.solidgate-checkout-status,\n.solidgate-checkout-status-text {\n color: var(--color-text-muted, #6b7280);\n}\n\n.solidgate-checkout-email-input:focus-visible,\n.solidgate-checkout-close:focus-visible,\n.solidgate-checkout-action:focus-visible {\n outline: 2px solid var(--color-accent, #3f51b5);\n outline-offset: 2px;\n}\n\n.solidgate-checkout-alert {\n margin: 0;\n color: var(--color-danger, #b91c1c);\n font-size: 14px;\n}\n\n.solidgate-checkout-action {\n box-sizing: border-box;\n width: 100%;\n min-height: 44px;\n border: 1px solid var(--color-accent, #3f51b5);\n border-radius: 8px;\n background: var(--color-accent, #3f51b5);\n padding: 8px 16px;\n color: var(--color-primary-text, #fff);\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n\n.solidgate-checkout-action:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.solidgate-checkout-action--spaced {\n margin-top: 16px;\n}\n\n.solidgate-checkout-wallets {\n gap: 12px;\n margin-bottom: 12px;\n}\n\n.solidgate-checkout-dialog.is-branded .solidgate-checkout-wallets {\n margin-top: 4px;\n}\n\n.solidgate-checkout-dialog.is-branded .solidgate-checkout-wallets > div:not(:empty) {\n min-height: 48px;\n}\n\n.solidgate-checkout-secure {\n width: fit-content;\n margin: 14px auto 0;\n border-radius: 999px;\n background: #edfff4;\n padding: 8px 14px;\n color: #2b2d31;\n font-size: 13px;\n font-weight: 700;\n}\n\n.solidgate-checkout-payment[hidden] {\n display: none;\n}\n\n.solidgate-checkout-status {\n margin-top: 12px;\n border: 1px solid var(--color-border, #d1d5db);\n border-radius: 12px;\n background: var(--color-bg, #f9fafb);\n padding: 16px;\n font-size: 14px;\n}\n\n.solidgate-checkout-status p,\n.solidgate-checkout-status-text {\n margin: 0;\n}\n";
1
+ export declare const solidgateCheckoutDialogStyles = "\n.solidgate-checkout-overlay {\n position: fixed;\n inset: 0;\n z-index: 100;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n padding: 16px;\n background: rgb(17 24 39 / 60%);\n backdrop-filter: blur(4px);\n}\n\n.solidgate-checkout-overlay.is-branded {\n z-index: 110;\n align-items: stretch;\n padding: 0;\n background: #fff;\n backdrop-filter: none;\n}\n\n.solidgate-checkout-dialog {\n box-sizing: border-box;\n width: min(100%, 512px);\n max-height: calc(100svh - 32px);\n overflow-y: auto;\n border: 1px solid var(--color-border, #d1d5db);\n border-radius: 16px;\n background: var(--color-surface, #fff);\n padding: 20px;\n color: var(--color-text, #111827);\n box-shadow: 0 24px 80px rgb(17 24 39 / 22%);\n}\n\n.solidgate-checkout-dialog.is-branded {\n width: min(100%, 430px);\n height: 100svh;\n max-height: 100svh;\n border: 0;\n border-radius: 0;\n background: #fff;\n padding: 0 17px 28px;\n color: #303136;\n box-shadow: none;\n font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n\n.solidgate-checkout-dialog.is-preparing {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n}\n\n.solidgate-checkout-loader {\n display: grid;\n place-items: center;\n}\n\n.solidgate-checkout-spinner {\n box-sizing: border-box;\n width: 44px;\n height: 44px;\n border: 4px solid var(--color-border, #d1d5db);\n border-top-color: var(--color-primary, #22c55e);\n border-radius: 50%;\n animation: solidgate-checkout-spin 720ms linear infinite;\n}\n\n.solidgate-checkout-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n@keyframes solidgate-checkout-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .solidgate-checkout-spinner {\n animation-duration: 1.6s;\n }\n}\n\n.solidgate-checkout-header {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 16px;\n margin-bottom: 16px;\n}\n\n.solidgate-checkout-dialog.is-branded .solidgate-checkout-header {\n min-height: 70px;\n margin: 0 -17px;\n padding: 0 56px;\n}\n\n.solidgate-checkout-title {\n margin: 0;\n color: var(--color-text, #111827);\n font-size: 18px;\n font-weight: 600;\n line-height: 1.3;\n}\n\n.solidgate-checkout-dialog.is-branded .solidgate-checkout-title {\n color: #020203;\n font-size: 24px;\n font-weight: 900;\n line-height: 1.15;\n text-align: center;\n}\n\n.solidgate-checkout-close {\n position: absolute;\n left: 0;\n top: 50%;\n width: 36px;\n height: 36px;\n flex: none;\n border: 1px solid var(--color-border, #d1d5db);\n border-radius: 8px;\n background: var(--color-bg, #f9fafb);\n color: var(--color-text, #111827);\n font-size: 22px;\n transform: translateY(-50%);\n cursor: pointer;\n}\n\n.solidgate-checkout-dialog.is-branded .solidgate-checkout-close {\n left: 16px;\n width: 40px;\n height: 40px;\n border: 0;\n border-radius: 999px;\n background: #f2f2f3;\n color: #aaa;\n}\n\n.solidgate-checkout-close span,\n.solidgate-checkout-close span::after {\n position: absolute;\n left: 50%;\n top: 50%;\n width: 22px;\n height: 3px;\n border-radius: 999px;\n background: currentColor;\n content: '';\n}\n\n.solidgate-checkout-close span {\n transform: translate(-50%, -50%) rotate(45deg);\n}\n\n.solidgate-checkout-close span::after {\n transform: translate(-50%, -50%) rotate(90deg);\n}\n\n.solidgate-checkout-close:hover {\n background: var(--color-accent-soft, #eef2ff);\n}\n\n.solidgate-checkout-summary {\n color: #303136;\n}\n\n.solidgate-checkout-countdown {\n min-height: 37px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0;\n border-radius: 12px;\n background: color-mix(in srgb, var(--solidgate-checkout-theme-color) 10%, #fff);\n color: var(--solidgate-checkout-theme-color);\n font-size: 16px;\n font-weight: 900;\n text-align: center;\n}\n\n.solidgate-checkout-satisfaction {\n margin: 17px 0 21px;\n color: #2f3034;\n font-size: 19px;\n font-weight: 800;\n line-height: 1.15;\n text-align: center;\n}\n\n.solidgate-checkout-satisfaction strong {\n color: var(--solidgate-checkout-theme-color);\n}\n\n.solidgate-checkout-price-stack {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.solidgate-checkout-price-row,\n.solidgate-checkout-promo,\n.solidgate-checkout-total {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.solidgate-checkout-price-row {\n font-size: 17px;\n}\n\n.solidgate-checkout-price-row.is-muted {\n color: #9d9d9f;\n font-weight: 500;\n}\n\n.solidgate-checkout-strike {\n text-decoration: line-through 2px;\n}\n\n.solidgate-checkout-price-row.is-discount {\n color: #040508;\n font-weight: 900;\n}\n\n.solidgate-checkout-price-row.is-discount strong:last-child {\n color: #ff2544;\n}\n\n.solidgate-checkout-promo {\n min-height: 42px;\n border-radius: 13px;\n background: #f0f0f0;\n padding: 0 14px;\n color: #8d8d90;\n font-size: 16px;\n}\n\n.solidgate-checkout-promo strong {\n color: #050609;\n font-weight: 900;\n}\n\n.solidgate-checkout-total {\n min-height: 76px;\n margin-top: 20px;\n border-top: 1px solid #dedede;\n font-size: 23px;\n font-weight: 800;\n}\n\n.solidgate-checkout-total.is-plain {\n margin-top: 0;\n}\n\n.solidgate-checkout-total strong {\n font-size: 25px;\n font-weight: 900;\n}\n\n.solidgate-checkout-total strong {\n display: inline-flex;\n align-items: center;\n gap: 7px;\n}\n.solidgate-checkout-total svg {\n width: 25px;\n height: 25px;\n fill: none;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linejoin: round;\n}\n.solidgate-checkout-saved {\n width: fit-content;\n min-height: 36px;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n margin: -8px 0 9px auto;\n border-radius: 12px;\n background: #ffdce3;\n padding: 0 14px;\n color: #ff2544;\n font-size: 14px;\n font-weight: 900;\n line-height: 1.1;\n}\n\n.solidgate-checkout-email-form,\n.solidgate-checkout-email-label,\n.solidgate-checkout-wallets {\n display: grid;\n}\n\n.solidgate-checkout-email-form {\n gap: 16px;\n}\n\n.solidgate-checkout-email-label {\n gap: 8px;\n color: var(--color-text, #111827);\n font-size: 14px;\n font-weight: 500;\n}\n\n.solidgate-checkout-email-input {\n box-sizing: border-box;\n width: 100%;\n min-height: 44px;\n border: 1px solid var(--color-border, #d1d5db);\n border-radius: 8px;\n background: var(--color-bg, #fff);\n padding: 8px 12px;\n color: var(--color-text, #111827);\n font: inherit;\n}\n\n.solidgate-checkout-email-input::placeholder,\n.solidgate-checkout-status,\n.solidgate-checkout-status-text {\n color: var(--color-text-muted, #6b7280);\n}\n\n.solidgate-checkout-email-input:focus-visible,\n.solidgate-checkout-close:focus-visible,\n.solidgate-checkout-action:focus-visible {\n outline: 2px solid var(--color-accent, #3f51b5);\n outline-offset: 2px;\n}\n\n.solidgate-checkout-alert {\n margin: 0;\n color: var(--color-danger, #b91c1c);\n font-size: 14px;\n}\n\n.solidgate-checkout-action {\n box-sizing: border-box;\n width: 100%;\n min-height: 44px;\n border: 1px solid var(--color-accent, #3f51b5);\n border-radius: 8px;\n background: var(--color-accent, #3f51b5);\n padding: 8px 16px;\n color: var(--color-primary-text, #fff);\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n\n.solidgate-checkout-action:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.solidgate-checkout-action--spaced {\n margin-top: 16px;\n}\n\n.solidgate-checkout-wallets {\n gap: 12px;\n}\n.solidgate-checkout-wallets > div:empty,\n.solidgate-checkout-wallets:not(:has(> div:not(:empty))) { display: none; }\n.solidgate-checkout-wallets > div:not(:empty) {\n width: 100%;\n height: 54px;\n}\n.solidgate-checkout-wallets apple-pay-button {\n --apple-pay-button-width: 100%;\n --apple-pay-button-height: 54px;\n --apple-pay-button-border-radius: 0;\n width: 100%;\n height: 54px;\n}\n.solidgate-checkout-payment.is-branded {\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin: 0 -17px;\n padding: 9px 17px 32px;\n background: #f2f2f3;\n}\n.solidgate-checkout-methods {\n display: grid;\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n gap: 42px;\n}\n.solidgate-checkout-method {\n min-height: 74px;\n border: 2px solid #e6e7eb;\n border-radius: 13px;\n background: #fff;\n color: #303136;\n padding: 9px 8px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 6px;\n font: inherit;\n cursor: pointer;\n}\n.solidgate-checkout-method[aria-selected='true'] { border: 3px solid #050609; }\n.solidgate-checkout-method:focus-visible { outline: 2px solid var(--solidgate-checkout-theme-color, #3f51b5); outline-offset: 2px; }\n.solidgate-checkout-method strong { font-size: 20px; font-weight: 800; line-height: 1.1; }\n.solidgate-checkout-tab-wallet { width: 58px; height: 36px; }\n.solidgate-checkout-tab-brands { display: flex; align-items: center; gap: 4px; }\n.solidgate-checkout-tab-brand { width: 24px; height: 15px; }\n.solidgate-checkout-tab-wallet svg, .solidgate-checkout-tab-brand svg { width: 100%; height: 100%; }\n.solidgate-checkout-secure {\n min-height: 47px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 9px;\n margin: 0;\n border-radius: 12px;\n background: #dcffd0;\n color: #207733;\n font-size: 18px;\n font-weight: 800;\n}\n.solidgate-checkout-secure svg { width: 23px; height: 23px; }\n.solidgate-checkout-payment.is-branded .solidgate-checkout-card { padding: 10px 14px 0; }\n.solidgate-checkout-secure.is-card { width: fit-content; margin: 14px auto 0; padding: 0 14px; }\n.solidgate-sdk-card-container iframe { border: 0; }\n.solidgate-checkout-payment[hidden],\n.solidgate-checkout-wallets[hidden],\n.solidgate-checkout-card[hidden] { display: none; }\n.solidgate-inline-wallet { width: 100%; }\n.solidgate-inline-wallet .solidgate-checkout-wallets:has(> div:not(:empty)) { margin-bottom: 12px; }\n\n.solidgate-checkout-status {\n margin-top: 12px;\n border: 1px solid var(--color-border, #d1d5db);\n border-radius: 12px;\n background: var(--color-bg, #f9fafb);\n padding: 16px;\n font-size: 14px;\n}\n\n.solidgate-checkout-status p,\n.solidgate-checkout-status-text {\n margin: 0;\n}\n";
@@ -270,19 +270,35 @@ export const solidgateCheckoutDialogStyles = `
270
270
  font-weight: 900;
271
271
  }
272
272
 
273
+ .solidgate-checkout-total strong {
274
+ display: inline-flex;
275
+ align-items: center;
276
+ gap: 7px;
277
+ }
278
+ .solidgate-checkout-total svg {
279
+ width: 25px;
280
+ height: 25px;
281
+ fill: none;
282
+ stroke: currentColor;
283
+ stroke-width: 2;
284
+ stroke-linejoin: round;
285
+ }
273
286
  .solidgate-checkout-saved {
274
287
  width: fit-content;
275
288
  min-height: 36px;
289
+ box-sizing: border-box;
276
290
  display: flex;
277
291
  align-items: center;
278
- gap: 7px;
279
- margin: 0 auto 12px;
280
- border-radius: 999px;
281
- background: #fff3cf;
282
- padding: 0 13px;
283
- color: #2e3034;
292
+ justify-content: center;
293
+ gap: 8px;
294
+ margin: -8px 0 9px auto;
295
+ border-radius: 12px;
296
+ background: #ffdce3;
297
+ padding: 0 14px;
298
+ color: #ff2544;
284
299
  font-size: 14px;
285
- font-weight: 800;
300
+ font-weight: 900;
301
+ line-height: 1.1;
286
302
  }
287
303
 
288
304
  .solidgate-checkout-email-form,
@@ -358,31 +374,77 @@ export const solidgateCheckoutDialogStyles = `
358
374
 
359
375
  .solidgate-checkout-wallets {
360
376
  gap: 12px;
361
- margin-bottom: 12px;
362
377
  }
363
-
364
- .solidgate-checkout-dialog.is-branded .solidgate-checkout-wallets {
365
- margin-top: 4px;
378
+ .solidgate-checkout-wallets > div:empty,
379
+ .solidgate-checkout-wallets:not(:has(> div:not(:empty))) { display: none; }
380
+ .solidgate-checkout-wallets > div:not(:empty) {
381
+ width: 100%;
382
+ height: 54px;
366
383
  }
367
-
368
- .solidgate-checkout-dialog.is-branded .solidgate-checkout-wallets > div:not(:empty) {
369
- min-height: 48px;
384
+ .solidgate-checkout-wallets apple-pay-button {
385
+ --apple-pay-button-width: 100%;
386
+ --apple-pay-button-height: 54px;
387
+ --apple-pay-button-border-radius: 0;
388
+ width: 100%;
389
+ height: 54px;
370
390
  }
371
-
372
- .solidgate-checkout-secure {
373
- width: fit-content;
374
- margin: 14px auto 0;
375
- border-radius: 999px;
376
- background: #edfff4;
377
- padding: 8px 14px;
378
- color: #2b2d31;
379
- font-size: 13px;
380
- font-weight: 700;
391
+ .solidgate-checkout-payment.is-branded {
392
+ display: flex;
393
+ flex-direction: column;
394
+ gap: 12px;
395
+ margin: 0 -17px;
396
+ padding: 9px 17px 32px;
397
+ background: #f2f2f3;
381
398
  }
382
-
383
- .solidgate-checkout-payment[hidden] {
384
- display: none;
399
+ .solidgate-checkout-methods {
400
+ display: grid;
401
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
402
+ gap: 42px;
403
+ }
404
+ .solidgate-checkout-method {
405
+ min-height: 74px;
406
+ border: 2px solid #e6e7eb;
407
+ border-radius: 13px;
408
+ background: #fff;
409
+ color: #303136;
410
+ padding: 9px 8px;
411
+ display: flex;
412
+ flex-direction: column;
413
+ align-items: center;
414
+ justify-content: center;
415
+ gap: 6px;
416
+ font: inherit;
417
+ cursor: pointer;
418
+ }
419
+ .solidgate-checkout-method[aria-selected='true'] { border: 3px solid #050609; }
420
+ .solidgate-checkout-method:focus-visible { outline: 2px solid var(--solidgate-checkout-theme-color, #3f51b5); outline-offset: 2px; }
421
+ .solidgate-checkout-method strong { font-size: 20px; font-weight: 800; line-height: 1.1; }
422
+ .solidgate-checkout-tab-wallet { width: 58px; height: 36px; }
423
+ .solidgate-checkout-tab-brands { display: flex; align-items: center; gap: 4px; }
424
+ .solidgate-checkout-tab-brand { width: 24px; height: 15px; }
425
+ .solidgate-checkout-tab-wallet svg, .solidgate-checkout-tab-brand svg { width: 100%; height: 100%; }
426
+ .solidgate-checkout-secure {
427
+ min-height: 47px;
428
+ display: flex;
429
+ align-items: center;
430
+ justify-content: center;
431
+ gap: 9px;
432
+ margin: 0;
433
+ border-radius: 12px;
434
+ background: #dcffd0;
435
+ color: #207733;
436
+ font-size: 18px;
437
+ font-weight: 800;
385
438
  }
439
+ .solidgate-checkout-secure svg { width: 23px; height: 23px; }
440
+ .solidgate-checkout-payment.is-branded .solidgate-checkout-card { padding: 10px 14px 0; }
441
+ .solidgate-checkout-secure.is-card { width: fit-content; margin: 14px auto 0; padding: 0 14px; }
442
+ .solidgate-sdk-card-container iframe { border: 0; }
443
+ .solidgate-checkout-payment[hidden],
444
+ .solidgate-checkout-wallets[hidden],
445
+ .solidgate-checkout-card[hidden] { display: none; }
446
+ .solidgate-inline-wallet { width: 100%; }
447
+ .solidgate-inline-wallet .solidgate-checkout-wallets:has(> div:not(:empty)) { margin-bottom: 12px; }
386
448
 
387
449
  .solidgate-checkout-status {
388
450
  margin-top: 12px;
@@ -22,6 +22,8 @@ export type SolidgateCheckoutDialogContent = {
22
22
  export type SolidgateCheckoutDialogPresentation = {
23
23
  buttonColor: string;
24
24
  cardSubmitLabel: string;
25
+ cardLabel?: string;
26
+ paymentMethodLabel?: string;
25
27
  countdownLabel: string;
26
28
  discountAmountLabel: string;
27
29
  discountLabel: string;
@@ -43,6 +45,8 @@ export type SolidgateCheckoutDialogPresentation = {
43
45
  };
44
46
  export type SolidgateCheckoutDialogProps = {
45
47
  open: boolean;
48
+ /** Wallet-only paywall placement; mount only one Solidgate surface at a time. */
49
+ layout?: 'dialog' | 'wallet';
46
50
  request: Omit<PrepareSolidgateCheckoutInput, 'signal'>;
47
51
  customerEmail?: string | null;
48
52
  checkoutAnalytics?: SolidgateCheckoutAnalyticsContext | null;
@@ -54,6 +58,8 @@ export type SolidgateCheckoutDialogProps = {
54
58
  onRetry?: () => void;
55
59
  onError?: (message: string) => void;
56
60
  onPreparationStart?: () => void;
61
+ /** True while a submitted payment still needs verification (including resumable errors). */
62
+ onPaymentPendingChange?: (pending: boolean) => void;
57
63
  onStateChange?: (state: SolidgateCheckoutDialogState) => void;
58
64
  };
59
65
  export type SolidgateCheckoutAnalyticsContext = {
@@ -11,5 +11,5 @@ export function SolidgateCheckoutSummary({ presentation }) {
11
11
  const showPromo = Boolean((presentation === null || presentation === void 0 ? void 0 : presentation.promoActive) &&
12
12
  presentation.discountPercent > 0 &&
13
13
  presentation.promoCode.trim());
14
- return (_jsxs("section", { className: 'solidgate-checkout-summary', children: [showPromo ? (_jsxs("p", { className: 'solidgate-checkout-countdown', children: [presentation.discountPercent, "% ", presentation.countdownLabel, ' ', formatCountdown(presentation.remainingSeconds), " min"] })) : null, _jsxs("p", { className: 'solidgate-checkout-satisfaction', children: [_jsx("strong", { children: presentation.satisfactionPercent }), ' ', presentation.satisfactionLabel] }), showPromo ? (_jsxs("div", { className: 'solidgate-checkout-price-stack', children: [_jsxs("div", { className: 'solidgate-checkout-price-row is-muted', children: [_jsx("span", { children: presentation.originalPriceLabel }), _jsx("span", { className: 'solidgate-checkout-strike', children: presentation.originalPriceValue })] }), _jsxs("div", { className: 'solidgate-checkout-price-row is-discount', children: [_jsx("strong", { children: presentation.discountLabel }), _jsx("strong", { children: presentation.discountAmountLabel })] }), _jsxs("div", { className: 'solidgate-checkout-promo', children: [_jsx("span", { children: presentation.promoCodeLabel }), _jsx("strong", { children: presentation.promoCode.trim() })] })] })) : null, _jsxs("div", { className: `solidgate-checkout-total${showPromo ? '' : ' is-plain'}`, children: [_jsx("span", { children: presentation.totalLabel }), _jsx("strong", { children: presentation.totalValue })] }), showPromo ? (_jsxs("p", { className: 'solidgate-checkout-saved', children: [_jsx("span", { "aria-hidden": 'true', children: "\uD83D\uDD25" }), presentation.savedLabel] })) : null] }));
14
+ return (_jsxs("section", { className: 'solidgate-checkout-summary', children: [showPromo ? (_jsxs("p", { className: 'solidgate-checkout-countdown', children: [presentation.discountPercent, "% ", presentation.countdownLabel, ' ', formatCountdown(presentation.remainingSeconds), " min"] })) : null, _jsxs("p", { className: 'solidgate-checkout-satisfaction', children: [_jsx("strong", { children: presentation.satisfactionPercent }), ' ', presentation.satisfactionLabel] }), showPromo ? (_jsxs("div", { className: 'solidgate-checkout-price-stack', children: [_jsxs("div", { className: 'solidgate-checkout-price-row is-muted', children: [_jsx("span", { children: presentation.originalPriceLabel }), _jsx("span", { className: 'solidgate-checkout-strike', children: presentation.originalPriceValue })] }), _jsxs("div", { className: 'solidgate-checkout-price-row is-discount', children: [_jsx("strong", { children: presentation.discountLabel }), _jsx("strong", { children: presentation.discountAmountLabel })] }), _jsxs("div", { className: 'solidgate-checkout-promo', children: [_jsx("span", { children: presentation.promoCodeLabel }), _jsx("strong", { children: presentation.promoCode.trim() })] })] })) : null, _jsxs("div", { className: `solidgate-checkout-total${showPromo ? '' : ' is-plain'}`, children: [_jsx("span", { children: presentation.totalLabel }), _jsxs("strong", { children: [_jsxs("svg", { viewBox: '0 0 24 24', "aria-hidden": 'true', children: [_jsx("path", { d: 'M20 13 11 22 2 13V2h11l9 9-2 2Z' }), _jsx("circle", { cx: '7', cy: '7', r: '1' })] }), presentation.totalValue] })] }), showPromo ? (_jsxs("p", { className: 'solidgate-checkout-saved', children: [_jsx("span", { "aria-hidden": 'true', children: "\uD83D\uDD25" }), presentation.savedLabel] })) : null] }));
15
15
  }
@@ -1,7 +1,11 @@
1
1
  import type { SolidgateCheckoutPreparation } from '../services/solidgate.service.js';
2
- export declare function SolidgatePaymentForm({ buttonColor, cardSubmitLabel, checkout, hidden, loadingLabel, onError, onMounted, onSubmit, onVerify, }: {
2
+ export declare function SolidgatePaymentForm({ buttonColor, walletOnly, cardSubmitLabel, secureLabel, cardLabel, paymentMethodLabel, checkout, hidden, onError, onMounted, onSubmit, onVerify, }: {
3
3
  buttonColor: string;
4
+ walletOnly?: boolean;
4
5
  cardSubmitLabel: string;
6
+ secureLabel?: string;
7
+ cardLabel?: string;
8
+ paymentMethodLabel?: string;
5
9
  checkout: SolidgateCheckoutPreparation;
6
10
  hidden: boolean;
7
11
  loadingLabel: string;
@@ -1,26 +1,15 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Suspense, lazy, useEffect, useRef } from 'react';
4
- const SolidgatePayment = lazy(async () => ({
5
- default: (await import('@solidgate/react-sdk')).default,
6
- }));
7
- const safeDestroyPaymentForm = (instance) => {
8
- var _a;
9
- try {
10
- instance === null || instance === void 0 ? void 0 : instance.unsubscribeAll();
11
- }
12
- catch (_b) {
13
- // The global destroy below is the final cleanup boundary.
14
- }
15
- try {
16
- (_a = window.PaymentFormSdk) === null || _a === void 0 ? void 0 : _a.destroy();
17
- }
18
- catch (_c) {
19
- // Cleanup must stay safe when the remote SDK is partially initialized.
20
- }
21
- };
22
- export function SolidgatePaymentForm({ buttonColor, cardSubmitLabel, checkout, hidden, loadingLabel, onError, onMounted, onSubmit, onVerify, }) {
23
- const instanceRef = useRef(null);
3
+ import { useEffect, useId, useRef, useState } from 'react';
4
+ import { PaymentBrandMark, SecurityLockIcon } from '../../stripe/components/CheckoutBrandAssets.js';
5
+ import { SolidgateSdkPayment } from './SolidgateSdkPayment.js';
6
+ export function SolidgatePaymentForm({ buttonColor, walletOnly = false, cardSubmitLabel, secureLabel, cardLabel = 'Credit card', paymentMethodLabel = 'Payment method', checkout, hidden, onError, onMounted, onSubmit, onVerify, }) {
7
+ const panelId = useId();
8
+ const [wallets, setWallets] = useState([]);
9
+ const [selectedMethod, setSelectedMethod] = useState('wallet');
10
+ const showTabs = !walletOnly && Boolean(secureLabel) && wallets.length > 0;
11
+ const showWallet = walletOnly || !showTabs || selectedMethod === 'wallet';
12
+ const showCard = !walletOnly && (!showTabs || selectedMethod === 'card');
24
13
  const submittedRef = useRef(false);
25
14
  const paymentBoundaryRef = useRef(null);
26
15
  const mountedReportedRef = useRef(false);
@@ -37,6 +26,12 @@ export function SolidgatePaymentForm({ buttonColor, cardSubmitLabel, checkout, h
37
26
  return;
38
27
  }
39
28
  const reportIframeMounted = () => {
29
+ var _a, _b;
30
+ const available = [
31
+ ((_a = applePayContainerRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('apple-pay-button')) ? 'Apple Pay' : null,
32
+ ((_b = googlePayContainerRef.current) === null || _b === void 0 ? void 0 : _b.querySelector('button')) ? 'Google Pay' : null,
33
+ ].filter((method) => Boolean(method));
34
+ setWallets((previous) => previous.join() === available.join() ? previous : available);
40
35
  if (!mountedReportedRef.current
41
36
  && boundary.querySelector('iframe#solid-payment-form-iframe, iframe[name="solid-payment-form-iframe"]')) {
42
37
  mountedReportedRef.current = true;
@@ -48,34 +43,19 @@ export function SolidgatePaymentForm({ buttonColor, cardSubmitLabel, checkout, h
48
43
  observer.observe(boundary, { childList: true, subtree: true });
49
44
  return () => observer.disconnect();
50
45
  }, [checkout.attemptId]);
51
- useEffect(() => {
52
- submittedRef.current = false;
53
- return () => {
54
- safeDestroyPaymentForm(instanceRef.current);
55
- instanceRef.current = null;
56
- };
57
- }, [checkout.attemptId]);
58
46
  const walletButtonType = checkout.display.billingInterval ? 'subscribe' : 'buy';
59
- return (_jsxs("div", { ref: paymentBoundaryRef, className: 'solidgate-checkout-payment', "data-solidgate-attempt-id": checkout.attemptId, hidden: hidden, "aria-hidden": hidden || undefined, children: [_jsxs("div", { className: 'solidgate-checkout-wallets', children: [_jsx("div", { ref: applePayContainerRef, "data-solidgate-wallet": 'apple-pay' }), _jsx("div", { ref: googlePayContainerRef, "data-solidgate-wallet": 'google-pay' })] }), _jsx(Suspense, { fallback: (_jsx("p", { role: 'status', className: 'solidgate-checkout-status-text', children: loadingLabel })), children: _jsx(SolidgatePayment, { merchantData: checkout.initialization.merchantData, width: '100%', formParams: {
60
- autoFocus: false,
61
- isSolidLogoVisible: true,
62
- submitButtonText: cardSubmitLabel,
63
- }, styles: {
47
+ return (_jsxs("div", { ref: paymentBoundaryRef, className: `solidgate-checkout-payment${secureLabel && !walletOnly ? ' is-branded' : ''}`, "data-solidgate-attempt-id": checkout.attemptId, hidden: hidden, "aria-hidden": hidden || undefined, children: [showTabs ? (_jsxs("div", { className: 'solidgate-checkout-methods', role: 'tablist', "aria-label": paymentMethodLabel, children: [_jsx("button", { type: 'button', role: 'tab', id: `${panelId}-wallet-tab`, "aria-label": wallets.join(' / '), "aria-selected": selectedMethod === 'wallet', "aria-controls": `${panelId}-wallet`, className: 'solidgate-checkout-method', onClick: () => setSelectedMethod('wallet'), children: wallets.map((label) => _jsx(PaymentBrandMark, { label: label, className: 'solidgate-checkout-tab-wallet' }, label)) }), _jsxs("button", { type: 'button', role: 'tab', id: `${panelId}-card-tab`, "aria-selected": selectedMethod === 'card', "aria-controls": `${panelId}-card`, className: 'solidgate-checkout-method', onClick: () => setSelectedMethod('card'), children: [_jsx("strong", { children: cardLabel }), _jsx("span", { className: 'solidgate-checkout-tab-brands', "aria-hidden": 'true', children: ['Visa', 'Mastercard', 'Maestro', 'Discover'].map((label) => (_jsx(PaymentBrandMark, { label: label, className: 'solidgate-checkout-tab-brand' }, label))) })] })] })) : null, !walletOnly && secureLabel && wallets.length > 0 && showWallet ? (_jsxs("p", { className: 'solidgate-checkout-secure', children: [_jsx(SecurityLockIcon, {}), secureLabel] })) : null, _jsxs("div", { className: 'solidgate-checkout-wallets', id: `${panelId}-wallet`, role: showTabs ? 'tabpanel' : undefined, "aria-labelledby": showTabs ? `${panelId}-wallet-tab` : undefined, hidden: !showWallet, children: [_jsx("div", { ref: applePayContainerRef, "data-solidgate-wallet": 'apple-pay' }), _jsx("div", { ref: googlePayContainerRef, "data-solidgate-wallet": 'google-pay' })] }), _jsx("div", { className: 'solidgate-checkout-card', id: `${panelId}-card`, role: showTabs ? 'tabpanel' : undefined, "aria-labelledby": showTabs ? `${panelId}-card-tab` : undefined, hidden: !showCard, children: _jsx(SolidgateSdkPayment, { onInitializationError: onError, merchantData: checkout.initialization.merchantData, width: '100%', formParams: Object.assign({ autoFocus: false, enabled: !walletOnly, isSolidLogoVisible: true, submitButtonText: cardSubmitLabel }, (secureLabel ? { cardNumberLabel: 'Card number', cardExpiryDateLabel: 'Expiration date', cardCvvLabel: 'Security code' } : {})), styles: {
64
48
  form_body: {
65
49
  'font-family': 'Inter, Arial, sans-serif',
66
50
  },
67
- input_group: {
68
- input: {
69
- 'border-color': '#d8d9dd',
70
- 'border-radius': '10px',
71
- },
72
- },
51
+ input_group: Object.assign({ input: Object.assign({ 'border-color': '#d8d9dd', 'border-radius': secureLabel ? '0' : '10px' }, (secureLabel ? { 'background-color': '#fff', 'font-size': '16px', height: '50px' } : {})) }, (secureLabel ? { '.label': { 'font-size': '14px', 'font-weight': '400', color: '#303136' } } : {})),
73
52
  submit_button: {
74
53
  'background-color': buttonColor,
75
54
  'border-radius': '10px',
76
- 'font-size': '16px',
55
+ 'font-size': secureLabel ? '21px' : '16px',
77
56
  'font-weight': '800',
78
- height: '52px',
57
+ height: secureLabel ? '60px' : '52px',
58
+ 'text-transform': 'none',
79
59
  },
80
60
  }, applePayButtonParams: {
81
61
  color: 'black',
@@ -86,17 +66,7 @@ export function SolidgatePaymentForm({ buttonColor, cardSubmitLabel, checkout, h
86
66
  color: 'black',
87
67
  enabled: true,
88
68
  type: walletButtonType,
89
- }, applePayContainerRef: applePayContainerRef, googlePayContainerRef: googlePayContainerRef, onReadyPaymentInstance: (instance) => {
90
- if (instanceRef.current && instanceRef.current !== instance) {
91
- try {
92
- instanceRef.current.unsubscribeAll();
93
- }
94
- catch (_a) {
95
- // The active instance remains usable even if stale-listener cleanup fails.
96
- }
97
- }
98
- instanceRef.current = instance;
99
- }, onMounted: () => {
69
+ }, applePayContainerRef: applePayContainerRef, googlePayContainerRef: googlePayContainerRef, onMounted: () => {
100
70
  if (!mountedReportedRef.current) {
101
71
  mountedReportedRef.current = true;
102
72
  onMountedRef.current();
@@ -110,5 +80,5 @@ export function SolidgatePaymentForm({ buttonColor, cardSubmitLabel, checkout, h
110
80
  return;
111
81
  }
112
82
  onError();
113
- } }, checkout.attemptId) })] }));
83
+ } }, checkout.attemptId) }), !walletOnly && secureLabel && (wallets.length === 0 || !showWallet) ? (_jsxs("p", { className: 'solidgate-checkout-secure is-card', children: [_jsx(SecurityLockIcon, {}), secureLabel] })) : null] }));
114
84
  }
@@ -0,0 +1,8 @@
1
+ import type Payment from '@solidgate/react-sdk';
2
+ import { type ComponentProps } from 'react';
3
+ type Props = ComponentProps<typeof Payment> & {
4
+ onInitializationError: () => void;
5
+ };
6
+ /** Own container IDs and cancel pending initialization when a placement goes away. */
7
+ export declare function SolidgateSdkPayment(props: Props): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,66 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useEffect, useId, useRef } from 'react';
4
+ let activeOwner = null;
5
+ /** Own container IDs and cancel pending initialization when a placement goes away. */
6
+ export function SolidgateSdkPayment(props) {
7
+ const id = `solidgate-${useId().replace(/[^a-zA-Z0-9]/g, '')}`;
8
+ const initialProps = useRef(props);
9
+ const callbacks = useRef(props);
10
+ useEffect(() => { callbacks.current = props; });
11
+ useEffect(() => {
12
+ var _a, _b;
13
+ let active = true;
14
+ let client = null;
15
+ let instance = null;
16
+ const owner = Symbol(id);
17
+ const config = initialProps.current;
18
+ const apple = (_a = config.applePayContainerRef) === null || _a === void 0 ? void 0 : _a.current;
19
+ const google = (_b = config.googlePayContainerRef) === null || _b === void 0 ? void 0 : _b.current;
20
+ if (apple)
21
+ apple.id = `${id}-apple`;
22
+ if (google)
23
+ google.id = `${id}-google`;
24
+ void import('@solidgate/react-sdk').then(async (sdk) => {
25
+ var _a, _b;
26
+ const loaded = await sdk.SdkLoader.load();
27
+ if (!active || !loaded)
28
+ return;
29
+ client = loaded;
30
+ activeOwner = owner;
31
+ instance = client.init({
32
+ merchantData: config.merchantData,
33
+ iframeParams: { containerId: id, width: config.width || '100%' },
34
+ formParams: config.formParams,
35
+ styles: config.styles,
36
+ applePayButtonParams: Object.assign(Object.assign({}, config.applePayButtonParams), { containerId: apple === null || apple === void 0 ? void 0 : apple.id }),
37
+ googlePayButtonParams: Object.assign(Object.assign({}, config.googlePayButtonParams), { containerId: google === null || google === void 0 ? void 0 : google.id }),
38
+ });
39
+ instance.on(sdk.MessageType.Mounted, (event) => { var _a, _b; return (_b = (_a = callbacks.current).onMounted) === null || _b === void 0 ? void 0 : _b.call(_a, event.data); });
40
+ instance.on(sdk.MessageType.Submit, (event) => { var _a, _b; return (_b = (_a = callbacks.current).onSubmit) === null || _b === void 0 ? void 0 : _b.call(_a, event.data); });
41
+ instance.on(sdk.MessageType.Verify, (event) => { var _a, _b; return (_b = (_a = callbacks.current).onVerify) === null || _b === void 0 ? void 0 : _b.call(_a, event.data); });
42
+ instance.on(sdk.MessageType.Success, (event) => { var _a, _b; return (_b = (_a = callbacks.current).onSuccess) === null || _b === void 0 ? void 0 : _b.call(_a, event.data); });
43
+ instance.on(sdk.MessageType.Fail, (event) => { var _a, _b; return (_b = (_a = callbacks.current).onFail) === null || _b === void 0 ? void 0 : _b.call(_a, event.data); });
44
+ instance.on(sdk.MessageType.Error, (event) => { var _a, _b; return (_b = (_a = callbacks.current).onError) === null || _b === void 0 ? void 0 : _b.call(_a, event.data); });
45
+ (_b = (_a = callbacks.current).onReadyPaymentInstance) === null || _b === void 0 ? void 0 : _b.call(_a, instance);
46
+ }).catch(() => {
47
+ if (active)
48
+ callbacks.current.onInitializationError();
49
+ });
50
+ return () => {
51
+ active = false;
52
+ if (activeOwner !== owner)
53
+ return;
54
+ activeOwner = null;
55
+ try {
56
+ instance === null || instance === void 0 ? void 0 : instance.unsubscribeAll();
57
+ }
58
+ catch ( /* Remote SDK may be partially initialized. */_a) { /* Remote SDK may be partially initialized. */ }
59
+ try {
60
+ client === null || client === void 0 ? void 0 : client.destroy();
61
+ }
62
+ catch ( /* Cleanup must not interrupt navigation. */_b) { /* Cleanup must not interrupt navigation. */ }
63
+ };
64
+ }, [id]);
65
+ return _jsx("div", { id: id, className: 'solidgate-sdk-card-container' });
66
+ }
@@ -29,6 +29,8 @@ export type SharedStripeCheckoutV2DialogProps = {
29
29
  initialWalletAvailable?: boolean | null;
30
30
  nameOnCardPlaceholder?: string;
31
31
  onClose: () => void;
32
+ /** Defaults to onClose after the wallet reports cancellation. */
33
+ onWalletCancel?: () => void;
32
34
  onCustomerEmailChange?: (value: string) => void;
33
35
  onCustomerEmailCommit?: (email: string) => Promise<string | null | void>;
34
36
  onError?: (message: string | null) => void;
@@ -74,5 +76,5 @@ export type SharedCheckoutSpecialOfferDialogProps = {
74
76
  themeColor: string;
75
77
  title: string;
76
78
  };
77
- export declare function SharedStripeCheckoutV2Dialog({ checkoutAnalytics, checkoutSessionId, clientSecret, onClose, stripePromise, supportedCountries, variant, presentation, ...props }: SharedStripeCheckoutV2DialogProps): import("react/jsx-runtime").JSX.Element;
79
+ export declare function SharedStripeCheckoutV2Dialog({ checkoutAnalytics, checkoutSessionId, clientSecret, onClose, onWalletCancel, stripePromise, supportedCountries, variant, presentation, ...props }: SharedStripeCheckoutV2DialogProps): import("react/jsx-runtime").JSX.Element;
78
80
  export declare function SharedCheckoutSpecialOfferDialog({ buttonColor, buttonLabel, description, discountLabel, imageAlt, imageSrc, onAccept, themeColor, title, }: SharedCheckoutSpecialOfferDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -59,7 +59,7 @@ function CheckoutSessionProvider({ children, clientSecret, fixedBillingCountry,
59
59
  return (_jsx(CheckoutProvider, { stripe: stripePromise, options: checkoutProviderOptions, children: providerChildren }, clientSecret));
60
60
  }
61
61
  export function SharedStripeCheckoutV2Dialog(_a) {
62
- var { checkoutAnalytics, checkoutSessionId, clientSecret, onClose, stripePromise, supportedCountries, variant = 'standard', presentation = 'dialog' } = _a, props = __rest(_a, ["checkoutAnalytics", "checkoutSessionId", "clientSecret", "onClose", "stripePromise", "supportedCountries", "variant", "presentation"]);
62
+ var { checkoutAnalytics, checkoutSessionId, clientSecret, onClose, onWalletCancel, stripePromise, supportedCountries, variant = 'standard', presentation = 'dialog' } = _a, props = __rest(_a, ["checkoutAnalytics", "checkoutSessionId", "clientSecret", "onClose", "onWalletCancel", "stripePromise", "supportedCountries", "variant", "presentation"]);
63
63
  const normalizedSupportedCountries = useMemo(() => normalizeSupportedCheckoutCountries(supportedCountries), [supportedCountries]);
64
64
  const fixedBillingCountry = getFixedSupportedBillingCountry(normalizedSupportedCountries);
65
65
  const handleClose = useCallback(() => {
@@ -90,7 +90,7 @@ export function SharedStripeCheckoutV2Dialog(_a) {
90
90
  window.addEventListener('keydown', handleKeyDown);
91
91
  return () => window.removeEventListener('keydown', handleKeyDown);
92
92
  }, [handleClose, presentation]);
93
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: presentation === 'inline' ? 'shared-checkout-v2-inline' : 'shared-checkout-v2-overlay', children: _jsx("div", { className: presentation === 'inline' ? undefined : 'shared-checkout-v2-dialog', "data-variant": variant, role: presentation === 'dialog' ? 'dialog' : 'region', "aria-modal": presentation === 'dialog' ? true : undefined, "aria-labelledby": presentation === 'dialog' ? 'shared-checkout-v2-title' : undefined, "aria-label": presentation === 'inline' ? props.title : undefined, children: _jsx(CheckoutSessionProvider, { clientSecret: clientSecret, fixedBillingCountry: fixedBillingCountry, stripePromise: stripePromise, variant: variant, children: _jsx(SharedStripeCheckoutV2CheckoutSessionForm, Object.assign({}, props, { presentation: presentation, checkoutAnalytics: checkoutAnalytics, checkoutSessionId: checkoutSessionId, clientSecret: clientSecret, onClose: handleClose, supportedCountries: normalizedSupportedCountries, variant: variant })) }) }) }), _jsx("style", { children: sharedStripeCheckoutV2Styles })] }));
93
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: presentation === 'inline' ? 'shared-checkout-v2-inline' : 'shared-checkout-v2-overlay', children: _jsx("div", { className: presentation === 'inline' ? undefined : 'shared-checkout-v2-dialog', "data-variant": variant, role: presentation === 'dialog' ? 'dialog' : 'region', "aria-modal": presentation === 'dialog' ? true : undefined, "aria-labelledby": presentation === 'dialog' ? 'shared-checkout-v2-title' : undefined, "aria-label": presentation === 'inline' ? props.title : undefined, children: _jsx(CheckoutSessionProvider, { clientSecret: clientSecret, fixedBillingCountry: fixedBillingCountry, stripePromise: stripePromise, variant: variant, children: _jsx(SharedStripeCheckoutV2CheckoutSessionForm, Object.assign({}, props, { presentation: presentation, checkoutAnalytics: checkoutAnalytics, checkoutSessionId: checkoutSessionId, clientSecret: clientSecret, onClose: handleClose, onWalletCancel: onWalletCancel !== null && onWalletCancel !== void 0 ? onWalletCancel : onClose, supportedCountries: normalizedSupportedCountries, variant: variant })) }) }) }), _jsx("style", { children: sharedStripeCheckoutV2Styles })] }));
94
94
  }
95
95
  function SharedCheckoutSpecialOfferGift({ discountLabel, imageAlt, imageSrc, }) {
96
96
  if (imageSrc) {
@@ -3,5 +3,5 @@ export declare const getFixedSupportedBillingCountry: (supportedCountries: reado
3
3
  type SharedStripeCheckoutV2FormProps = Omit<SharedStripeCheckoutV2DialogProps, 'stripePromise' | 'onClose'> & {
4
4
  onClose: () => void;
5
5
  };
6
- export declare function SharedStripeCheckoutV2CheckoutSessionForm({ copy, amountCents, buttonColor, cardSubmitLabel, closeAriaLabel, countdownLabel, checkoutAnalytics, checkoutSessionId, customerEmail, customerEmailEditable: allowEmailEditing, customerEmailLabel, customerEmailPlaceholder, customerEmailInvalidMessage, customerName, discountAmountLabel, discountLabel, discountPercent, initialWalletAvailable, onClose, onCustomerEmailChange, onCustomerEmailCommit, onError, onInactiveCheckoutSession, onPaymentInfoSubmitted, onSuccess, paymentMethodLabels, promoActive, processingLabel, promoCode, promoCodeLabel, remainingSeconds, returnUrl, savedLabel, secureLabel, satisfactionLabel, satisfactionPercent, summaryLabel, supportedCountries, themeColor, title, totalLabel, totalValue, unsupportedCountryMessage, walletButtonLabel, originalPriceLabel, originalPriceValue, variant, presentation, }: SharedStripeCheckoutV2FormProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function SharedStripeCheckoutV2CheckoutSessionForm({ copy, amountCents, buttonColor, cardSubmitLabel, closeAriaLabel, countdownLabel, checkoutAnalytics, checkoutSessionId, customerEmail, customerEmailEditable: allowEmailEditing, customerEmailLabel, customerEmailPlaceholder, customerEmailInvalidMessage, customerName, discountAmountLabel, discountLabel, discountPercent, initialWalletAvailable, onClose, onWalletCancel, onCustomerEmailChange, onCustomerEmailCommit, onError, onInactiveCheckoutSession, onPaymentInfoSubmitted, onSuccess, paymentMethodLabels, promoActive, processingLabel, promoCode, promoCodeLabel, remainingSeconds, returnUrl, savedLabel, secureLabel, satisfactionLabel, satisfactionPercent, summaryLabel, supportedCountries, themeColor, title, totalLabel, totalValue, unsupportedCountryMessage, walletButtonLabel, originalPriceLabel, originalPriceValue, variant, presentation, }: SharedStripeCheckoutV2FormProps): import("react/jsx-runtime").JSX.Element;
7
7
  export {};
@@ -22,7 +22,7 @@ function getFriendlyCardErrorMessage(error, fallback) {
22
22
  ? error.message
23
23
  : fallback;
24
24
  }
25
- export function SharedStripeCheckoutV2CheckoutSessionForm({ copy = defaultCheckoutV2Copy, amountCents, buttonColor, cardSubmitLabel, closeAriaLabel, countdownLabel, checkoutAnalytics, checkoutSessionId, customerEmail, customerEmailEditable: allowEmailEditing = false, customerEmailLabel = 'Email', customerEmailPlaceholder = 'Enter your email', customerEmailInvalidMessage = 'Enter a valid email address.', customerName, discountAmountLabel, discountLabel, discountPercent, initialWalletAvailable, onClose, onCustomerEmailChange, onCustomerEmailCommit, onError, onInactiveCheckoutSession, onPaymentInfoSubmitted, onSuccess, paymentMethodLabels = defaultPaymentMethodLabels, promoActive, processingLabel, promoCode, promoCodeLabel, remainingSeconds, returnUrl, savedLabel, secureLabel, satisfactionLabel, satisfactionPercent, summaryLabel, supportedCountries, themeColor, title, totalLabel, totalValue, unsupportedCountryMessage, walletButtonLabel, originalPriceLabel, originalPriceValue, variant = 'standard', presentation = 'dialog', }) {
25
+ export function SharedStripeCheckoutV2CheckoutSessionForm({ copy = defaultCheckoutV2Copy, amountCents, buttonColor, cardSubmitLabel, closeAriaLabel, countdownLabel, checkoutAnalytics, checkoutSessionId, customerEmail, customerEmailEditable: allowEmailEditing = false, customerEmailLabel = 'Email', customerEmailPlaceholder = 'Enter your email', customerEmailInvalidMessage = 'Enter a valid email address.', customerName, discountAmountLabel, discountLabel, discountPercent, initialWalletAvailable, onClose, onWalletCancel, onCustomerEmailChange, onCustomerEmailCommit, onError, onInactiveCheckoutSession, onPaymentInfoSubmitted, onSuccess, paymentMethodLabels = defaultPaymentMethodLabels, promoActive, processingLabel, promoCode, promoCodeLabel, remainingSeconds, returnUrl, savedLabel, secureLabel, satisfactionLabel, satisfactionPercent, summaryLabel, supportedCountries, themeColor, title, totalLabel, totalValue, unsupportedCountryMessage, walletButtonLabel, originalPriceLabel, originalPriceValue, variant = 'standard', presentation = 'dialog', }) {
26
26
  const checkoutState = useCheckout();
27
27
  const walletPaymentMethods = usePlatformWalletPaymentMethods();
28
28
  const [selectedMethod, setSelectedMethod] = useState('wallet');
@@ -278,7 +278,7 @@ export function SharedStripeCheckoutV2CheckoutSessionForm({ copy = defaultChecko
278
278
  effectiveSelectedMethod === 'wallet' ? 'is-visible' : '',
279
279
  ]
280
280
  .filter(Boolean)
281
- .join(' '), children: [_jsxs("p", { className: 'shared-checkout-v2-secure-pill', children: [_jsx(SecurityLockIcon, { className: 'shared-checkout-v2-secure-pill-icon' }), secureLabel] }), _jsxs("div", { className: 'shared-checkout-v2-wallet-shell', "aria-label": walletAriaLabel, children: [_jsx(StripeCheckoutExpressCheckoutButton, { amountCents: amountCents, availabilityPaymentMethods: walletPaymentMethods, beforeConfirm: ensureCustomerEmail, checkoutAnalytics: checkoutAnalytics, checkoutSessionId: checkoutSessionId, className: 'shared-checkout-v2-express-buttons', confirmEmail: false, customerEmail: resolvedCustomerEmail, customerName: customerName, initialAvailable: initialWalletAvailable, keepInitialAvailableOnReady: initialWalletAvailable === true, onAvailabilityChange: handleWalletAvailabilityChange, onError: (message) => setSharedError(message, true), onPaymentInfoSubmitted: onPaymentInfoSubmitted, onPaymentRejected: () => setSelectedMethod('card'), onSuccess: () => trackCheckoutSuccess(), onEmbeddedComplete: () => setCompleted(true), onVerificationPending: () => setProviderConfirmed(true), options: expressCheckoutOptions, returnUrl: returnUrl, summaryLabel: expressCheckoutSummaryLabel, supportedCountries: normalizedSupportedCountries, unsupportedCountryMessage: unsupportedCountryMessage }), _jsx("span", { className: 'shared-checkout-v2-sr-only', children: walletAriaLabel })] })] }) : null, _jsxs("div", { hidden: effectiveSelectedMethod !== 'card', className: [
281
+ .join(' '), children: [_jsxs("p", { className: 'shared-checkout-v2-secure-pill', children: [_jsx(SecurityLockIcon, { className: 'shared-checkout-v2-secure-pill-icon' }), secureLabel] }), _jsxs("div", { className: 'shared-checkout-v2-wallet-shell', "aria-label": walletAriaLabel, children: [_jsx(StripeCheckoutExpressCheckoutButton, { amountCents: amountCents, availabilityPaymentMethods: walletPaymentMethods, beforeConfirm: ensureCustomerEmail, checkoutAnalytics: checkoutAnalytics, checkoutSessionId: checkoutSessionId, className: 'shared-checkout-v2-express-buttons', confirmEmail: false, customerEmail: resolvedCustomerEmail, customerName: customerName, initialAvailable: initialWalletAvailable, keepInitialAvailableOnReady: initialWalletAvailable === true, onAvailabilityChange: handleWalletAvailabilityChange, onCancel: onWalletCancel, onError: (message) => setSharedError(message, true), onPaymentInfoSubmitted: onPaymentInfoSubmitted, onPaymentRejected: () => setSelectedMethod('card'), onSuccess: () => trackCheckoutSuccess(), onEmbeddedComplete: () => setCompleted(true), onVerificationPending: () => setProviderConfirmed(true), options: expressCheckoutOptions, returnUrl: returnUrl, summaryLabel: expressCheckoutSummaryLabel, supportedCountries: normalizedSupportedCountries, unsupportedCountryMessage: unsupportedCountryMessage }), _jsx("span", { className: 'shared-checkout-v2-sr-only', children: walletAriaLabel })] })] }) : null, _jsxs("div", { hidden: effectiveSelectedMethod !== 'card', className: [
282
282
  'shared-checkout-v2-card-panel',
283
283
  effectiveSelectedMethod === 'card' ? 'is-visible' : '',
284
284
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funnelsgrove/payments",
3
- "version": "0.26.0",
3
+ "version": "0.28.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/The-Solid-Grove/funnelsgrove.git",