@funnelsgrove/payments 0.7.20 → 0.7.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/providers/stripe/components/SharedStripeCheckoutV2Dialog.d.ts +2 -1
- package/dist/providers/stripe/components/SharedStripeCheckoutV2Dialog.js +72 -7
- package/dist/providers/stripe/hooks/useStripeOneTimeCheckoutSession.d.ts +4 -3
- package/dist/providers/stripe/hooks/useStripeOneTimeCheckoutSession.js +10 -4
- package/dist/providers/stripe/hooks/useStripeSubscriptionCheckoutSession.d.ts +4 -3
- package/dist/providers/stripe/hooks/useStripeSubscriptionCheckoutSession.js +7 -4
- package/dist/services/publishedBillingRuntime.service.d.ts +1 -0
- package/dist/services/publishedBillingRuntime.service.js +9 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -32,6 +32,10 @@ Use these for new one-time paywall plans:
|
|
|
32
32
|
- `createStripeOneTimeCheckout`
|
|
33
33
|
- `SharedStripeCheckoutV2Dialog`
|
|
34
34
|
|
|
35
|
+
`SharedStripeCheckoutV2Dialog` defaults to the existing full-screen `standard` surface. Pass
|
|
36
|
+
`variant='compact'` for a centered desktop modal with the same Stripe-owned wallet/card flow;
|
|
37
|
+
mobile remains full-screen and all checkout analytics and verified-success behavior are unchanged.
|
|
38
|
+
|
|
35
39
|
Use `completeStripeOneClickPayment` for normal post-checkout one-click upsells. It delegates the charge to `funnelSdkService.chargeOneClickPayment` and owns any required Stripe confirmation. `chargeStripeOneClickPayment` remains the lower-level charge-only primitive.
|
|
36
40
|
|
|
37
41
|
Solidgate browser checkout is available for controlled provider-routed funnels through
|
|
@@ -94,7 +98,7 @@ When a live funnel still uses one of these, migrate the funnel deliberately with
|
|
|
94
98
|
- `providers/solidgate/components/*`: the official-SDK checkout dialog and canonical verification lifecycle.
|
|
95
99
|
- `components/ManageSubscriptionScreen`: provider-neutral subscription management UI.
|
|
96
100
|
|
|
97
|
-
Funnels should call `resolvePublishedBillingRuntime` once at their runtime-provider boundary. Screens consume its resolved view and should not parse offer sets or pricing-experiment variants themselves.
|
|
101
|
+
Funnels should call `resolvePublishedBillingRuntime` once at their runtime-provider boundary. Screens consume its resolved view and should not parse offer sets or pricing-experiment variants themselves. Pass the resolved `stripePublishableKey` into shared Stripe checkout hooks so Stripe.js can load while the Checkout Session request is still in flight; the key returned by that request remains the compatibility fallback.
|
|
98
102
|
|
|
99
103
|
## Engineering Rules
|
|
100
104
|
|
|
@@ -51,6 +51,7 @@ export type SharedStripeCheckoutV2DialogProps = {
|
|
|
51
51
|
walletButtonLabel: string;
|
|
52
52
|
originalPriceLabel: string;
|
|
53
53
|
originalPriceValue: string;
|
|
54
|
+
variant?: 'standard' | 'compact';
|
|
54
55
|
};
|
|
55
56
|
export type SharedCheckoutSpecialOfferDialogProps = {
|
|
56
57
|
buttonColor: string;
|
|
@@ -63,5 +64,5 @@ export type SharedCheckoutSpecialOfferDialogProps = {
|
|
|
63
64
|
themeColor: string;
|
|
64
65
|
title: string;
|
|
65
66
|
};
|
|
66
|
-
export declare function SharedStripeCheckoutV2Dialog({ checkoutAnalytics, checkoutSessionId, clientSecret, onClose, stripePromise, supportedCountries, ...props }: SharedStripeCheckoutV2DialogProps): import("react/jsx-runtime").JSX.Element;
|
|
67
|
+
export declare function SharedStripeCheckoutV2Dialog({ checkoutAnalytics, checkoutSessionId, clientSecret, onClose, stripePromise, supportedCountries, variant, ...props }: SharedStripeCheckoutV2DialogProps): import("react/jsx-runtime").JSX.Element;
|
|
67
68
|
export declare function SharedCheckoutSpecialOfferDialog({ buttonColor, buttonLabel, description, discountLabel, imageAlt, imageSrc, onAccept, themeColor, title, }: SharedCheckoutSpecialOfferDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -40,6 +40,7 @@ const stripeCheckoutV2Appearance = {
|
|
|
40
40
|
},
|
|
41
41
|
},
|
|
42
42
|
};
|
|
43
|
+
const compactStripeCheckoutV2Appearance = Object.assign(Object.assign({}, stripeCheckoutV2Appearance), { variables: Object.assign(Object.assign({}, stripeCheckoutV2Appearance.variables), { borderRadius: '14px', colorPrimary: '#1687f8' }) });
|
|
43
44
|
const isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
44
45
|
const formatCountdown = (remainingSeconds) => {
|
|
45
46
|
const normalizedSeconds = Number.isFinite(remainingSeconds)
|
|
@@ -59,7 +60,7 @@ function getFriendlyCardErrorMessage(error) {
|
|
|
59
60
|
? error.message
|
|
60
61
|
: 'Payment failed. Please review your card details and try again.';
|
|
61
62
|
}
|
|
62
|
-
function SharedStripeCheckoutV2CheckoutSessionForm({ 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, }) {
|
|
63
|
+
function SharedStripeCheckoutV2CheckoutSessionForm({ 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, variant = 'standard', }) {
|
|
63
64
|
const checkoutState = useCheckout();
|
|
64
65
|
const walletPaymentMethods = usePlatformWalletPaymentMethods();
|
|
65
66
|
const [selectedMethod, setSelectedMethod] = useState('wallet');
|
|
@@ -279,7 +280,7 @@ function SharedStripeCheckoutV2CheckoutSessionForm({ amountCents, buttonColor, c
|
|
|
279
280
|
}
|
|
280
281
|
};
|
|
281
282
|
const visibleError = error;
|
|
282
|
-
return (_jsxs("div", { className: 'shared-checkout-v2-shell', 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 })] }), _jsxs("section", { className: 'shared-checkout-v2-summary', children: [showPromo ? (_jsxs("p", { className: 'shared-checkout-v2-countdown', children: [discountPercent, "% ", countdownLabel, " ", countdownValue, " min"] })) : null, _jsxs("p", { className: 'shared-checkout-v2-satisfaction', children: [_jsx("strong", { children: satisfactionPercent }), " ", satisfactionLabel] }), 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: [
|
|
283
|
+
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 })] }), _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: [
|
|
283
284
|
'shared-checkout-v2-total',
|
|
284
285
|
showPromo ? '' : 'is-plain',
|
|
285
286
|
]
|
|
@@ -312,7 +313,7 @@ function SharedStripeCheckoutV2CheckoutSessionForm({ amountCents, buttonColor, c
|
|
|
312
313
|
onCustomerEmailChange === null || onCustomerEmailChange === void 0 ? void 0 : onCustomerEmailChange(event.target.value);
|
|
313
314
|
} }) })] }), _jsx(PaymentElement, { options: paymentElementOptions, onChange: handlePaymentElementChange }), 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, 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] })] })] })] }));
|
|
314
315
|
}
|
|
315
|
-
function CheckoutSessionProvider({ children, clientSecret, fixedBillingCountry, stripePromise, }) {
|
|
316
|
+
function CheckoutSessionProvider({ children, clientSecret, fixedBillingCountry, stripePromise, variant, }) {
|
|
316
317
|
const providerChildren = children;
|
|
317
318
|
const checkoutProviderOptions = useMemo(() => (Object.assign(Object.assign({ clientSecret }, (fixedBillingCountry
|
|
318
319
|
? {
|
|
@@ -325,12 +326,14 @@ function CheckoutSessionProvider({ children, clientSecret, fixedBillingCountry,
|
|
|
325
326
|
},
|
|
326
327
|
}
|
|
327
328
|
: {})), { elementsOptions: {
|
|
328
|
-
appearance:
|
|
329
|
-
|
|
329
|
+
appearance: variant === 'compact'
|
|
330
|
+
? compactStripeCheckoutV2Appearance
|
|
331
|
+
: stripeCheckoutV2Appearance,
|
|
332
|
+
} })), [clientSecret, fixedBillingCountry, variant]);
|
|
330
333
|
return (_jsx(CheckoutProvider, { stripe: stripePromise, options: checkoutProviderOptions, children: providerChildren }, clientSecret));
|
|
331
334
|
}
|
|
332
335
|
export function SharedStripeCheckoutV2Dialog(_a) {
|
|
333
|
-
var { checkoutAnalytics, checkoutSessionId, clientSecret, onClose, stripePromise, supportedCountries } = _a, props = __rest(_a, ["checkoutAnalytics", "checkoutSessionId", "clientSecret", "onClose", "stripePromise", "supportedCountries"]);
|
|
336
|
+
var { checkoutAnalytics, checkoutSessionId, clientSecret, onClose, stripePromise, supportedCountries, variant = 'standard' } = _a, props = __rest(_a, ["checkoutAnalytics", "checkoutSessionId", "clientSecret", "onClose", "stripePromise", "supportedCountries", "variant"]);
|
|
334
337
|
const normalizedSupportedCountries = useMemo(() => normalizeSupportedCheckoutCountries(supportedCountries), [supportedCountries]);
|
|
335
338
|
const fixedBillingCountry = getFixedSupportedBillingCountry(normalizedSupportedCountries);
|
|
336
339
|
useEffect(() => {
|
|
@@ -348,7 +351,7 @@ export function SharedStripeCheckoutV2Dialog(_a) {
|
|
|
348
351
|
window.addEventListener('keydown', handleKeyDown);
|
|
349
352
|
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
350
353
|
}, [onClose]);
|
|
351
|
-
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(CheckoutSessionProvider, { clientSecret: clientSecret, fixedBillingCountry: fixedBillingCountry, stripePromise: stripePromise, children: _jsx(SharedStripeCheckoutV2CheckoutSessionForm, Object.assign({}, props, { checkoutAnalytics: checkoutAnalytics, checkoutSessionId: checkoutSessionId, clientSecret: clientSecret, onClose: onClose, supportedCountries: normalizedSupportedCountries })) }) }) }), _jsx("style", { children: sharedStripeCheckoutV2Styles })] }));
|
|
354
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: 'shared-checkout-v2-overlay', children: _jsx("div", { className: 'shared-checkout-v2-dialog', "data-variant": variant, role: 'dialog', "aria-modal": 'true', "aria-labelledby": 'shared-checkout-v2-title', children: _jsx(CheckoutSessionProvider, { clientSecret: clientSecret, fixedBillingCountry: fixedBillingCountry, stripePromise: stripePromise, variant: variant, children: _jsx(SharedStripeCheckoutV2CheckoutSessionForm, Object.assign({}, props, { checkoutAnalytics: checkoutAnalytics, checkoutSessionId: checkoutSessionId, clientSecret: clientSecret, onClose: onClose, supportedCountries: normalizedSupportedCountries, variant: variant })) }) }) }), _jsx("style", { children: sharedStripeCheckoutV2Styles })] }));
|
|
352
355
|
}
|
|
353
356
|
function SharedCheckoutSpecialOfferGift({ discountLabel, imageAlt, imageSrc, }) {
|
|
354
357
|
if (imageSrc) {
|
|
@@ -383,6 +386,68 @@ const sharedStripeCheckoutV2Styles = `
|
|
|
383
386
|
background: #fff;
|
|
384
387
|
}
|
|
385
388
|
|
|
389
|
+
@media (min-width: 640px) {
|
|
390
|
+
.shared-checkout-v2-overlay:has(.shared-checkout-v2-dialog[data-variant='compact']) {
|
|
391
|
+
align-items: center;
|
|
392
|
+
padding: 24px;
|
|
393
|
+
background: rgb(0 0 0 / 48%);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.shared-checkout-v2-dialog[data-variant='compact'] {
|
|
397
|
+
width: min(100%, 520px);
|
|
398
|
+
height: auto;
|
|
399
|
+
max-height: calc(100svh - 48px);
|
|
400
|
+
border-radius: 24px;
|
|
401
|
+
box-shadow: 0 24px 70px rgb(0 0 0 / 28%);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.shared-checkout-v2-shell[data-variant='compact'] {
|
|
406
|
+
height: auto;
|
|
407
|
+
max-height: min(100svh, 760px);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.shared-checkout-v2-shell[data-variant='compact'] .shared-checkout-v2-header {
|
|
411
|
+
min-height: 88px;
|
|
412
|
+
padding: 0 72px;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.shared-checkout-v2-shell[data-variant='compact'] .shared-checkout-v2-header h2 {
|
|
416
|
+
font-size: 27px;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
.shared-checkout-v2-shell[data-variant='compact'] .shared-checkout-v2-close {
|
|
420
|
+
right: 22px;
|
|
421
|
+
left: auto;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.shared-checkout-v2-shell[data-variant='compact'] .shared-checkout-v2-summary {
|
|
425
|
+
padding: 0 36px;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.shared-checkout-v2-shell[data-variant='compact'] .shared-checkout-v2-total {
|
|
429
|
+
min-height: 82px;
|
|
430
|
+
border: 1px solid #ececef;
|
|
431
|
+
border-radius: 16px;
|
|
432
|
+
padding: 0 22px;
|
|
433
|
+
background: #fbfbfc;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.shared-checkout-v2-shell[data-variant='compact'] .shared-checkout-v2-total svg {
|
|
437
|
+
display: none;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.shared-checkout-v2-shell[data-variant='compact'] .shared-checkout-v2-payment {
|
|
441
|
+
padding-right: 36px;
|
|
442
|
+
padding-left: 36px;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
.shared-checkout-v2-shell[data-variant='compact'] .shared-checkout-v2-card-submit {
|
|
446
|
+
border-radius: 14px;
|
|
447
|
+
background: var(--shared-checkout-v2-button-color);
|
|
448
|
+
text-transform: none;
|
|
449
|
+
}
|
|
450
|
+
|
|
386
451
|
.shared-checkout-v2-shell {
|
|
387
452
|
height: 100%;
|
|
388
453
|
max-height: 100svh;
|
|
@@ -13,6 +13,7 @@ export type StripeOneTimeCheckoutSessionInput = {
|
|
|
13
13
|
plan?: StripeOneTimeCheckoutPlanInput | null;
|
|
14
14
|
returnUrl: string;
|
|
15
15
|
runtimeConfig?: StripeRuntimeConfigOverrides;
|
|
16
|
+
stripePublishableKey?: string | null;
|
|
16
17
|
userId?: string | null;
|
|
17
18
|
};
|
|
18
19
|
export type StripeOneTimeCheckoutPreparationOptions = {
|
|
@@ -39,10 +40,10 @@ export type StripeOneTimeCheckoutSession = {
|
|
|
39
40
|
stripePromise: Promise<Stripe | null> | null;
|
|
40
41
|
};
|
|
41
42
|
export declare const buildStripeOneTimeCheckoutPreparationAnalyticsMetadata: (analyticsMetadata: Record<string, unknown> | null | undefined, options?: StripeOneTimeCheckoutPreparationOptions) => Record<string, unknown> | null | undefined;
|
|
42
|
-
export type StripeOneTimeCheckoutIntentKeyInput = Pick<StripeOneTimeCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'plan' | 'returnUrl' | 'runtimeConfig' | 'userId'> & {
|
|
43
|
+
export type StripeOneTimeCheckoutIntentKeyInput = Pick<StripeOneTimeCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'plan' | 'returnUrl' | 'runtimeConfig' | 'stripePublishableKey' | 'userId'> & {
|
|
43
44
|
analyticsMetadata?: Record<string, unknown> | null;
|
|
44
45
|
};
|
|
45
|
-
export declare function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, userId, }: StripeOneTimeCheckoutIntentKeyInput): string;
|
|
46
|
+
export declare function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutIntentKeyInput): string;
|
|
46
47
|
export declare function shouldResetStripeOneTimeCheckoutSessionForIntentKey(previousIntentKey: string | null, nextIntentKey: string): boolean;
|
|
47
|
-
export declare function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled, onError, plan, returnUrl, runtimeConfig, userId, }: StripeOneTimeCheckoutSessionInput): StripeOneTimeCheckoutSession;
|
|
48
|
+
export declare function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutSessionInput): StripeOneTimeCheckoutSession;
|
|
48
49
|
export {};
|
|
@@ -36,13 +36,14 @@ export const buildStripeOneTimeCheckoutPreparationAnalyticsMetadata = (analytics
|
|
|
36
36
|
const _b = analyticsMetadata !== null && analyticsMetadata !== void 0 ? analyticsMetadata : {}, { payment_method: _paymentMethod, paymentMethod: _camelCasePaymentMethod } = _b, metadata = __rest(_b, ["payment_method", "paymentMethod"]);
|
|
37
37
|
return Object.assign(Object.assign(Object.assign({}, metadata), (checkoutStartSource ? { checkoutStartSource } : {})), (paymentMethod ? { payment_method: paymentMethod } : {}));
|
|
38
38
|
};
|
|
39
|
-
export function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, userId, }) {
|
|
39
|
+
export function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
|
|
40
40
|
var _a;
|
|
41
41
|
const runtimeConfigSignature = [
|
|
42
42
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.apiBaseUrl),
|
|
43
43
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelId),
|
|
44
44
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelVersionId),
|
|
45
45
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey),
|
|
46
|
+
normalizeRuntimeConfigValue(stripePublishableKey),
|
|
46
47
|
].join('|');
|
|
47
48
|
const planSignature = [
|
|
48
49
|
normalizeRuntimeConfigValue(plan === null || plan === void 0 ? void 0 : plan.id),
|
|
@@ -65,7 +66,7 @@ export function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, cu
|
|
|
65
66
|
export function shouldResetStripeOneTimeCheckoutSessionForIntentKey(previousIntentKey, nextIntentKey) {
|
|
66
67
|
return previousIntentKey !== null && previousIntentKey !== nextIntentKey;
|
|
67
68
|
}
|
|
68
|
-
export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled = true, onError, plan, returnUrl, runtimeConfig, userId, }) {
|
|
69
|
+
export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled = true, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
|
|
69
70
|
var _a, _b, _c;
|
|
70
71
|
const [clientSecret, setClientSecret] = useState(null);
|
|
71
72
|
const [clientSecretIntentKey, setClientSecretIntentKey] = useState(null);
|
|
@@ -77,7 +78,8 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
|
|
|
77
78
|
const requestIdRef = useRef(0);
|
|
78
79
|
const configured = enabled &&
|
|
79
80
|
(isStripeConfigured(checkoutMode) ||
|
|
80
|
-
Boolean(normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey))
|
|
81
|
+
Boolean(normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey)) ||
|
|
82
|
+
Boolean(normalizeRuntimeConfigValue(stripePublishableKey)));
|
|
81
83
|
const intentKey = buildStripeOneTimeCheckoutIntentKey({
|
|
82
84
|
checkoutMode,
|
|
83
85
|
couponId,
|
|
@@ -85,6 +87,7 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
|
|
|
85
87
|
plan,
|
|
86
88
|
returnUrl,
|
|
87
89
|
runtimeConfig,
|
|
90
|
+
stripePublishableKey,
|
|
88
91
|
userId,
|
|
89
92
|
});
|
|
90
93
|
const planKey = [
|
|
@@ -94,7 +97,10 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
|
|
|
94
97
|
].join('|');
|
|
95
98
|
const activeClientSecret = clientSecretIntentKey === intentKey ? clientSecret : null;
|
|
96
99
|
const activeCheckoutSessionId = clientSecretIntentKey === intentKey ? checkoutSessionId : null;
|
|
97
|
-
const stripePromise = useMemo(() =>
|
|
100
|
+
const stripePromise = useMemo(() => {
|
|
101
|
+
var _a;
|
|
102
|
+
return getStripePromise(checkoutMode, (_a = runtimeStripePublishableKey !== null && runtimeStripePublishableKey !== void 0 ? runtimeStripePublishableKey : stripePublishableKey) !== null && _a !== void 0 ? _a : runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey);
|
|
103
|
+
}, [checkoutMode, runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey, runtimeStripePublishableKey, stripePublishableKey]);
|
|
98
104
|
const previousIntentKeyRef = useRef(intentKey);
|
|
99
105
|
const analyticsMetadataRef = useRef(analyticsMetadata);
|
|
100
106
|
useEffect(() => {
|
|
@@ -14,6 +14,7 @@ export type StripeSubscriptionCheckoutSessionInput = {
|
|
|
14
14
|
plan?: PaywallPlan | null;
|
|
15
15
|
returnUrl: string;
|
|
16
16
|
runtimeConfig?: StripeRuntimeConfigOverrides;
|
|
17
|
+
stripePublishableKey?: string | null;
|
|
17
18
|
userId?: string | null;
|
|
18
19
|
};
|
|
19
20
|
export type StripeSubscriptionCheckoutPreparationOptions = {
|
|
@@ -42,10 +43,10 @@ export type StripeSubscriptionCheckoutSession = {
|
|
|
42
43
|
updateCheckoutSessionPlan: () => Promise<boolean>;
|
|
43
44
|
};
|
|
44
45
|
export declare const buildStripeSubscriptionCheckoutPreparationAnalyticsMetadata: (analyticsMetadata: Record<string, unknown> | null | undefined, options?: StripeSubscriptionCheckoutPreparationOptions) => Record<string, unknown> | null | undefined;
|
|
45
|
-
export type StripeSubscriptionCheckoutIntentKeyInput = Pick<StripeSubscriptionCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'returnUrl' | 'runtimeConfig' | 'userId'> & {
|
|
46
|
+
export type StripeSubscriptionCheckoutIntentKeyInput = Pick<StripeSubscriptionCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'returnUrl' | 'runtimeConfig' | 'stripePublishableKey' | 'userId'> & {
|
|
46
47
|
analyticsMetadata?: Record<string, unknown> | null;
|
|
47
48
|
};
|
|
48
|
-
export declare function buildStripeSubscriptionCheckoutIntentKey({ checkoutMode, couponId, customerEmail, returnUrl, runtimeConfig, userId, }: StripeSubscriptionCheckoutIntentKeyInput): string;
|
|
49
|
+
export declare function buildStripeSubscriptionCheckoutIntentKey({ checkoutMode, couponId, customerEmail, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeSubscriptionCheckoutIntentKeyInput): string;
|
|
49
50
|
export declare function shouldResetStripeSubscriptionCheckoutSessionForIntentKey(previousIntentKey: string | null, nextIntentKey: string): boolean;
|
|
50
51
|
export declare function isInactiveCheckoutSessionError(message?: string | null): boolean;
|
|
51
|
-
export declare function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled, onError, plan, returnUrl, runtimeConfig, userId, }: StripeSubscriptionCheckoutSessionInput): StripeSubscriptionCheckoutSession;
|
|
52
|
+
export declare function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeSubscriptionCheckoutSessionInput): StripeSubscriptionCheckoutSession;
|
|
@@ -35,12 +35,13 @@ export const buildStripeSubscriptionCheckoutPreparationAnalyticsMetadata = (anal
|
|
|
35
35
|
const _b = analyticsMetadata !== null && analyticsMetadata !== void 0 ? analyticsMetadata : {}, { payment_method: _paymentMethod, paymentMethod: _camelCasePaymentMethod } = _b, metadata = __rest(_b, ["payment_method", "paymentMethod"]);
|
|
36
36
|
return Object.assign(Object.assign(Object.assign({}, metadata), (checkoutStartSource ? { checkoutStartSource } : {})), (paymentMethod ? { payment_method: paymentMethod } : {}));
|
|
37
37
|
};
|
|
38
|
-
export function buildStripeSubscriptionCheckoutIntentKey({ checkoutMode, couponId, customerEmail, returnUrl, runtimeConfig, userId, }) {
|
|
38
|
+
export function buildStripeSubscriptionCheckoutIntentKey({ checkoutMode, couponId, customerEmail, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
|
|
39
39
|
const runtimeConfigSignature = [
|
|
40
40
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.apiBaseUrl),
|
|
41
41
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelId),
|
|
42
42
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelVersionId),
|
|
43
43
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey),
|
|
44
|
+
normalizeRuntimeConfigValue(stripePublishableKey),
|
|
44
45
|
].join('|');
|
|
45
46
|
const customerEmailSignature = normalizeRuntimeConfigValue(customerEmail);
|
|
46
47
|
const userIdSignature = normalizeRuntimeConfigValue(userId);
|
|
@@ -61,7 +62,7 @@ export function isInactiveCheckoutSessionError(message) {
|
|
|
61
62
|
var _a;
|
|
62
63
|
return /\bcheckout session\b.*\bno longer active\b/i.test((_a = message === null || message === void 0 ? void 0 : message.trim()) !== null && _a !== void 0 ? _a : '');
|
|
63
64
|
}
|
|
64
|
-
export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled = true, onError, plan, returnUrl, runtimeConfig, userId, }) {
|
|
65
|
+
export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled = true, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
|
|
65
66
|
var _a, _b, _c, _d, _e;
|
|
66
67
|
const [clientSecret, setClientSecret] = useState(null);
|
|
67
68
|
const [clientSecretIntentKey, setClientSecretIntentKey] = useState(null);
|
|
@@ -74,13 +75,15 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
|
|
|
74
75
|
const requestIdRef = useRef(0);
|
|
75
76
|
const configured = enabled &&
|
|
76
77
|
(isStripeConfigured(checkoutMode) ||
|
|
77
|
-
Boolean(normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey))
|
|
78
|
+
Boolean(normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey)) ||
|
|
79
|
+
Boolean(normalizeRuntimeConfigValue(stripePublishableKey)));
|
|
78
80
|
const intentKey = buildStripeSubscriptionCheckoutIntentKey({
|
|
79
81
|
checkoutMode,
|
|
80
82
|
couponId,
|
|
81
83
|
customerEmail,
|
|
82
84
|
returnUrl,
|
|
83
85
|
runtimeConfig,
|
|
86
|
+
stripePublishableKey,
|
|
84
87
|
userId,
|
|
85
88
|
});
|
|
86
89
|
const planKey = [
|
|
@@ -93,7 +96,7 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
|
|
|
93
96
|
const activeClientSecret = clientSecretIntentKey === intentKey ? clientSecret : null;
|
|
94
97
|
const activeCheckoutSessionId = clientSecretIntentKey === intentKey ? checkoutSessionId : null;
|
|
95
98
|
const activePlanKey = clientSecretIntentKey === intentKey ? clientSecretPlanKey : null;
|
|
96
|
-
const stripePromise = useMemo(() => getStripePromise(checkoutMode, runtimeStripePublishableKey), [checkoutMode, runtimeStripePublishableKey]);
|
|
99
|
+
const stripePromise = useMemo(() => getStripePromise(checkoutMode, runtimeStripePublishableKey !== null && runtimeStripePublishableKey !== void 0 ? runtimeStripePublishableKey : stripePublishableKey), [checkoutMode, runtimeStripePublishableKey, stripePublishableKey]);
|
|
97
100
|
const previousIntentKeyRef = useRef(intentKey);
|
|
98
101
|
const analyticsMetadataRef = useRef(analyticsMetadata);
|
|
99
102
|
useEffect(() => {
|
|
@@ -8,6 +8,7 @@ export type ResolvedPublishedBillingRuntime = {
|
|
|
8
8
|
offerSetId: string;
|
|
9
9
|
paymentProfileId: string | null;
|
|
10
10
|
provider: 'stripe' | 'solidgate';
|
|
11
|
+
stripePublishableKey: string | null;
|
|
11
12
|
experimentId: string | null;
|
|
12
13
|
variantKey: string | null;
|
|
13
14
|
experiments: readonly FunnelExperimentDefinition[];
|
|
@@ -2,7 +2,7 @@ import { resolveGeneratedOfferSetRuntime, resolvePublishedOfferSetSelection, res
|
|
|
2
2
|
import { buildBillingDiscountCatalog } from './paywallOffer.service.js';
|
|
3
3
|
import { buildConfigPaywallPlans, } from '../providers/stripe/services/stripe.service.js';
|
|
4
4
|
export const resolvePublishedBillingRuntime = ({ config, featureFlags, mode, search = '', defaultOfferSetId, baseCatalogsByMode, fallbackDiscounts, resolvedExperiments = resolvePublishedRuntimeExperiments(config), }) => {
|
|
5
|
-
var _a, _b, _c, _d;
|
|
5
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
6
6
|
const offerSets = (_a = config === null || config === void 0 ? void 0 : config.offerSets) !== null && _a !== void 0 ? _a : [];
|
|
7
7
|
const selection = resolvePublishedOfferSetSelection({
|
|
8
8
|
offerSets,
|
|
@@ -22,12 +22,17 @@ export const resolvePublishedBillingRuntime = ({ config, featureFlags, mode, sea
|
|
|
22
22
|
.map((key) => planCatalog[key])
|
|
23
23
|
.filter((plan) => Boolean(plan));
|
|
24
24
|
const discountList = runtime.getDiscountList(mode);
|
|
25
|
+
const provider = runtime.getPaymentProvider(mode);
|
|
26
|
+
const paymentProviderConfig = (_c = (_b = runtime.offerSet) === null || _b === void 0 ? void 0 : _b.paymentProviderConfigByMode) === null || _c === void 0 ? void 0 : _c[mode];
|
|
25
27
|
return {
|
|
26
|
-
revisionId: (
|
|
28
|
+
revisionId: (_d = config === null || config === void 0 ? void 0 : config.revisionId) !== null && _d !== void 0 ? _d : null,
|
|
27
29
|
mode,
|
|
28
30
|
offerSetId: selection.offerSetId,
|
|
29
|
-
paymentProfileId: ((
|
|
30
|
-
provider
|
|
31
|
+
paymentProfileId: ((_f = (_e = runtime.offerSet) === null || _e === void 0 ? void 0 : _e.paymentProfileId) === null || _f === void 0 ? void 0 : _f.trim()) || null,
|
|
32
|
+
provider,
|
|
33
|
+
stripePublishableKey: provider === 'stripe' && (paymentProviderConfig === null || paymentProviderConfig === void 0 ? void 0 : paymentProviderConfig.provider) === 'stripe'
|
|
34
|
+
? ((_g = paymentProviderConfig === null || paymentProviderConfig === void 0 ? void 0 : paymentProviderConfig.stripePublishableKey) === null || _g === void 0 ? void 0 : _g.trim()) || null
|
|
35
|
+
: null,
|
|
31
36
|
experimentId: selection.experimentId,
|
|
32
37
|
variantKey: selection.variantKey,
|
|
33
38
|
experiments: resolvedExperiments.experiments,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@funnelsgrove/payments",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.22",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/The-Solid-Grove/funnelsgrove.git",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"test:run": "vitest run --passWithNoTests"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@funnelsgrove/analytics": "^0.1.
|
|
36
|
-
"@funnelsgrove/runtime": "^0.7.
|
|
35
|
+
"@funnelsgrove/analytics": "^0.1.79",
|
|
36
|
+
"@funnelsgrove/runtime": "^0.7.30",
|
|
37
37
|
"@solidgate/react-sdk": "1.34.0",
|
|
38
38
|
"@stripe/react-stripe-js": "^5.6.0",
|
|
39
39
|
"@stripe/stripe-js": "^8.7.0",
|