@funnelsgrove/payments 0.11.23 → 0.11.26

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.
@@ -0,0 +1,400 @@
1
+ export const solidgateCheckoutDialogStyles = `
2
+ .solidgate-checkout-overlay {
3
+ position: fixed;
4
+ inset: 0;
5
+ z-index: 100;
6
+ box-sizing: border-box;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ overflow: hidden;
11
+ padding: 16px;
12
+ background: rgb(17 24 39 / 60%);
13
+ backdrop-filter: blur(4px);
14
+ }
15
+
16
+ .solidgate-checkout-overlay.is-branded {
17
+ z-index: 110;
18
+ align-items: stretch;
19
+ padding: 0;
20
+ background: #fff;
21
+ backdrop-filter: none;
22
+ }
23
+
24
+ .solidgate-checkout-dialog {
25
+ box-sizing: border-box;
26
+ width: min(100%, 512px);
27
+ max-height: calc(100svh - 32px);
28
+ overflow-y: auto;
29
+ border: 1px solid var(--color-border, #d1d5db);
30
+ border-radius: 16px;
31
+ background: var(--color-surface, #fff);
32
+ padding: 20px;
33
+ color: var(--color-text, #111827);
34
+ box-shadow: 0 24px 80px rgb(17 24 39 / 22%);
35
+ }
36
+
37
+ .solidgate-checkout-dialog.is-branded {
38
+ width: min(100%, 430px);
39
+ height: 100svh;
40
+ max-height: 100svh;
41
+ border: 0;
42
+ border-radius: 0;
43
+ background: #fff;
44
+ padding: 0 17px 28px;
45
+ color: #303136;
46
+ box-shadow: none;
47
+ font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
48
+ }
49
+
50
+ .solidgate-checkout-dialog.is-preparing {
51
+ position: absolute;
52
+ opacity: 0;
53
+ pointer-events: none;
54
+ }
55
+
56
+ .solidgate-checkout-loader {
57
+ display: grid;
58
+ place-items: center;
59
+ }
60
+
61
+ .solidgate-checkout-spinner {
62
+ box-sizing: border-box;
63
+ width: 44px;
64
+ height: 44px;
65
+ border: 4px solid var(--color-border, #d1d5db);
66
+ border-top-color: var(--color-primary, #22c55e);
67
+ border-radius: 50%;
68
+ animation: solidgate-checkout-spin 720ms linear infinite;
69
+ }
70
+
71
+ .solidgate-checkout-visually-hidden {
72
+ position: absolute;
73
+ width: 1px;
74
+ height: 1px;
75
+ overflow: hidden;
76
+ clip: rect(0 0 0 0);
77
+ clip-path: inset(50%);
78
+ white-space: nowrap;
79
+ }
80
+
81
+ @keyframes solidgate-checkout-spin {
82
+ to {
83
+ transform: rotate(360deg);
84
+ }
85
+ }
86
+
87
+ @media (prefers-reduced-motion: reduce) {
88
+ .solidgate-checkout-spinner {
89
+ animation-duration: 1.6s;
90
+ }
91
+ }
92
+
93
+ .solidgate-checkout-header {
94
+ position: relative;
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+ gap: 16px;
99
+ margin-bottom: 16px;
100
+ }
101
+
102
+ .solidgate-checkout-dialog.is-branded .solidgate-checkout-header {
103
+ min-height: 70px;
104
+ margin: 0 -17px;
105
+ padding: 0 56px;
106
+ }
107
+
108
+ .solidgate-checkout-title {
109
+ margin: 0;
110
+ color: var(--color-text, #111827);
111
+ font-size: 18px;
112
+ font-weight: 600;
113
+ line-height: 1.3;
114
+ }
115
+
116
+ .solidgate-checkout-dialog.is-branded .solidgate-checkout-title {
117
+ color: #020203;
118
+ font-size: 24px;
119
+ font-weight: 900;
120
+ line-height: 1.15;
121
+ text-align: center;
122
+ }
123
+
124
+ .solidgate-checkout-close {
125
+ position: absolute;
126
+ left: 0;
127
+ top: 50%;
128
+ width: 36px;
129
+ height: 36px;
130
+ flex: none;
131
+ border: 1px solid var(--color-border, #d1d5db);
132
+ border-radius: 8px;
133
+ background: var(--color-bg, #f9fafb);
134
+ color: var(--color-text, #111827);
135
+ font-size: 22px;
136
+ transform: translateY(-50%);
137
+ cursor: pointer;
138
+ }
139
+
140
+ .solidgate-checkout-dialog.is-branded .solidgate-checkout-close {
141
+ left: 16px;
142
+ width: 40px;
143
+ height: 40px;
144
+ border: 0;
145
+ border-radius: 999px;
146
+ background: #f2f2f3;
147
+ color: #aaa;
148
+ }
149
+
150
+ .solidgate-checkout-close span,
151
+ .solidgate-checkout-close span::after {
152
+ position: absolute;
153
+ left: 50%;
154
+ top: 50%;
155
+ width: 22px;
156
+ height: 3px;
157
+ border-radius: 999px;
158
+ background: currentColor;
159
+ content: '';
160
+ }
161
+
162
+ .solidgate-checkout-close span {
163
+ transform: translate(-50%, -50%) rotate(45deg);
164
+ }
165
+
166
+ .solidgate-checkout-close span::after {
167
+ transform: translate(-50%, -50%) rotate(90deg);
168
+ }
169
+
170
+ .solidgate-checkout-close:hover {
171
+ background: var(--color-accent-soft, #eef2ff);
172
+ }
173
+
174
+ .solidgate-checkout-summary {
175
+ color: #303136;
176
+ }
177
+
178
+ .solidgate-checkout-countdown {
179
+ min-height: 37px;
180
+ display: flex;
181
+ align-items: center;
182
+ justify-content: center;
183
+ margin: 0;
184
+ border-radius: 12px;
185
+ background: color-mix(in srgb, var(--solidgate-checkout-theme-color) 10%, #fff);
186
+ color: var(--solidgate-checkout-theme-color);
187
+ font-size: 16px;
188
+ font-weight: 900;
189
+ text-align: center;
190
+ }
191
+
192
+ .solidgate-checkout-satisfaction {
193
+ margin: 17px 0 21px;
194
+ color: #2f3034;
195
+ font-size: 19px;
196
+ font-weight: 800;
197
+ line-height: 1.15;
198
+ text-align: center;
199
+ }
200
+
201
+ .solidgate-checkout-satisfaction strong {
202
+ color: var(--solidgate-checkout-theme-color);
203
+ }
204
+
205
+ .solidgate-checkout-price-stack {
206
+ display: flex;
207
+ flex-direction: column;
208
+ gap: 8px;
209
+ }
210
+
211
+ .solidgate-checkout-price-row,
212
+ .solidgate-checkout-promo,
213
+ .solidgate-checkout-total {
214
+ display: flex;
215
+ align-items: center;
216
+ justify-content: space-between;
217
+ gap: 12px;
218
+ }
219
+
220
+ .solidgate-checkout-price-row {
221
+ font-size: 17px;
222
+ }
223
+
224
+ .solidgate-checkout-price-row.is-muted {
225
+ color: #9d9d9f;
226
+ font-weight: 500;
227
+ }
228
+
229
+ .solidgate-checkout-strike {
230
+ text-decoration: line-through 2px;
231
+ }
232
+
233
+ .solidgate-checkout-price-row.is-discount {
234
+ color: #040508;
235
+ font-weight: 900;
236
+ }
237
+
238
+ .solidgate-checkout-price-row.is-discount strong:last-child {
239
+ color: #ff2544;
240
+ }
241
+
242
+ .solidgate-checkout-promo {
243
+ min-height: 42px;
244
+ border-radius: 13px;
245
+ background: #f0f0f0;
246
+ padding: 0 14px;
247
+ color: #8d8d90;
248
+ font-size: 16px;
249
+ }
250
+
251
+ .solidgate-checkout-promo strong {
252
+ color: #050609;
253
+ font-weight: 900;
254
+ }
255
+
256
+ .solidgate-checkout-total {
257
+ min-height: 76px;
258
+ margin-top: 20px;
259
+ border-top: 1px solid #dedede;
260
+ font-size: 23px;
261
+ font-weight: 800;
262
+ }
263
+
264
+ .solidgate-checkout-total.is-plain {
265
+ margin-top: 0;
266
+ }
267
+
268
+ .solidgate-checkout-total strong {
269
+ font-size: 25px;
270
+ font-weight: 900;
271
+ }
272
+
273
+ .solidgate-checkout-saved {
274
+ width: fit-content;
275
+ min-height: 36px;
276
+ display: flex;
277
+ 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;
284
+ font-size: 14px;
285
+ font-weight: 800;
286
+ }
287
+
288
+ .solidgate-checkout-email-form,
289
+ .solidgate-checkout-email-label,
290
+ .solidgate-checkout-wallets {
291
+ display: grid;
292
+ }
293
+
294
+ .solidgate-checkout-email-form {
295
+ gap: 16px;
296
+ }
297
+
298
+ .solidgate-checkout-email-label {
299
+ gap: 8px;
300
+ color: var(--color-text, #111827);
301
+ font-size: 14px;
302
+ font-weight: 500;
303
+ }
304
+
305
+ .solidgate-checkout-email-input {
306
+ box-sizing: border-box;
307
+ width: 100%;
308
+ min-height: 44px;
309
+ border: 1px solid var(--color-border, #d1d5db);
310
+ border-radius: 8px;
311
+ background: var(--color-bg, #fff);
312
+ padding: 8px 12px;
313
+ color: var(--color-text, #111827);
314
+ font: inherit;
315
+ }
316
+
317
+ .solidgate-checkout-email-input::placeholder,
318
+ .solidgate-checkout-status,
319
+ .solidgate-checkout-status-text {
320
+ color: var(--color-text-muted, #6b7280);
321
+ }
322
+
323
+ .solidgate-checkout-email-input:focus-visible,
324
+ .solidgate-checkout-close:focus-visible,
325
+ .solidgate-checkout-action:focus-visible {
326
+ outline: 2px solid var(--color-accent, #3f51b5);
327
+ outline-offset: 2px;
328
+ }
329
+
330
+ .solidgate-checkout-alert {
331
+ margin: 0;
332
+ color: var(--color-danger, #b91c1c);
333
+ font-size: 14px;
334
+ }
335
+
336
+ .solidgate-checkout-action {
337
+ box-sizing: border-box;
338
+ width: 100%;
339
+ min-height: 44px;
340
+ border: 1px solid var(--color-accent, #3f51b5);
341
+ border-radius: 8px;
342
+ background: var(--color-accent, #3f51b5);
343
+ padding: 8px 16px;
344
+ color: var(--color-primary-text, #fff);
345
+ font: inherit;
346
+ font-weight: 600;
347
+ cursor: pointer;
348
+ }
349
+
350
+ .solidgate-checkout-action:disabled {
351
+ cursor: not-allowed;
352
+ opacity: 0.6;
353
+ }
354
+
355
+ .solidgate-checkout-action--spaced {
356
+ margin-top: 16px;
357
+ }
358
+
359
+ .solidgate-checkout-wallets {
360
+ gap: 12px;
361
+ margin-bottom: 12px;
362
+ }
363
+
364
+ .solidgate-checkout-dialog.is-branded .solidgate-checkout-wallets {
365
+ margin-top: 4px;
366
+ }
367
+
368
+ .solidgate-checkout-dialog.is-branded .solidgate-checkout-wallets > div:not(:empty) {
369
+ min-height: 48px;
370
+ }
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;
381
+ }
382
+
383
+ .solidgate-checkout-payment[hidden] {
384
+ display: none;
385
+ }
386
+
387
+ .solidgate-checkout-status {
388
+ margin-top: 12px;
389
+ border: 1px solid var(--color-border, #d1d5db);
390
+ border-radius: 12px;
391
+ background: var(--color-bg, #f9fafb);
392
+ padding: 16px;
393
+ font-size: 14px;
394
+ }
395
+
396
+ .solidgate-checkout-status p,
397
+ .solidgate-checkout-status-text {
398
+ margin: 0;
399
+ }
400
+ `;
@@ -0,0 +1,66 @@
1
+ import type { FunnelSdkRuntimeConfigOverrides, FunnelStepType, RuntimeMode } from '@funnelsgrove/runtime';
2
+ import type { PrepareSolidgateCheckoutInput, SolidgateCheckoutPreparation } from '../services/solidgate.service.js';
3
+ export type SolidgateCheckoutDialogState = 'collecting_email' | 'loading' | 'ready' | 'submitting' | 'verifying' | 'success' | 'recoverable_error' | 'expired';
4
+ export type SolidgateCheckoutDialogContent = {
5
+ title: string;
6
+ closeAriaLabel: string;
7
+ loading: string;
8
+ submitting: string;
9
+ verifying: string;
10
+ success: string;
11
+ error: string;
12
+ expired: string;
13
+ retry: string;
14
+ resumeVerification: string;
15
+ customerEmailLabel: string;
16
+ customerEmailPlaceholder: string;
17
+ customerEmailInvalid: string;
18
+ customerEmailUnavailable: string;
19
+ customerEmailContinue: string;
20
+ };
21
+ export type SolidgateCheckoutDialogPresentation = {
22
+ buttonColor: string;
23
+ cardSubmitLabel: string;
24
+ countdownLabel: string;
25
+ discountAmountLabel: string;
26
+ discountLabel: string;
27
+ discountPercent: number;
28
+ originalPriceLabel: string;
29
+ originalPriceValue: string;
30
+ promoActive: boolean;
31
+ promoCode: string;
32
+ promoCodeLabel: string;
33
+ remainingSeconds: number;
34
+ satisfactionLabel: string;
35
+ satisfactionPercent: string;
36
+ savedLabel: string;
37
+ secureLabel: string;
38
+ themeColor: string;
39
+ title: string;
40
+ totalLabel: string;
41
+ totalValue: string;
42
+ };
43
+ export type SolidgateCheckoutDialogProps = {
44
+ open: boolean;
45
+ request: Omit<PrepareSolidgateCheckoutInput, 'signal'>;
46
+ customerEmail?: string | null;
47
+ checkoutAnalytics?: SolidgateCheckoutAnalyticsContext | null;
48
+ content?: Partial<SolidgateCheckoutDialogContent>;
49
+ presentation?: SolidgateCheckoutDialogPresentation;
50
+ onClose: () => void;
51
+ onCustomerEmailCommit?: (email: string) => Promise<string>;
52
+ onSuccess?: (checkout: SolidgateCheckoutPreparation) => void | Promise<void>;
53
+ onRetry?: () => void;
54
+ onError?: (message: string) => void;
55
+ onStateChange?: (state: SolidgateCheckoutDialogState) => void;
56
+ };
57
+ export type SolidgateCheckoutAnalyticsContext = {
58
+ environment?: RuntimeMode;
59
+ featureFlags?: Record<string, string | null | undefined>;
60
+ metadata?: Record<string, unknown> | null;
61
+ runtimeConfig?: FunnelSdkRuntimeConfigOverrides;
62
+ stepId: string;
63
+ stepName: string;
64
+ stepType: Extract<FunnelStepType, 'checkout' | 'paywall_offer' | 'upsell_offer'>;
65
+ stepContractVersion: number;
66
+ };
@@ -0,0 +1,4 @@
1
+ import type { SolidgateCheckoutDialogPresentation } from './SolidgateCheckoutDialog.types.js';
2
+ export declare function SolidgateCheckoutSummary({ presentation }: {
3
+ presentation: SolidgateCheckoutDialogPresentation;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ const formatCountdown = (remainingSeconds) => {
3
+ const normalizedSeconds = Number.isFinite(remainingSeconds)
4
+ ? Math.max(0, Math.floor(remainingSeconds))
5
+ : 0;
6
+ const minutes = Math.floor(normalizedSeconds / 60);
7
+ const seconds = normalizedSeconds % 60;
8
+ return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
9
+ };
10
+ export function SolidgateCheckoutSummary({ presentation }) {
11
+ const showPromo = Boolean((presentation === null || presentation === void 0 ? void 0 : presentation.promoActive) &&
12
+ presentation.discountPercent > 0 &&
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] }));
15
+ }
@@ -0,0 +1,12 @@
1
+ import type { SolidgateCheckoutPreparation } from '../services/solidgate.service.js';
2
+ export declare function SolidgatePaymentForm({ buttonColor, cardSubmitLabel, checkout, hidden, loadingLabel, onError, onMounted, onSubmit, onVerify, }: {
3
+ buttonColor: string;
4
+ cardSubmitLabel: string;
5
+ checkout: SolidgateCheckoutPreparation;
6
+ hidden: boolean;
7
+ loadingLabel: string;
8
+ onError: () => void;
9
+ onMounted: () => void;
10
+ onSubmit: () => void;
11
+ onVerify: () => void;
12
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,114 @@
1
+ 'use client';
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);
24
+ const submittedRef = useRef(false);
25
+ const paymentBoundaryRef = useRef(null);
26
+ const mountedReportedRef = useRef(false);
27
+ const onMountedRef = useRef(onMounted);
28
+ const applePayContainerRef = useRef(null);
29
+ const googlePayContainerRef = useRef(null);
30
+ useEffect(() => {
31
+ onMountedRef.current = onMounted;
32
+ }, [onMounted]);
33
+ useEffect(() => {
34
+ mountedReportedRef.current = false;
35
+ const boundary = paymentBoundaryRef.current;
36
+ if (!boundary) {
37
+ return;
38
+ }
39
+ const reportIframeMounted = () => {
40
+ if (!mountedReportedRef.current
41
+ && boundary.querySelector('iframe#solid-payment-form-iframe, iframe[name="solid-payment-form-iframe"]')) {
42
+ mountedReportedRef.current = true;
43
+ onMountedRef.current();
44
+ }
45
+ };
46
+ reportIframeMounted();
47
+ const observer = new MutationObserver(reportIframeMounted);
48
+ observer.observe(boundary, { childList: true, subtree: true });
49
+ return () => observer.disconnect();
50
+ }, [checkout.attemptId]);
51
+ useEffect(() => {
52
+ submittedRef.current = false;
53
+ return () => {
54
+ safeDestroyPaymentForm(instanceRef.current);
55
+ instanceRef.current = null;
56
+ };
57
+ }, [checkout.attemptId]);
58
+ 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: {
64
+ form_body: {
65
+ 'font-family': 'Inter, Arial, sans-serif',
66
+ },
67
+ input_group: {
68
+ input: {
69
+ 'border-color': '#d8d9dd',
70
+ 'border-radius': '10px',
71
+ },
72
+ },
73
+ submit_button: {
74
+ 'background-color': buttonColor,
75
+ 'border-radius': '10px',
76
+ 'font-size': '16px',
77
+ 'font-weight': '800',
78
+ height: '52px',
79
+ },
80
+ }, applePayButtonParams: {
81
+ color: 'black',
82
+ enabled: true,
83
+ integrationType: 'js',
84
+ type: walletButtonType,
85
+ }, googlePayButtonParams: {
86
+ color: 'black',
87
+ enabled: true,
88
+ 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: () => {
100
+ if (!mountedReportedRef.current) {
101
+ mountedReportedRef.current = true;
102
+ onMountedRef.current();
103
+ }
104
+ }, onSubmit: () => {
105
+ submittedRef.current = true;
106
+ onSubmit();
107
+ }, onVerify: onVerify, onSuccess: onVerify, onFail: onVerify, onError: () => {
108
+ if (submittedRef.current) {
109
+ onVerify();
110
+ return;
111
+ }
112
+ onError();
113
+ } }, checkout.attemptId) })] }));
114
+ }
@@ -110,7 +110,7 @@ const parseStatus = (value) => {
110
110
  };
111
111
  };
112
112
  export const prepareSolidgateCheckout = async (input) => {
113
- var _a, _b, _c, _d;
113
+ var _a, _b, _c, _d, _e;
114
114
  const useV2 = ((_a = input.runtimeConfig) === null || _a === void 0 ? void 0 : _a.paymentsApiVersion) === 'v2';
115
115
  const paymentProfileId = ((_b = input.paymentProfileId) === null || _b === void 0 ? void 0 : _b.trim()) || null;
116
116
  const providerPlanId = ((_c = input.providerPlanId) === null || _c === void 0 ? void 0 : _c.trim()) || null;
@@ -121,7 +121,7 @@ export const prepareSolidgateCheckout = async (input) => {
121
121
  }
122
122
  return parsePreparation(await postJson(useV2
123
123
  ? '/sdk/public/v2/payments/checkout-sessions'
124
- : '/sdk/public/payments/solidgate/checkout', Object.assign(Object.assign({}, (useV2 ? {
124
+ : '/sdk/public/payments/solidgate/checkout', Object.assign(Object.assign(Object.assign(Object.assign({}, (useV2 ? {
125
125
  checkoutType,
126
126
  uiMode: 'custom',
127
127
  environment,
@@ -129,7 +129,9 @@ export const prepareSolidgateCheckout = async (input) => {
129
129
  provider: 'solidgate',
130
130
  providerPlanId,
131
131
  planKey: requiredString(input.funnelPlanKey, 'funnelPlanKey'),
132
- } : {})), { funnelId: resolveFunnelId(input.funnelId, input.runtimeConfig), funnelEndUserId: requiredString(input.funnelEndUserId, 'funnelEndUserId'), offerSetId: requiredString(input.offerSetId, 'offerSetId'), funnelPlanKey: requiredString(input.funnelPlanKey, 'funnelPlanKey'), idempotencyKey: requiredString(input.idempotencyKey, 'idempotencyKey'), discountKeyOrProviderId: ((_d = input.discountKeyOrProviderId) === null || _d === void 0 ? void 0 : _d.trim()) || null, returnUrl: requiredString(input.returnUrl, 'returnUrl'), successUrl: requiredString(input.successUrl, 'successUrl'), failUrl: requiredString(input.failUrl, 'failUrl') }), input.runtimeConfig, input.signal));
132
+ } : {})), { funnelId: resolveFunnelId(input.funnelId, input.runtimeConfig), funnelEndUserId: requiredString(input.funnelEndUserId, 'funnelEndUserId'), offerSetId: requiredString(input.offerSetId, 'offerSetId'), funnelPlanKey: requiredString(input.funnelPlanKey, 'funnelPlanKey'), idempotencyKey: requiredString(input.idempotencyKey, 'idempotencyKey') }), (useV2
133
+ ? { couponId: ((_d = input.discountKeyOrProviderId) === null || _d === void 0 ? void 0 : _d.trim()) || null }
134
+ : { discountKeyOrProviderId: ((_e = input.discountKeyOrProviderId) === null || _e === void 0 ? void 0 : _e.trim()) || null })), { returnUrl: requiredString(input.returnUrl, 'returnUrl'), successUrl: requiredString(input.successUrl, 'successUrl'), failUrl: requiredString(input.failUrl, 'failUrl') }), input.runtimeConfig, input.signal));
133
135
  };
134
136
  export const retrieveSolidgateCheckoutStatus = async (input) => {
135
137
  var _a;
@@ -1,5 +1,8 @@
1
1
  import type { AvailablePaymentMethods, StripeCheckoutExpressCheckoutElementOptions } from '@stripe/stripe-js';
2
2
  import { type StripeSubscriptionCheckoutAnalyticsContext } from '../services/checkoutCompletionAnalytics.service.js';
3
+ export type StripeWalletCheckoutSuccess = {
4
+ checkoutSessionId: string | null;
5
+ };
3
6
  export type StripeCheckoutExpressCheckoutButtonProps = {
4
7
  amountCents: number;
5
8
  beforeConfirm?: () => Promise<string | null>;
@@ -27,7 +30,7 @@ export type StripeCheckoutExpressCheckoutButtonProps = {
27
30
  message: string;
28
31
  paymentMethod?: string;
29
32
  }) => void;
30
- onSuccess?: () => void | Promise<void>;
33
+ onSuccess?: (result: StripeWalletCheckoutSuccess) => void | Promise<void>;
31
34
  unsupportedCountryMessage?: string;
32
35
  };
33
36
  export declare function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAnalytics, checkoutSessionId, returnUrl, confirmEmail, customerEmail, className, options, availabilityPaymentMethods, initialAvailable, keepInitialAvailableOnReady, serverUpdateKey, supportedCountries, onServerUpdate, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onPaymentRejected, onSuccess, unsupportedCountryMessage, }: StripeCheckoutExpressCheckoutButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -154,7 +154,7 @@ export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAna
154
154
  if (checkoutAnalytics) {
155
155
  await trackPaidStripeSubscriptionCheckoutCompleted(Object.assign({ checkoutSessionId }, checkoutAnalytics));
156
156
  }
157
- await (onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess());
157
+ await (onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess({ checkoutSessionId: checkoutSessionId !== null && checkoutSessionId !== void 0 ? checkoutSessionId : null }));
158
158
  };
159
159
  const queueCheckoutStarted = (paymentMethod, checkoutStartSource = 'wallet_click') => {
160
160
  if (!checkoutAnalytics) {
@@ -1,3 +1,4 @@
1
+ import type { StripeWalletCheckoutSuccess } from './StripeCheckoutExpressCheckoutButton.js';
1
2
  import { type ReactNode } from 'react';
2
3
  import type { Appearance, StripeCheckoutExpressCheckoutElementOptions } from '@stripe/stripe-js';
3
4
  import { type PlatformWalletPaymentMethod } from './walletPlatform.js';
@@ -64,7 +65,7 @@ export type StripeWalletSurfaceProps = {
64
65
  onCancel?: () => void;
65
66
  onError?: (message: string | null, context: StripeWalletSurfaceErrorContext) => void;
66
67
  onPaymentInfoSubmitted?: () => void | Promise<void>;
67
- onSuccess?: () => void | Promise<void>;
68
+ onSuccess?: (result: StripeWalletCheckoutSuccess) => void | Promise<void>;
68
69
  onUnavailableClick?: () => Promise<void> | void;
69
70
  paymentMethods?: readonly PlatformWalletPaymentMethod[];
70
71
  renderHeader?: (props: {