@funnelsgrove/payments 0.15.6 → 0.15.8

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.
Files changed (25) hide show
  1. package/README.md +20 -1
  2. package/dist/components/CheckoutEmailDialog.d.ts +15 -0
  3. package/dist/components/CheckoutEmailDialog.js +66 -0
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.js +2 -0
  6. package/dist/providers/stripe/components/SharedStripeCheckoutV2.styles.d.ts +1 -0
  7. package/dist/providers/stripe/components/SharedStripeCheckoutV2.styles.js +781 -0
  8. package/dist/providers/stripe/components/SharedStripeCheckoutV2Dialog.d.ts +5 -0
  9. package/dist/providers/stripe/components/SharedStripeCheckoutV2Dialog.js +8 -1092
  10. package/dist/providers/stripe/components/SharedStripeCheckoutV2Form.internal.d.ts +7 -0
  11. package/dist/providers/stripe/components/SharedStripeCheckoutV2Form.internal.js +272 -0
  12. package/dist/providers/stripe/components/SharedStripeCheckoutV2Summary.internal.d.ts +6 -0
  13. package/dist/providers/stripe/components/SharedStripeCheckoutV2Summary.internal.js +19 -0
  14. package/dist/providers/stripe/components/StripeCheckoutExpressCheckoutButton.js +10 -3
  15. package/dist/providers/stripe/components/StripeWalletSurface.internal.d.ts +5 -1
  16. package/dist/providers/stripe/components/StripeWalletSurface.internal.js +53 -4
  17. package/dist/providers/stripe/components/useCheckoutEmail.internal.d.ts +20 -0
  18. package/dist/providers/stripe/components/useCheckoutEmail.internal.js +74 -0
  19. package/dist/providers/stripe/services/checkoutCompletionAnalytics.service.d.ts +3 -1
  20. package/dist/providers/stripe/services/checkoutCompletionAnalytics.service.js +39 -1
  21. package/dist/providers/stripe/services/oneClick/completePayment.js +9 -4
  22. package/dist/providers/stripe/services/oneClick/types.d.ts +2 -0
  23. package/dist/services/checkoutEmail.d.ts +3 -0
  24. package/dist/services/checkoutEmail.js +20 -0
  25. package/package.json +2 -2
@@ -0,0 +1,7 @@
1
+ import type { SharedStripeCheckoutV2DialogProps } from './SharedStripeCheckoutV2Dialog.js';
2
+ export declare const getFixedSupportedBillingCountry: (supportedCountries: readonly string[]) => string | null;
3
+ type SharedStripeCheckoutV2FormProps = Omit<SharedStripeCheckoutV2DialogProps, 'stripePromise' | 'onClose'> & {
4
+ onClose: () => void;
5
+ };
6
+ export declare function SharedStripeCheckoutV2CheckoutSessionForm({ 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, }: SharedStripeCheckoutV2FormProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,272 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useMemo, useRef, useState } from 'react';
4
+ import { PaymentElement, useCheckout } from '@stripe/react-stripe-js/checkout';
5
+ import { isValidCheckoutEmail as isValidEmail, isCheckoutEmailError } from '../../../services/checkoutEmail.js';
6
+ import { PaymentBrandMark, SecurityLockIcon } from './CheckoutBrandAssets.js';
7
+ import { StripeCheckoutExpressCheckoutButton } from './StripeCheckoutExpressCheckoutButton.js';
8
+ import { getUnsupportedCheckoutCountryMessage, normalizeSupportedCheckoutCountries } from './checkoutCountries.js';
9
+ import { isInactiveCheckoutSessionError } from '../hooks/useStripeSubscriptionCheckoutSession.js';
10
+ import { getStripeWalletPaymentMethodOrder, usePlatformWalletPaymentMethods } from './walletPlatform.js';
11
+ import { trackPaidStripeSubscriptionCheckoutCompleted, trackStripeSubscriptionPaymentInfoSubmitted } from '../services/checkoutCompletionAnalytics.service.js';
12
+ import { trackCheckoutFailureShown } from '../../../services/checkoutObservability.service.js';
13
+ import { SharedStripeCheckoutV2Summary } from './SharedStripeCheckoutV2Summary.internal.js';
14
+ import { useCheckoutEmail } from './useCheckoutEmail.internal.js';
15
+ const defaultPaymentMethodLabels = ['Visa', 'Mastercard', 'Maestro', 'Discover'];
16
+ export const getFixedSupportedBillingCountry = (supportedCountries) => supportedCountries.length === 1 ? supportedCountries[0] : null;
17
+ const checkoutCountryLabels = {
18
+ US: 'United States',
19
+ };
20
+ const getCheckoutCountryLabel = (countryCode) => { var _a; return (_a = checkoutCountryLabels[countryCode]) !== null && _a !== void 0 ? _a : countryCode; };
21
+ function getFriendlyCardErrorMessage(error) {
22
+ return error instanceof Error && error.message
23
+ ? error.message
24
+ : 'Payment failed. Please review your card details and try again.';
25
+ }
26
+ export function SharedStripeCheckoutV2CheckoutSessionForm({ 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', }) {
27
+ const checkoutState = useCheckout();
28
+ const walletPaymentMethods = usePlatformWalletPaymentMethods();
29
+ const [selectedMethod, setSelectedMethod] = useState('wallet');
30
+ const [walletAvailable, setWalletAvailable] = useState(initialWalletAvailable !== null && initialWalletAvailable !== void 0 ? initialWalletAvailable : null);
31
+ const effectiveWalletAvailable = initialWalletAvailable === true && walletAvailable !== false
32
+ ? true
33
+ : walletAvailable;
34
+ const [submitting, setSubmitting] = useState(false);
35
+ const submitInFlightRef = useRef(false);
36
+ const [paymentElementReady, setPaymentElementReady] = useState(false);
37
+ const [paymentElementComplete, setPaymentElementComplete] = useState(false);
38
+ const [error, setError] = useState(null);
39
+ const [billingCountry, setBillingCountry] = useState(null);
40
+ const { initialCustomerEmail, resolvedCustomerEmail, customerEmailEditable, emailDraft, setEmailDraft, rejectedEmail, setRejectedEmail, emailSaving, emailSessionChanged, commitEmailDraftIfValid, ensureCustomerEmail } = useCheckoutEmail({
41
+ customerEmail, allowEmailEditing, customerEmailInvalidMessage,
42
+ onCustomerEmailCommit, onCustomerEmailChange, onError: (message) => setSharedError(message),
43
+ });
44
+ const normalizedSupportedCountries = useMemo(() => normalizeSupportedCheckoutCountries(supportedCountries), [supportedCountries]);
45
+ const fixedBillingCountry = getFixedSupportedBillingCountry(normalizedSupportedCountries);
46
+ const fixedBillingCountryLabel = fixedBillingCountry
47
+ ? getCheckoutCountryLabel(fixedBillingCountry)
48
+ : null;
49
+ const cardBrandLabels = useMemo(() => paymentMethodLabels.length > 0 ? paymentMethodLabels : defaultPaymentMethodLabels, [paymentMethodLabels]);
50
+ const normalizedPromoCode = promoCode.trim();
51
+ const showPromo = promoActive !== null && promoActive !== void 0 ? promoActive : (discountPercent > 0 && normalizedPromoCode.length > 0);
52
+ const emailFieldClassName = [
53
+ 'shared-checkout-v2-email-field',
54
+ customerEmailEditable ? '' : 'is-disabled',
55
+ ]
56
+ .filter(Boolean)
57
+ .join(' ');
58
+ const checkoutStyle = {
59
+ '--shared-checkout-v2-theme-color': themeColor,
60
+ '--shared-checkout-v2-button-color': buttonColor,
61
+ };
62
+ const expressCheckoutSummaryLabel = (summaryLabel === null || summaryLabel === void 0 ? void 0 : summaryLabel.trim()) || discountLabel || title;
63
+ const walletAriaLabel = walletPaymentMethods
64
+ .map((method) => method === 'applePay' ? walletButtonLabel : 'Google Pay')
65
+ .join(' / ');
66
+ const showWalletMethod = effectiveWalletAvailable !== false && walletPaymentMethods.length > 0;
67
+ const effectiveSelectedMethod = showWalletMethod && selectedMethod === 'wallet'
68
+ && !emailSessionChanged && isValidEmail(initialCustomerEmail) && rejectedEmail === null
69
+ && resolvedCustomerEmail === initialCustomerEmail ? 'wallet' : 'card';
70
+ const expressCheckoutOptions = useMemo(() => {
71
+ return {
72
+ buttonHeight: 55,
73
+ buttonTheme: {
74
+ applePay: 'black',
75
+ googlePay: 'black',
76
+ },
77
+ buttonType: {
78
+ applePay: 'subscribe',
79
+ googlePay: 'subscribe',
80
+ },
81
+ layout: {
82
+ maxColumns: 1,
83
+ maxRows: 2,
84
+ overflow: 'auto',
85
+ },
86
+ paymentMethodOrder: getStripeWalletPaymentMethodOrder(walletPaymentMethods),
87
+ paymentMethods: {
88
+ amazonPay: 'never',
89
+ applePay: walletPaymentMethods.includes('applePay') ? 'always' : 'never',
90
+ googlePay: walletPaymentMethods.includes('googlePay') ? 'always' : 'never',
91
+ klarna: 'never',
92
+ link: 'never',
93
+ paypal: 'never',
94
+ },
95
+ };
96
+ }, [walletPaymentMethods]);
97
+ const paymentElementOptions = useMemo(() => {
98
+ return {
99
+ fields: {
100
+ billingDetails: {
101
+ name: 'never',
102
+ email: 'never',
103
+ address: {
104
+ country: fixedBillingCountry ? 'never' : 'auto',
105
+ },
106
+ },
107
+ },
108
+ layout: 'tabs',
109
+ wallets: {
110
+ applePay: 'never',
111
+ googlePay: 'never',
112
+ link: 'never',
113
+ },
114
+ };
115
+ }, [fixedBillingCountry]);
116
+ const handleInactiveCheckoutSession = () => {
117
+ setError(null);
118
+ onInactiveCheckoutSession === null || onInactiveCheckoutSession === void 0 ? void 0 : onInactiveCheckoutSession();
119
+ };
120
+ const setSharedError = (message, alreadyTracked = false, providerError) => {
121
+ if (isCheckoutEmailError(providerError) || isCheckoutEmailError(message)) {
122
+ setRejectedEmail(initialCustomerEmail);
123
+ setSelectedMethod('card');
124
+ }
125
+ if (isInactiveCheckoutSessionError(message)) {
126
+ handleInactiveCheckoutSession();
127
+ return;
128
+ }
129
+ if (message && checkoutAnalytics && !alreadyTracked) {
130
+ trackCheckoutFailureShown({
131
+ analytics: checkoutAnalytics,
132
+ checkoutSessionId,
133
+ errorMessage: message,
134
+ failureStage: 'card_form',
135
+ paymentMethod: 'card',
136
+ provider: 'stripe',
137
+ providerDeclineCode: providerError === null || providerError === void 0 ? void 0 : providerError.decline_code,
138
+ providerErrorCode: providerError === null || providerError === void 0 ? void 0 : providerError.code,
139
+ providerErrorType: providerError === null || providerError === void 0 ? void 0 : providerError.type,
140
+ });
141
+ }
142
+ setError(message);
143
+ onError === null || onError === void 0 ? void 0 : onError(message);
144
+ };
145
+ const selectWalletMethod = () => {
146
+ if (showWalletMethod) {
147
+ setSelectedMethod('wallet');
148
+ }
149
+ };
150
+ const selectCardMethod = () => setSelectedMethod('card');
151
+ const handleWalletAvailabilityChange = (available) => {
152
+ setWalletAvailable(available);
153
+ if (!available && selectedMethod === 'wallet') {
154
+ setSelectedMethod('card');
155
+ }
156
+ };
157
+ const getBillingCountryError = (country) => getUnsupportedCheckoutCountryMessage({
158
+ billingCountry: country,
159
+ message: unsupportedCountryMessage,
160
+ supportedCountries: normalizedSupportedCountries,
161
+ });
162
+ const handlePaymentElementChange = (event) => {
163
+ var _a, _b;
164
+ setPaymentElementComplete(event.complete);
165
+ setBillingCountry((_b = (_a = event.value.billingDetails) === null || _a === void 0 ? void 0 : _a.address.country) !== null && _b !== void 0 ? _b : fixedBillingCountry);
166
+ };
167
+ const trackCheckoutSuccess = async () => {
168
+ if (checkoutAnalytics) {
169
+ await trackPaidStripeSubscriptionCheckoutCompleted(Object.assign({ checkoutSessionId }, checkoutAnalytics));
170
+ }
171
+ await (onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess());
172
+ };
173
+ const trackPaymentInfoSubmitted = async () => {
174
+ if (checkoutAnalytics) {
175
+ await trackStripeSubscriptionPaymentInfoSubmitted(Object.assign({ checkoutSessionId }, checkoutAnalytics)).catch(() => 'analytics_rejected');
176
+ }
177
+ await (onPaymentInfoSubmitted === null || onPaymentInfoSubmitted === void 0 ? void 0 : onPaymentInfoSubmitted());
178
+ };
179
+ useEffect(() => {
180
+ if (effectiveSelectedMethod !== 'card' || typeof window === 'undefined') {
181
+ return;
182
+ }
183
+ const resizeTimer = window.setTimeout(() => {
184
+ window.dispatchEvent(new Event('resize'));
185
+ }, 0);
186
+ return () => window.clearTimeout(resizeTimer);
187
+ }, [effectiveSelectedMethod]);
188
+ const handleSubmit = async (event) => {
189
+ event.preventDefault();
190
+ if (submitInFlightRef.current || emailSessionChanged) {
191
+ return;
192
+ }
193
+ const billingCountryError = getBillingCountryError(billingCountry !== null && billingCountry !== void 0 ? billingCountry : fixedBillingCountry);
194
+ if (billingCountryError) {
195
+ setSharedError(billingCountryError);
196
+ return;
197
+ }
198
+ if (checkoutState.type !== 'success') {
199
+ setSharedError(checkoutState.type === 'error'
200
+ ? checkoutState.error.message
201
+ : 'Payment form is not ready yet.');
202
+ return;
203
+ }
204
+ if (!paymentElementReady) {
205
+ setSharedError('Payment form is not ready yet.', true);
206
+ return;
207
+ }
208
+ submitInFlightRef.current = true;
209
+ setSubmitting(true);
210
+ setSharedError(null);
211
+ const finishSubmitting = () => {
212
+ submitInFlightRef.current = false;
213
+ setSubmitting(false);
214
+ };
215
+ try {
216
+ const syncedEmail = await ensureCustomerEmail();
217
+ if (!syncedEmail) {
218
+ finishSubmitting();
219
+ return;
220
+ }
221
+ if (paymentElementComplete) {
222
+ await trackPaymentInfoSubmitted();
223
+ }
224
+ const result = await checkoutState.checkout.confirm({
225
+ redirect: 'if_required',
226
+ });
227
+ if (result.type === 'error') {
228
+ const message = result.error.message || 'Payment failed.';
229
+ setSharedError(message, false, result.error);
230
+ finishSubmitting();
231
+ return;
232
+ }
233
+ if (typeof window !== 'undefined') {
234
+ await trackCheckoutSuccess();
235
+ window.location.assign(returnUrl);
236
+ return;
237
+ }
238
+ finishSubmitting();
239
+ }
240
+ catch (submitError) {
241
+ setSharedError(getFriendlyCardErrorMessage(submitError));
242
+ finishSubmitting();
243
+ }
244
+ };
245
+ const visibleError = error;
246
+ return (_jsxs("div", { className: 'shared-checkout-v2-shell', "data-variant": variant, style: checkoutStyle, children: [_jsxs("header", { className: 'shared-checkout-v2-header', children: [_jsx("button", { type: 'button', className: 'shared-checkout-v2-close', onClick: onClose, "aria-label": closeAriaLabel, children: _jsx("span", { "aria-hidden": 'true' }) }), _jsx("h2", { id: 'shared-checkout-v2-title', children: title })] }), _jsx(SharedStripeCheckoutV2Summary, { discountPercent, countdownLabel, remainingSeconds, variant, satisfactionPercent, satisfactionLabel, originalPriceLabel, originalPriceValue, discountLabel, discountAmountLabel, promoCodeLabel, promoCode, totalLabel, totalValue, savedLabel, showPromo }), _jsxs("form", { className: 'shared-checkout-v2-payment', onSubmit: (event) => void handleSubmit(event), children: [showWalletMethod ? (_jsxs("div", { className: 'shared-checkout-v2-methods', role: 'tablist', "aria-label": 'Payment method', children: [_jsxs("button", { type: 'button', className: [
247
+ 'shared-checkout-v2-method',
248
+ effectiveSelectedMethod === 'wallet' ? 'is-selected' : '',
249
+ ]
250
+ .filter(Boolean)
251
+ .join(' '), onClick: selectWalletMethod, role: 'tab', "aria-selected": effectiveSelectedMethod === 'wallet', children: [_jsxs("span", { className: 'shared-checkout-v2-tab-wallets', "aria-hidden": 'true', children: [walletPaymentMethods.includes('applePay') ? (_jsx(PaymentBrandMark, { label: 'Apple Pay', className: 'shared-checkout-v2-tab-wallet' })) : null, walletPaymentMethods.includes('googlePay') ? (_jsx(PaymentBrandMark, { label: 'Google Pay', className: 'shared-checkout-v2-tab-wallet' })) : null] }), _jsx("span", { className: 'shared-checkout-v2-sr-only', children: walletAriaLabel })] }), _jsxs("button", { type: 'button', className: [
252
+ 'shared-checkout-v2-method',
253
+ effectiveSelectedMethod === 'card' ? 'is-selected' : '',
254
+ ]
255
+ .filter(Boolean)
256
+ .join(' '), onClick: selectCardMethod, role: 'tab', "aria-selected": effectiveSelectedMethod === 'card', children: [_jsx("strong", { children: "Credit card" }), _jsx("span", { className: 'shared-checkout-v2-tab-brands', "aria-hidden": 'true', children: cardBrandLabels.slice(0, 4).map((label) => (_jsx(PaymentBrandMark, { label: label, className: 'shared-checkout-v2-tab-brand' }, label))) })] })] })) : null, _jsxs("div", { hidden: effectiveSelectedMethod !== 'wallet', className: [
257
+ 'shared-checkout-v2-wallet-panel',
258
+ effectiveSelectedMethod === 'wallet' ? 'is-visible' : '',
259
+ ]
260
+ .filter(Boolean)
261
+ .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, options: expressCheckoutOptions, returnUrl: returnUrl, summaryLabel: expressCheckoutSummaryLabel, supportedCountries: normalizedSupportedCountries, unsupportedCountryMessage: unsupportedCountryMessage }), _jsx("span", { className: 'shared-checkout-v2-sr-only', children: walletAriaLabel })] })] }), _jsxs("div", { hidden: effectiveSelectedMethod !== 'card', className: [
262
+ 'shared-checkout-v2-card-panel',
263
+ effectiveSelectedMethod === 'card' ? 'is-visible' : '',
264
+ ]
265
+ .filter(Boolean)
266
+ .join(' '), children: [_jsxs("div", { className: 'shared-checkout-v2-card-box', children: [_jsxs("label", { className: emailFieldClassName, children: [_jsx("span", { className: 'shared-checkout-v2-email-label', children: customerEmailLabel }), _jsx("span", { className: 'shared-checkout-v2-email-control', children: _jsx("input", { type: 'email', autoComplete: 'email', className: 'shared-checkout-v2-email-input', disabled: !customerEmailEditable || emailSaving, inputMode: 'email', readOnly: !customerEmailEditable, value: customerEmailEditable ? emailDraft : initialCustomerEmail, placeholder: customerEmailPlaceholder, onBlur: (event) => commitEmailDraftIfValid(event.currentTarget.value), onChange: (event) => {
267
+ if (!customerEmailEditable) {
268
+ return;
269
+ }
270
+ setEmailDraft(event.target.value);
271
+ } }) })] }), _jsx(PaymentElement, { options: paymentElementOptions, onChange: handlePaymentElementChange, onReady: () => setPaymentElementReady(true) }), fixedBillingCountry && fixedBillingCountryLabel ? (_jsxs("label", { className: 'shared-checkout-v2-country-field', children: [_jsx("span", { className: 'shared-checkout-v2-country-label', children: "Country" }), _jsx("span", { className: 'shared-checkout-v2-country-control', children: _jsx("select", { "aria-label": 'Country', className: 'shared-checkout-v2-country-select', value: fixedBillingCountry, onChange: () => setBillingCountry(fixedBillingCountry), children: _jsx("option", { value: fixedBillingCountry, children: fixedBillingCountryLabel }) }) })] })) : null] }), visibleError ? _jsx("p", { className: 'shared-checkout-v2-error', children: visibleError }) : null, _jsxs("button", { type: 'submit', className: 'shared-checkout-v2-card-submit', disabled: submitting || emailSaving || emailSessionChanged || !paymentElementReady, children: [_jsx(SecurityLockIcon, { className: 'shared-checkout-v2-card-submit-icon' }), submitting || emailSaving || emailSessionChanged ? processingLabel : cardSubmitLabel] }), _jsx("div", { className: 'shared-checkout-v2-card-brands', "aria-hidden": 'true', children: cardBrandLabels.map((label) => (_jsx(PaymentBrandMark, { label: label, className: 'shared-checkout-v2-card-brand' }, label))) }), _jsxs("p", { className: 'shared-checkout-v2-secure-pill shared-checkout-v2-secure-pill--card', children: [_jsx(SecurityLockIcon, { className: 'shared-checkout-v2-secure-pill-icon' }), secureLabel] })] })] })] }));
272
+ }
@@ -0,0 +1,6 @@
1
+ import type { SharedStripeCheckoutV2DialogProps } from './SharedStripeCheckoutV2Dialog.js';
2
+ type SummaryProps = Pick<SharedStripeCheckoutV2DialogProps, 'discountPercent' | 'countdownLabel' | 'remainingSeconds' | 'variant' | 'satisfactionPercent' | 'satisfactionLabel' | 'originalPriceLabel' | 'originalPriceValue' | 'discountLabel' | 'discountAmountLabel' | 'promoCodeLabel' | 'promoCode' | 'totalLabel' | 'totalValue' | 'savedLabel'> & {
3
+ showPromo: boolean;
4
+ };
5
+ export declare function SharedStripeCheckoutV2Summary({ discountPercent, countdownLabel, remainingSeconds, variant, satisfactionPercent, satisfactionLabel, originalPriceLabel, originalPriceValue, discountLabel, discountAmountLabel, promoCodeLabel, promoCode, totalLabel, totalValue, savedLabel, showPromo }: SummaryProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,19 @@
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 SharedStripeCheckoutV2Summary({ discountPercent, countdownLabel, remainingSeconds, variant, satisfactionPercent, satisfactionLabel, originalPriceLabel, originalPriceValue, discountLabel, discountAmountLabel, promoCodeLabel, promoCode, totalLabel, totalValue, savedLabel, showPromo }) {
11
+ const countdownValue = formatCountdown(remainingSeconds);
12
+ const normalizedPromoCode = promoCode.trim();
13
+ return (_jsxs("section", { className: 'shared-checkout-v2-summary', children: [showPromo ? (_jsxs("p", { className: 'shared-checkout-v2-countdown', children: [discountPercent, "% ", countdownLabel, " ", countdownValue, " min"] })) : null, variant === 'standard' ? (_jsxs("p", { className: 'shared-checkout-v2-satisfaction', children: [_jsx("strong", { children: satisfactionPercent }), " ", satisfactionLabel] })) : null, showPromo ? (_jsxs("div", { className: 'shared-checkout-v2-price-stack', children: [_jsxs("div", { className: 'shared-checkout-v2-price-row is-muted', children: [_jsx("span", { children: originalPriceLabel }), _jsx("span", { className: 'shared-checkout-v2-strike', children: originalPriceValue })] }), _jsxs("div", { className: 'shared-checkout-v2-price-row is-discount', children: [_jsx("strong", { children: discountLabel }), _jsx("strong", { children: discountAmountLabel })] }), _jsxs("div", { className: 'shared-checkout-v2-promo', children: [_jsx("span", { children: promoCodeLabel }), _jsx("strong", { children: normalizedPromoCode })] })] })) : null, _jsxs("div", { className: [
14
+ 'shared-checkout-v2-total',
15
+ showPromo ? '' : 'is-plain',
16
+ ]
17
+ .filter(Boolean)
18
+ .join(' '), children: [_jsx("span", { children: totalLabel }), _jsxs("strong", { children: [_jsx("svg", { viewBox: '0 0 24 24', "aria-hidden": 'true', children: _jsx("path", { d: 'M20.6 13.4 12.4 21.6a2.2 2.2 0 0 1-3.1 0L2.4 14.7a2.2 2.2 0 0 1-.6-1.6V5.4a2 2 0 0 1 2-2h7.7a2.2 2.2 0 0 1 1.6.6l7.5 7.5a1.4 1.4 0 0 1 0 1.9ZM7.2 8.1a1.2 1.2 0 1 0 0-2.4 1.2 1.2 0 0 0 0 2.4Z' }) }), totalValue] })] }), showPromo ? (_jsxs("p", { className: 'shared-checkout-v2-saved', children: [_jsx("span", { "aria-hidden": 'true', children: "\uD83D\uDD25" }), savedLabel] })) : null] }));
19
+ }
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { isValidCheckoutEmail, isCheckoutEmailError } from '../../../services/checkoutEmail.js';
3
4
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
5
  import { ExpressCheckoutElement, useCheckout, } from '@stripe/react-stripe-js/checkout';
5
6
  import { queueStripeSubscriptionCheckoutStarted, trackPaidStripeSubscriptionCheckoutCompleted, trackStripeSubscriptionPaymentInfoSubmitted, } from '../services/checkoutCompletionAnalytics.service.js';
@@ -188,7 +189,7 @@ export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAna
188
189
  providerErrorType: providerError === null || providerError === void 0 ? void 0 : providerError.type,
189
190
  });
190
191
  }
191
- onError === null || onError === void 0 ? void 0 : onError(message);
192
+ onError === null || onError === void 0 ? void 0 : onError(isCheckoutEmailError(providerError) ? 'Enter a valid email address to continue.' : message);
192
193
  };
193
194
  const handleConfirm = async (event) => {
194
195
  var _a, _b, _c, _d, _e, _f;
@@ -235,8 +236,8 @@ export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAna
235
236
  return;
236
237
  }
237
238
  }
238
- if (beforeConfirm && !preparedCustomerEmail) {
239
- const message = 'Email is required to continue.';
239
+ if (!isValidCheckoutEmail(preparedCustomerEmail)) {
240
+ const message = 'Enter a valid email address to continue.';
240
241
  if (checkoutAnalytics) {
241
242
  trackCheckoutCanceled({
242
243
  analytics: checkoutAnalytics,
@@ -250,6 +251,12 @@ export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAna
250
251
  event.paymentFailed({ reason: 'invalid_payment_data', message });
251
252
  return;
252
253
  }
254
+ if ((preparedCustomerEmail === null || preparedCustomerEmail === void 0 ? void 0 : preparedCustomerEmail.trim()) !== (customerEmail === null || customerEmail === void 0 ? void 0 : customerEmail.trim())) {
255
+ const message = 'Your email was updated. Please select your payment method again.';
256
+ event.paymentFailed({ reason: 'invalid_payment_data', message });
257
+ onError === null || onError === void 0 ? void 0 : onError(message);
258
+ return;
259
+ }
253
260
  if (checkoutAnalytics) {
254
261
  await trackStripeSubscriptionPaymentInfoSubmitted(Object.assign({ checkoutSessionId }, checkoutAnalytics)).catch(() => 'analytics_rejected');
255
262
  }
@@ -1,3 +1,4 @@
1
+ import { type CheckoutEmailDialogProps } from '../../../components/CheckoutEmailDialog.js';
1
2
  import type { StripeWalletCheckoutSuccess } from './StripeCheckoutExpressCheckoutButton.js';
2
3
  import { type ReactNode } from 'react';
3
4
  import type { Appearance, StripeCheckoutExpressCheckoutElementOptions } from '@stripe/stripe-js';
@@ -57,6 +58,9 @@ export type StripeWalletSurfaceProps = {
57
58
  className?: string;
58
59
  containerClassName?: string;
59
60
  customerEmail?: string | null;
61
+ onCustomerEmailCommit?: CheckoutEmailDialogProps['onSave'];
62
+ onResolveCustomerEmail?: () => Promise<string | null>;
63
+ emailDialogContent?: Pick<CheckoutEmailDialogProps, 'title' | 'description' | 'emailLabel' | 'placeholder' | 'invalidMessage' | 'continueLabel' | 'cancelLabel'>;
60
64
  customerName?: string | null;
61
65
  disabled?: boolean;
62
66
  googlePayOptions?: Partial<StripeCheckoutExpressCheckoutElementOptions>;
@@ -80,4 +84,4 @@ export type StripeWalletSurfaceProps = {
80
84
  surfaceId: string;
81
85
  suspended?: boolean;
82
86
  };
83
- export declare function StripeWalletSurface({ amountCents, appearance, applePayOptions, applePayPlaceholderLabel, beforeConfirm, checkoutAnalytics, className, containerClassName, customerEmail, customerName, disabled, googlePayOptions, googlePayPlaceholderLabel, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onSuccess, onUnavailableClick, paymentMethods, renderHeader, resolveMethodClassName, resolveMethodWrapperClassName, returnUrl, session, slotClassName, summaryLabel, surfaceId, suspended, }: StripeWalletSurfaceProps): import("react/jsx-runtime").JSX.Element | null;
87
+ export declare function StripeWalletSurface({ amountCents, appearance, applePayOptions, applePayPlaceholderLabel, beforeConfirm, checkoutAnalytics, className, containerClassName, customerEmail, onCustomerEmailCommit, onResolveCustomerEmail, emailDialogContent, customerName, disabled, googlePayOptions, googlePayPlaceholderLabel, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onSuccess, onUnavailableClick, paymentMethods, renderHeader, resolveMethodClassName, resolveMethodWrapperClassName, returnUrl, session, slotClassName, summaryLabel, surfaceId, suspended, }: StripeWalletSurfaceProps): import("react/jsx-runtime").JSX.Element | null;
@@ -1,5 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { CheckoutEmailDialog } from '../../../components/CheckoutEmailDialog.js';
4
+ import { isCheckoutEmailError, isValidCheckoutEmail, normalizeCheckoutEmailResult } from '../../../services/checkoutEmail.js';
3
5
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
6
  import { usePlatformWalletPaymentMethods, } from './walletPlatform.js';
5
7
  import { ApplePaySubscriptionCheckoutSlot } from './ApplePaySubscriptionCheckoutSlot.js';
@@ -74,8 +76,41 @@ function buildAvailabilitySignature(availability) {
74
76
  .join(','),
75
77
  ].join('|');
76
78
  }
77
- export function StripeWalletSurface({ amountCents, appearance, applePayOptions, applePayPlaceholderLabel, beforeConfirm, checkoutAnalytics, className, containerClassName, customerEmail, customerName, disabled, googlePayOptions, googlePayPlaceholderLabel, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onSuccess, onUnavailableClick, paymentMethods, renderHeader, resolveMethodClassName, resolveMethodWrapperClassName, returnUrl, session, slotClassName, summaryLabel, surfaceId, suspended = false, }) {
78
- var _a;
79
+ export function StripeWalletSurface({ amountCents, appearance, applePayOptions, applePayPlaceholderLabel, beforeConfirm, checkoutAnalytics, className, containerClassName, customerEmail, onCustomerEmailCommit, onResolveCustomerEmail, emailDialogContent, customerName, disabled, googlePayOptions, googlePayPlaceholderLabel, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onSuccess, onUnavailableClick, paymentMethods, renderHeader, resolveMethodClassName, resolveMethodWrapperClassName, returnUrl, session, slotClassName, summaryLabel, surfaceId, suspended = false, }) {
80
+ var _a, _b, _c;
81
+ const [emailDialogOpen, setEmailDialogOpen] = useState(false);
82
+ const [rejectedEmail, setRejectedEmail] = useState(null);
83
+ const [savedEmail, setSavedEmail] = useState(null);
84
+ const normalizedEmail = (_a = customerEmail === null || customerEmail === void 0 ? void 0 : customerEmail.trim()) !== null && _a !== void 0 ? _a : '';
85
+ const needsEmail = !isValidCheckoutEmail(normalizedEmail)
86
+ || rejectedEmail === normalizedEmail
87
+ || (savedEmail !== null && savedEmail !== normalizedEmail);
88
+ const [resolvingEmail, setResolvingEmail] = useState(false);
89
+ useEffect(() => {
90
+ if (savedEmail === normalizedEmail)
91
+ setSavedEmail(null);
92
+ }, [normalizedEmail, savedEmail]);
93
+ const openEmailDialog = async () => {
94
+ if (resolvingEmail)
95
+ return;
96
+ if (!onCustomerEmailCommit) {
97
+ await (onUnavailableClick === null || onUnavailableClick === void 0 ? void 0 : onUnavailableClick());
98
+ return;
99
+ }
100
+ setResolvingEmail(true);
101
+ try {
102
+ const resolved = await (onResolveCustomerEmail === null || onResolveCustomerEmail === void 0 ? void 0 : onResolveCustomerEmail());
103
+ if (isValidCheckoutEmail(resolved) && (resolved === null || resolved === void 0 ? void 0 : resolved.trim()) !== rejectedEmail)
104
+ return;
105
+ setEmailDialogOpen(true);
106
+ }
107
+ catch (_a) {
108
+ setEmailDialogOpen(true);
109
+ }
110
+ finally {
111
+ setResolvingEmail(false);
112
+ }
113
+ };
79
114
  const platformWalletPaymentMethods = usePlatformWalletPaymentMethods();
80
115
  const walletPaymentMethods = normalizeStripeWalletSurfaceMethods(paymentMethods !== null && paymentMethods !== void 0 ? paymentMethods : platformWalletPaymentMethods);
81
116
  const normalizedSurfaceId = surfaceId.trim();
@@ -92,6 +127,10 @@ export function StripeWalletSurface({ amountCents, appearance, applePayOptions,
92
127
  surfaceMessage: null,
93
128
  });
94
129
  const emitError = useCallback((message, paymentMethod) => {
130
+ if (isCheckoutEmailError(message)) {
131
+ setRejectedEmail(normalizedEmail);
132
+ setEmailDialogOpen(true);
133
+ }
95
134
  const emission = resolveStripeWalletSurfaceError({
96
135
  errorState: errorStateRef.current,
97
136
  message,
@@ -103,7 +142,7 @@ export function StripeWalletSurface({ amountCents, appearance, applePayOptions,
103
142
  }
104
143
  errorStateRef.current = emission.errorState;
105
144
  onError === null || onError === void 0 ? void 0 : onError(emission.message, emission.context);
106
- }, [normalizedSurfaceId, onError]);
145
+ }, [normalizedEmail, normalizedSurfaceId, onError]);
107
146
  useEffect(() => {
108
147
  if (reportedAvailabilitySignatureRef.current === availabilitySignature) {
109
148
  return;
@@ -152,6 +191,16 @@ export function StripeWalletSurface({ amountCents, appearance, applePayOptions,
152
191
  resolved: availability.resolved,
153
192
  suspended,
154
193
  });
194
+ if (needsEmail && session.configured && !suspended && walletPaymentMethods.length > 0) {
195
+ return (_jsxs("div", { className: containerClassName, "data-wallet-surface-id": normalizedSurfaceId, children: [_jsx("button", { type: 'button', className: ['bg-card text-foreground border-border', className].filter(Boolean).join(' '), style: { minHeight: 55, width: '100%', borderRadius: 12, font: 'inherit', cursor: 'pointer' }, disabled: disabled || resolvingEmail, onClick: () => void openEmailDialog(), children: (_b = emailDialogContent === null || emailDialogContent === void 0 ? void 0 : emailDialogContent.continueLabel) !== null && _b !== void 0 ? _b : 'Continue' }), emailDialogOpen && onCustomerEmailCommit ? (_jsx(CheckoutEmailDialog, Object.assign({}, emailDialogContent, { customerEmail: normalizedEmail, rejectedEmail: rejectedEmail, onClose: () => setEmailDialogOpen(false), onSave: async (email) => {
196
+ const saved = await onCustomerEmailCommit(email);
197
+ const nextEmail = normalizeCheckoutEmailResult(saved, email, emailDialogContent === null || emailDialogContent === void 0 ? void 0 : emailDialogContent.invalidMessage);
198
+ setSavedEmail(nextEmail);
199
+ setRejectedEmail(null);
200
+ session.setError(null);
201
+ return nextEmail;
202
+ } }))) : null] }));
203
+ }
155
204
  if (!shouldRenderSurface) {
156
205
  return null;
157
206
  }
@@ -160,7 +209,7 @@ export function StripeWalletSurface({ amountCents, appearance, applePayOptions,
160
209
  containerClassName !== null && containerClassName !== void 0 ? containerClassName : '',
161
210
  ]
162
211
  .filter(Boolean)
163
- .join(' '), "data-wallet-surface-id": normalizedSurfaceId, children: [(_a = renderHeader === null || renderHeader === void 0 ? void 0 : renderHeader({ availability })) !== null && _a !== void 0 ? _a : null, visibleWalletPaymentMethods.map((method) => {
212
+ .join(' '), "data-wallet-surface-id": normalizedSurfaceId, children: [(_c = renderHeader === null || renderHeader === void 0 ? void 0 : renderHeader({ availability })) !== null && _c !== void 0 ? _c : null, visibleWalletPaymentMethods.map((method) => {
164
213
  var _a;
165
214
  return (_jsx("div", { className: [
166
215
  'stripe-subscription-wallet-surface__method',
@@ -0,0 +1,20 @@
1
+ import type { SharedStripeCheckoutV2DialogProps } from './SharedStripeCheckoutV2Dialog.js';
2
+ type EmailInput = Pick<SharedStripeCheckoutV2DialogProps, 'customerEmail' | 'onCustomerEmailCommit' | 'onCustomerEmailChange'> & {
3
+ allowEmailEditing: boolean;
4
+ customerEmailInvalidMessage: string;
5
+ onError: (message: string) => void;
6
+ };
7
+ export declare function useCheckoutEmail({ customerEmail, allowEmailEditing, customerEmailInvalidMessage, onCustomerEmailCommit, onCustomerEmailChange, onError }: EmailInput): {
8
+ initialCustomerEmail: string;
9
+ resolvedCustomerEmail: string;
10
+ customerEmailEditable: boolean;
11
+ emailDraft: string;
12
+ setEmailDraft: import("react").Dispatch<import("react").SetStateAction<string>>;
13
+ rejectedEmail: string | null;
14
+ setRejectedEmail: import("react").Dispatch<import("react").SetStateAction<string | null>>;
15
+ emailSaving: boolean;
16
+ emailSessionChanged: boolean;
17
+ commitEmailDraftIfValid: (value: string) => void;
18
+ ensureCustomerEmail: () => Promise<string | null>;
19
+ };
20
+ export {};
@@ -0,0 +1,74 @@
1
+ 'use client';
2
+ import { useRef, useState } from 'react';
3
+ import { isValidCheckoutEmail as isValidEmail, normalizeCheckoutEmailResult } from '../../../services/checkoutEmail.js';
4
+ export function useCheckoutEmail({ customerEmail, allowEmailEditing, customerEmailInvalidMessage, onCustomerEmailCommit, onCustomerEmailChange, onError }) {
5
+ const initialCustomerEmail = (customerEmail === null || customerEmail === void 0 ? void 0 : customerEmail.trim()) || '';
6
+ const sessionCustomerEmail = useRef(initialCustomerEmail).current;
7
+ const emailSessionChanged = sessionCustomerEmail !== initialCustomerEmail;
8
+ const [emailDraft, setEmailDraft] = useState(initialCustomerEmail);
9
+ const [rejectedEmail, setRejectedEmail] = useState(null);
10
+ const customerEmailEditable = allowEmailEditing || !isValidEmail(initialCustomerEmail) || rejectedEmail !== null;
11
+ const resolvedCustomerEmail = customerEmailEditable
12
+ ? emailDraft.trim()
13
+ : initialCustomerEmail;
14
+ const emailCommitRef = useRef(null);
15
+ const [emailSaving, setEmailSaving] = useState(false);
16
+ const commitCustomerEmail = async (normalizedEmail) => {
17
+ if (emailCommitRef.current)
18
+ return emailCommitRef.current;
19
+ if ((rejectedEmail === null || rejectedEmail === void 0 ? void 0 : rejectedEmail.toLowerCase()) === normalizedEmail.toLowerCase()) {
20
+ throw new Error(customerEmailInvalidMessage);
21
+ }
22
+ if (normalizedEmail === initialCustomerEmail)
23
+ return normalizedEmail;
24
+ if (!onCustomerEmailCommit)
25
+ throw new Error('Unable to save your email. Please try again.');
26
+ setEmailSaving(true);
27
+ const pending = (async () => {
28
+ const committedEmail = await onCustomerEmailCommit(normalizedEmail);
29
+ const nextEmail = normalizeCheckoutEmailResult(committedEmail, normalizedEmail, customerEmailInvalidMessage);
30
+ setEmailDraft(nextEmail);
31
+ setRejectedEmail(null);
32
+ onCustomerEmailChange === null || onCustomerEmailChange === void 0 ? void 0 : onCustomerEmailChange(nextEmail);
33
+ return nextEmail;
34
+ })();
35
+ emailCommitRef.current = pending;
36
+ try {
37
+ return await pending;
38
+ }
39
+ finally {
40
+ emailCommitRef.current = null;
41
+ setEmailSaving(false);
42
+ }
43
+ };
44
+ const commitEmailDraftIfValid = (value) => {
45
+ const normalizedEmail = value.trim();
46
+ if (!customerEmailEditable || !onCustomerEmailCommit) {
47
+ return;
48
+ }
49
+ if (!normalizedEmail || !isValidEmail(normalizedEmail)) {
50
+ return;
51
+ }
52
+ void commitCustomerEmail(normalizedEmail).catch((commitError) => {
53
+ onError(commitError instanceof Error ? commitError.message : 'Unable to save your email. Please try again.');
54
+ });
55
+ };
56
+ const ensureCustomerEmail = async () => {
57
+ if (emailSessionChanged)
58
+ return null;
59
+ const normalizedEmail = resolvedCustomerEmail.trim();
60
+ if (!normalizedEmail || !isValidEmail(normalizedEmail)) {
61
+ onError(customerEmailInvalidMessage);
62
+ return null;
63
+ }
64
+ if (emailCommitRef.current || normalizedEmail !== initialCustomerEmail || rejectedEmail !== null) {
65
+ await commitCustomerEmail(normalizedEmail);
66
+ // Saving can switch Funnel User and replace this Checkout Session. Require a fresh action.
67
+ return null;
68
+ }
69
+ return normalizedEmail;
70
+ };
71
+ return { initialCustomerEmail, resolvedCustomerEmail, customerEmailEditable,
72
+ emailDraft, setEmailDraft, rejectedEmail, setRejectedEmail, emailSaving,
73
+ emailSessionChanged, commitEmailDraftIfValid, ensureCustomerEmail };
74
+ }
@@ -1,5 +1,6 @@
1
1
  import type { FunnelStepType, RuntimeMode } from '@funnelsgrove/runtime';
2
- import { type StripeRuntimeConfigOverrides } from './stripe.service.js';
2
+ import type { StripeRuntimeConfigOverrides } from './shared/types.js';
3
+ import type { ChargeOneClickPaymentResponse, CompleteStripeOneClickPaymentInput } from './oneClick/types.js';
3
4
  export type StripeSubscriptionCheckoutAnalyticsContext = {
4
5
  environment?: RuntimeMode;
5
6
  featureFlags?: Record<string, string | null | undefined>;
@@ -28,3 +29,4 @@ export declare function trackStripeSubscriptionCheckoutStarted(input: TrackStrip
28
29
  export declare function queueStripeSubscriptionCheckoutStarted(input: TrackStripeSubscriptionCheckoutStartedInput): void;
29
30
  export declare function trackStripeSubscriptionPaymentInfoSubmitted(input: TrackStripeSubscriptionPaymentInfoSubmittedInput): Promise<TrackStripeSubscriptionPaymentInfoSubmittedResult>;
30
31
  export declare function trackPaidStripeSubscriptionCheckoutCompleted(input: TrackPaidStripeSubscriptionCheckoutCompletedInput): Promise<TrackPaidStripeSubscriptionCheckoutCompletedResult>;
32
+ export declare function trackPaidStripeOneClickPaymentCompleted(input: CompleteStripeOneClickPaymentInput, payment: ChargeOneClickPaymentResponse): Promise<void>;