@funnelsgrove/payments 0.1.43 → 0.1.45
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/dist/components/shared/SharedStripeCheckoutV2Dialog.d.ts +3 -1
- package/dist/components/shared/SharedStripeCheckoutV2Dialog.js +40 -12
- package/dist/components/shared/StripeCheckoutExpressCheckoutButton.d.ts +3 -1
- package/dist/components/shared/StripeCheckoutExpressCheckoutButton.js +14 -1
- package/dist/components/shared/checkoutCountries.d.ts +7 -0
- package/dist/components/shared/checkoutCountries.js +25 -0
- package/package.json +1 -1
|
@@ -42,10 +42,12 @@ export type SharedStripeCheckoutV2DialogProps = {
|
|
|
42
42
|
satisfactionPercent: string;
|
|
43
43
|
stripePromise: Promise<Stripe | null>;
|
|
44
44
|
summaryLabel?: string;
|
|
45
|
+
supportedCountries?: readonly string[];
|
|
45
46
|
themeColor: string;
|
|
46
47
|
title: string;
|
|
47
48
|
totalLabel: string;
|
|
48
49
|
totalValue: string;
|
|
50
|
+
unsupportedCountryMessage?: string;
|
|
49
51
|
walletButtonLabel: string;
|
|
50
52
|
originalPriceLabel: string;
|
|
51
53
|
originalPriceValue: string;
|
|
@@ -61,5 +63,5 @@ export type SharedCheckoutSpecialOfferDialogProps = {
|
|
|
61
63
|
themeColor: string;
|
|
62
64
|
title: string;
|
|
63
65
|
};
|
|
64
|
-
export declare function SharedStripeCheckoutV2Dialog({ checkoutAnalytics, checkoutSessionId, clientSecret, onClose, stripePromise, ...props }: SharedStripeCheckoutV2DialogProps): import("react/jsx-runtime").JSX.Element;
|
|
66
|
+
export declare function SharedStripeCheckoutV2Dialog({ checkoutAnalytics, checkoutSessionId, clientSecret, onClose, stripePromise, supportedCountries, ...props }: SharedStripeCheckoutV2DialogProps): import("react/jsx-runtime").JSX.Element;
|
|
65
67
|
export declare function SharedCheckoutSpecialOfferDialog({ buttonColor, buttonLabel, description, discountLabel, imageAlt, imageSrc, onAccept, themeColor, title, }: SharedCheckoutSpecialOfferDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -15,6 +15,7 @@ import { useEffect, useMemo, useState, } from 'react';
|
|
|
15
15
|
import { CheckoutProvider, PaymentElement, useCheckout, } from '@stripe/react-stripe-js/checkout';
|
|
16
16
|
import { PaymentBrandMark, SecurityLockIcon } from './CheckoutBrandAssets.js';
|
|
17
17
|
import { StripeCheckoutExpressCheckoutButton } from './StripeCheckoutExpressCheckoutButton.js';
|
|
18
|
+
import { getUnsupportedCheckoutCountryMessage, normalizeSupportedCheckoutCountries, } from './checkoutCountries.js';
|
|
18
19
|
import { isInactiveCheckoutSessionError } from '../../providers/stripe/useStripeSubscriptionCheckoutSession.js';
|
|
19
20
|
import { getStripeWalletPaymentMethodOrder, usePlatformWalletPaymentMethods, } from './walletPlatform.js';
|
|
20
21
|
import { trackPaidStripeSubscriptionCheckoutCompleted, trackStripeSubscriptionCheckoutStarted, } from '../../services/checkoutCompletionAnalytics.service.js';
|
|
@@ -48,12 +49,13 @@ const formatCountdown = (remainingSeconds) => {
|
|
|
48
49
|
const seconds = normalizedSeconds % 60;
|
|
49
50
|
return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
|
|
50
51
|
};
|
|
52
|
+
const getFixedSupportedBillingCountry = (supportedCountries) => supportedCountries.length === 1 ? supportedCountries[0] : null;
|
|
51
53
|
function getFriendlyCardErrorMessage(error) {
|
|
52
54
|
return error instanceof Error && error.message
|
|
53
55
|
? error.message
|
|
54
56
|
: 'Payment failed. Please review your card details and try again.';
|
|
55
57
|
}
|
|
56
|
-
function SharedStripeCheckoutV2Form({ amountCents, buttonColor, cardSubmitLabel, closeAriaLabel, countdownLabel, checkoutAnalytics, checkoutSessionId, customerEmail, customerEmailEditable = 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, themeColor, title, totalLabel, totalValue, walletButtonLabel, originalPriceLabel, originalPriceValue, }) {
|
|
58
|
+
function SharedStripeCheckoutV2Form({ amountCents, buttonColor, cardSubmitLabel, closeAriaLabel, countdownLabel, checkoutAnalytics, checkoutSessionId, customerEmail, customerEmailEditable = 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, }) {
|
|
57
59
|
const checkoutState = useCheckout();
|
|
58
60
|
const walletPaymentMethods = usePlatformWalletPaymentMethods();
|
|
59
61
|
const [selectedMethod, setSelectedMethod] = useState('wallet');
|
|
@@ -63,8 +65,11 @@ function SharedStripeCheckoutV2Form({ amountCents, buttonColor, cardSubmitLabel,
|
|
|
63
65
|
: walletAvailable;
|
|
64
66
|
const [submitting, setSubmitting] = useState(false);
|
|
65
67
|
const [error, setError] = useState(null);
|
|
68
|
+
const [billingCountry, setBillingCountry] = useState(null);
|
|
66
69
|
const initialCustomerEmail = (customerEmail === null || customerEmail === void 0 ? void 0 : customerEmail.trim()) || '';
|
|
67
70
|
const [emailDraft, setEmailDraft] = useState(initialCustomerEmail);
|
|
71
|
+
const normalizedSupportedCountries = useMemo(() => normalizeSupportedCheckoutCountries(supportedCountries), [supportedCountries]);
|
|
72
|
+
const fixedBillingCountry = getFixedSupportedBillingCountry(normalizedSupportedCountries);
|
|
68
73
|
const cardBrandLabels = useMemo(() => paymentMethodLabels.length > 0 ? paymentMethodLabels : defaultPaymentMethodLabels, [paymentMethodLabels]);
|
|
69
74
|
const normalizedPromoCode = promoCode.trim();
|
|
70
75
|
const showPromo = promoActive !== null && promoActive !== void 0 ? promoActive : (discountPercent > 0 && normalizedPromoCode.length > 0);
|
|
@@ -122,7 +127,7 @@ function SharedStripeCheckoutV2Form({ amountCents, buttonColor, cardSubmitLabel,
|
|
|
122
127
|
name: 'never',
|
|
123
128
|
email: 'never',
|
|
124
129
|
address: {
|
|
125
|
-
country: 'auto',
|
|
130
|
+
country: fixedBillingCountry ? 'never' : 'auto',
|
|
126
131
|
},
|
|
127
132
|
},
|
|
128
133
|
},
|
|
@@ -133,7 +138,7 @@ function SharedStripeCheckoutV2Form({ amountCents, buttonColor, cardSubmitLabel,
|
|
|
133
138
|
link: 'never',
|
|
134
139
|
},
|
|
135
140
|
};
|
|
136
|
-
}, []);
|
|
141
|
+
}, [fixedBillingCountry]);
|
|
137
142
|
const handleInactiveCheckoutSession = () => {
|
|
138
143
|
setError(null);
|
|
139
144
|
onInactiveCheckoutSession === null || onInactiveCheckoutSession === void 0 ? void 0 : onInactiveCheckoutSession();
|
|
@@ -158,6 +163,15 @@ function SharedStripeCheckoutV2Form({ amountCents, buttonColor, cardSubmitLabel,
|
|
|
158
163
|
setSelectedMethod('card');
|
|
159
164
|
}
|
|
160
165
|
};
|
|
166
|
+
const getBillingCountryError = (country) => getUnsupportedCheckoutCountryMessage({
|
|
167
|
+
billingCountry: country,
|
|
168
|
+
message: unsupportedCountryMessage,
|
|
169
|
+
supportedCountries: normalizedSupportedCountries,
|
|
170
|
+
});
|
|
171
|
+
const handlePaymentElementChange = (event) => {
|
|
172
|
+
var _a, _b;
|
|
173
|
+
setBillingCountry((_b = (_a = event.value.billingDetails) === null || _a === void 0 ? void 0 : _a.address.country) !== null && _b !== void 0 ? _b : fixedBillingCountry);
|
|
174
|
+
};
|
|
161
175
|
const trackCheckoutSuccess = async () => {
|
|
162
176
|
if (checkoutAnalytics) {
|
|
163
177
|
await trackPaidStripeSubscriptionCheckoutCompleted(Object.assign({ checkoutSessionId }, checkoutAnalytics));
|
|
@@ -210,6 +224,11 @@ function SharedStripeCheckoutV2Form({ amountCents, buttonColor, cardSubmitLabel,
|
|
|
210
224
|
if (submitting) {
|
|
211
225
|
return;
|
|
212
226
|
}
|
|
227
|
+
const billingCountryError = getBillingCountryError(billingCountry !== null && billingCountry !== void 0 ? billingCountry : fixedBillingCountry);
|
|
228
|
+
if (billingCountryError) {
|
|
229
|
+
setSharedError(billingCountryError);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
213
232
|
if (checkoutState.type !== 'success') {
|
|
214
233
|
setSharedError(checkoutState.type === 'error'
|
|
215
234
|
? checkoutState.error.message
|
|
@@ -267,7 +286,7 @@ function SharedStripeCheckoutV2Form({ amountCents, buttonColor, cardSubmitLabel,
|
|
|
267
286
|
effectiveSelectedMethod === 'wallet' ? 'is-visible' : '',
|
|
268
287
|
]
|
|
269
288
|
.filter(Boolean)
|
|
270
|
-
.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, className: 'shared-checkout-v2-express-buttons', confirmEmail: false, customerEmail: resolvedCustomerEmail, customerName: customerName, initialAvailable: initialWalletAvailable, keepInitialAvailableOnReady: initialWalletAvailable === true, onAvailabilityChange: handleWalletAvailabilityChange, onError: setSharedError, onPaymentInfoSubmitted: onPaymentInfoSubmitted, onSuccess: trackCheckoutSuccess, options: expressCheckoutOptions, returnUrl: returnUrl, summaryLabel: expressCheckoutSummaryLabel }), _jsx("span", { className: 'shared-checkout-v2-sr-only', children: walletAriaLabel })] })] }), _jsxs("div", { hidden: effectiveSelectedMethod !== 'card', className: [
|
|
289
|
+
.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, className: 'shared-checkout-v2-express-buttons', confirmEmail: false, customerEmail: resolvedCustomerEmail, customerName: customerName, initialAvailable: initialWalletAvailable, keepInitialAvailableOnReady: initialWalletAvailable === true, onAvailabilityChange: handleWalletAvailabilityChange, onError: setSharedError, onPaymentInfoSubmitted: onPaymentInfoSubmitted, 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: [
|
|
271
290
|
'shared-checkout-v2-card-panel',
|
|
272
291
|
effectiveSelectedMethod === 'card' ? 'is-visible' : '',
|
|
273
292
|
]
|
|
@@ -278,16 +297,25 @@ function SharedStripeCheckoutV2Form({ amountCents, buttonColor, cardSubmitLabel,
|
|
|
278
297
|
}
|
|
279
298
|
setEmailDraft(event.target.value);
|
|
280
299
|
onCustomerEmailChange === null || onCustomerEmailChange === void 0 ? void 0 : onCustomerEmailChange(event.target.value);
|
|
281
|
-
} }) })] }), _jsx(PaymentElement, { options: paymentElementOptions })] }), visibleError ? _jsx("p", { className: 'shared-checkout-v2-error', children: visibleError }) : null, _jsxs("button", { type: 'submit', className: 'shared-checkout-v2-card-submit', disabled: submitting, children: [_jsx(SecurityLockIcon, { className: 'shared-checkout-v2-card-submit-icon' }), submitting ? 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] })] })] })] }));
|
|
300
|
+
} }) })] }), _jsx(PaymentElement, { options: paymentElementOptions, onChange: handlePaymentElementChange })] }), visibleError ? _jsx("p", { className: 'shared-checkout-v2-error', children: visibleError }) : null, _jsxs("button", { type: 'submit', className: 'shared-checkout-v2-card-submit', disabled: submitting, children: [_jsx(SecurityLockIcon, { className: 'shared-checkout-v2-card-submit-icon' }), submitting ? 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] })] })] })] }));
|
|
282
301
|
}
|
|
283
302
|
export function SharedStripeCheckoutV2Dialog(_a) {
|
|
284
|
-
var { checkoutAnalytics, checkoutSessionId, clientSecret, onClose, stripePromise } = _a, props = __rest(_a, ["checkoutAnalytics", "checkoutSessionId", "clientSecret", "onClose", "stripePromise"]);
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
303
|
+
var { checkoutAnalytics, checkoutSessionId, clientSecret, onClose, stripePromise, supportedCountries } = _a, props = __rest(_a, ["checkoutAnalytics", "checkoutSessionId", "clientSecret", "onClose", "stripePromise", "supportedCountries"]);
|
|
304
|
+
const normalizedSupportedCountries = useMemo(() => normalizeSupportedCheckoutCountries(supportedCountries), [supportedCountries]);
|
|
305
|
+
const fixedBillingCountry = getFixedSupportedBillingCountry(normalizedSupportedCountries);
|
|
306
|
+
const checkoutProviderOptions = useMemo(() => (Object.assign(Object.assign({ clientSecret }, (fixedBillingCountry
|
|
307
|
+
? {
|
|
308
|
+
defaultValues: {
|
|
309
|
+
billingAddress: {
|
|
310
|
+
address: {
|
|
311
|
+
country: fixedBillingCountry,
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
}
|
|
316
|
+
: {})), { elementsOptions: {
|
|
288
317
|
appearance: stripeCheckoutV2Appearance,
|
|
289
|
-
},
|
|
290
|
-
}), [clientSecret]);
|
|
318
|
+
} })), [clientSecret, fixedBillingCountry]);
|
|
291
319
|
useEffect(() => {
|
|
292
320
|
if (!checkoutAnalytics) {
|
|
293
321
|
return;
|
|
@@ -303,7 +331,7 @@ export function SharedStripeCheckoutV2Dialog(_a) {
|
|
|
303
331
|
window.addEventListener('keydown', handleKeyDown);
|
|
304
332
|
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
305
333
|
}, [onClose]);
|
|
306
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: 'shared-checkout-v2-overlay', children: _jsx("div", { className: 'shared-checkout-v2-dialog', role: 'dialog', "aria-modal": 'true', "aria-labelledby": 'shared-checkout-v2-title', children: _jsx(CheckoutProvider, { stripe: stripePromise, options: checkoutProviderOptions, children: _jsx(SharedStripeCheckoutV2Form, Object.assign({}, props, { checkoutAnalytics: checkoutAnalytics, checkoutSessionId: checkoutSessionId, clientSecret: clientSecret, onClose: onClose })) }, clientSecret) }) }), _jsx("style", { children: sharedStripeCheckoutV2Styles })] }));
|
|
334
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: 'shared-checkout-v2-overlay', children: _jsx("div", { className: 'shared-checkout-v2-dialog', role: 'dialog', "aria-modal": 'true', "aria-labelledby": 'shared-checkout-v2-title', children: _jsx(CheckoutProvider, { stripe: stripePromise, options: checkoutProviderOptions, children: _jsx(SharedStripeCheckoutV2Form, Object.assign({}, props, { checkoutAnalytics: checkoutAnalytics, checkoutSessionId: checkoutSessionId, clientSecret: clientSecret, onClose: onClose, supportedCountries: normalizedSupportedCountries })) }, clientSecret) }) }), _jsx("style", { children: sharedStripeCheckoutV2Styles })] }));
|
|
307
335
|
}
|
|
308
336
|
function SharedCheckoutSpecialOfferGift({ discountLabel, imageAlt, imageSrc, }) {
|
|
309
337
|
if (imageSrc) {
|
|
@@ -16,11 +16,13 @@ export type StripeCheckoutExpressCheckoutButtonProps = {
|
|
|
16
16
|
initialAvailable?: boolean | null;
|
|
17
17
|
keepInitialAvailableOnReady?: boolean;
|
|
18
18
|
serverUpdateKey?: string | null;
|
|
19
|
+
supportedCountries?: readonly string[];
|
|
19
20
|
onServerUpdate?: () => Promise<boolean>;
|
|
20
21
|
onAvailabilityChange?: (available: boolean) => void;
|
|
21
22
|
onCancel?: () => void;
|
|
22
23
|
onError?: (message: string | null) => void;
|
|
23
24
|
onPaymentInfoSubmitted?: () => void | Promise<void>;
|
|
24
25
|
onSuccess?: () => void | Promise<void>;
|
|
26
|
+
unsupportedCountryMessage?: string;
|
|
25
27
|
};
|
|
26
|
-
export declare function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAnalytics, checkoutSessionId, returnUrl, confirmEmail, customerEmail, className, options, availabilityPaymentMethods, initialAvailable, keepInitialAvailableOnReady, serverUpdateKey, onServerUpdate, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onSuccess, }: StripeCheckoutExpressCheckoutButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export declare function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAnalytics, checkoutSessionId, returnUrl, confirmEmail, customerEmail, className, options, availabilityPaymentMethods, initialAvailable, keepInitialAvailableOnReady, serverUpdateKey, supportedCountries, onServerUpdate, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onSuccess, unsupportedCountryMessage, }: StripeCheckoutExpressCheckoutButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { ExpressCheckoutElement, useCheckout, } from '@stripe/react-stripe-js/checkout';
|
|
5
5
|
import { trackPaidStripeSubscriptionCheckoutCompleted, trackStripeSubscriptionCheckoutStarted, } from '../../services/checkoutCompletionAnalytics.service.js';
|
|
6
|
+
import { getUnsupportedCheckoutCountryMessage, normalizeSupportedCheckoutCountries, } from './checkoutCountries.js';
|
|
6
7
|
const ExpressCheckoutElementWithCancel = ExpressCheckoutElement;
|
|
7
8
|
const buildDefaultOptions = () => ({
|
|
8
9
|
buttonHeight: 55,
|
|
@@ -27,7 +28,7 @@ const buildDefaultOptions = () => ({
|
|
|
27
28
|
paypal: 'never',
|
|
28
29
|
},
|
|
29
30
|
});
|
|
30
|
-
export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAnalytics, checkoutSessionId, returnUrl, confirmEmail = true, customerEmail, className, options, availabilityPaymentMethods = ['applePay'], initialAvailable, keepInitialAvailableOnReady = false, serverUpdateKey, onServerUpdate, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onSuccess, }) {
|
|
31
|
+
export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAnalytics, checkoutSessionId, returnUrl, confirmEmail = true, customerEmail, className, options, availabilityPaymentMethods = ['applePay'], initialAvailable, keepInitialAvailableOnReady = false, serverUpdateKey, supportedCountries, onServerUpdate, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onSuccess, unsupportedCountryMessage, }) {
|
|
31
32
|
const checkoutState = useCheckout();
|
|
32
33
|
const appliedServerUpdateKeyRef = useRef('');
|
|
33
34
|
const serverUpdatePromiseRef = useRef(null);
|
|
@@ -37,6 +38,7 @@ export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAna
|
|
|
37
38
|
? true
|
|
38
39
|
: walletAvailable;
|
|
39
40
|
const baseOptions = useMemo(() => buildDefaultOptions(), []);
|
|
41
|
+
const normalizedSupportedCountries = useMemo(() => normalizeSupportedCheckoutCountries(supportedCountries), [supportedCountries]);
|
|
40
42
|
const resolvedOptions = useMemo(() => {
|
|
41
43
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
42
44
|
return Object.assign(Object.assign(Object.assign({}, baseOptions), (options !== null && options !== void 0 ? options : {})), { buttonTheme: Object.assign(Object.assign({}, ((_a = baseOptions.buttonTheme) !== null && _a !== void 0 ? _a : {})), ((_b = options === null || options === void 0 ? void 0 : options.buttonTheme) !== null && _b !== void 0 ? _b : {})), buttonType: Object.assign(Object.assign({}, ((_c = baseOptions.buttonType) !== null && _c !== void 0 ? _c : {})), ((_d = options === null || options === void 0 ? void 0 : options.buttonType) !== null && _d !== void 0 ? _d : {})), layout: Object.assign(Object.assign({}, ((_e = baseOptions.layout) !== null && _e !== void 0 ? _e : {})), ((_f = options === null || options === void 0 ? void 0 : options.layout) !== null && _f !== void 0 ? _f : {})), paymentMethods: Object.assign(Object.assign({}, ((_g = baseOptions.paymentMethods) !== null && _g !== void 0 ? _g : {})), ((_h = options === null || options === void 0 ? void 0 : options.paymentMethods) !== null && _h !== void 0 ? _h : {})), paymentMethodOrder: (_j = options === null || options === void 0 ? void 0 : options.paymentMethodOrder) !== null && _j !== void 0 ? _j : baseOptions.paymentMethodOrder });
|
|
@@ -94,6 +96,7 @@ export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAna
|
|
|
94
96
|
await (onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess());
|
|
95
97
|
};
|
|
96
98
|
const handleConfirm = async (event) => {
|
|
99
|
+
var _a, _b, _c;
|
|
97
100
|
if (checkoutState.type !== 'success') {
|
|
98
101
|
const message = checkoutState.type === 'error'
|
|
99
102
|
? checkoutState.error.message
|
|
@@ -103,6 +106,16 @@ export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, checkoutAna
|
|
|
103
106
|
return;
|
|
104
107
|
}
|
|
105
108
|
onError === null || onError === void 0 ? void 0 : onError(null);
|
|
109
|
+
const unsupportedCountryError = getUnsupportedCheckoutCountryMessage({
|
|
110
|
+
billingCountry: (_c = (_b = (_a = event.billingDetails) === null || _a === void 0 ? void 0 : _a.address) === null || _b === void 0 ? void 0 : _b.country) !== null && _c !== void 0 ? _c : null,
|
|
111
|
+
message: unsupportedCountryMessage,
|
|
112
|
+
supportedCountries: normalizedSupportedCountries,
|
|
113
|
+
});
|
|
114
|
+
if (unsupportedCountryError) {
|
|
115
|
+
onError === null || onError === void 0 ? void 0 : onError(unsupportedCountryError);
|
|
116
|
+
event.paymentFailed({ reason: 'invalid_billing_address', message: unsupportedCountryError });
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
106
119
|
const updated = await ensureServerUpdated();
|
|
107
120
|
if (!updated) {
|
|
108
121
|
const message = 'Unable to update checkout session.';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const defaultUnsupportedCheckoutCountryMessage = "Payment is not available for the selected billing country.";
|
|
2
|
+
export declare function normalizeSupportedCheckoutCountries(countries?: readonly string[] | null): string[];
|
|
3
|
+
export declare function getUnsupportedCheckoutCountryMessage({ billingCountry, message, supportedCountries, }: {
|
|
4
|
+
billingCountry?: string | null;
|
|
5
|
+
message?: string;
|
|
6
|
+
supportedCountries: readonly string[];
|
|
7
|
+
}): string | null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const defaultUnsupportedCheckoutCountryMessage = 'Payment is not available for the selected billing country.';
|
|
2
|
+
const normalizeCheckoutCountryCode = (countryCode) => {
|
|
3
|
+
const normalizedCountryCode = (countryCode === null || countryCode === void 0 ? void 0 : countryCode.trim().toUpperCase()) || '';
|
|
4
|
+
return /^[A-Z]{2}$/.test(normalizedCountryCode) ? normalizedCountryCode : null;
|
|
5
|
+
};
|
|
6
|
+
export function normalizeSupportedCheckoutCountries(countries) {
|
|
7
|
+
const normalizedCountries = new Set();
|
|
8
|
+
for (const country of countries !== null && countries !== void 0 ? countries : []) {
|
|
9
|
+
const normalizedCountry = normalizeCheckoutCountryCode(country);
|
|
10
|
+
if (normalizedCountry) {
|
|
11
|
+
normalizedCountries.add(normalizedCountry);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return Array.from(normalizedCountries);
|
|
15
|
+
}
|
|
16
|
+
export function getUnsupportedCheckoutCountryMessage({ billingCountry, message = defaultUnsupportedCheckoutCountryMessage, supportedCountries, }) {
|
|
17
|
+
if (supportedCountries.length === 0) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const normalizedBillingCountry = normalizeCheckoutCountryCode(billingCountry);
|
|
21
|
+
if (!normalizedBillingCountry) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return supportedCountries.includes(normalizedBillingCountry) ? null : message;
|
|
25
|
+
}
|