@funnelsgrove/payments 0.9.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/providers/stripe/components/ApplePaySubscriptionCheckoutSlot.d.ts +3 -3
- package/dist/providers/stripe/components/ApplePaySubscriptionCheckoutSlot.js +3 -3
- package/dist/providers/stripe/components/GooglePaySubscriptionCheckoutSlot.d.ts +3 -3
- package/dist/providers/stripe/components/GooglePaySubscriptionCheckoutSlot.js +3 -3
- package/dist/providers/stripe/components/StripeOneTimeWalletSurface.d.ts +15 -0
- package/dist/providers/stripe/components/StripeOneTimeWalletSurface.js +28 -0
- package/dist/providers/stripe/components/StripeSubscriptionWalletSurface.d.ts +5 -76
- package/dist/providers/stripe/components/StripeSubscriptionWalletSurface.js +7 -170
- package/dist/providers/stripe/components/StripeWalletSurface.internal.d.ts +82 -0
- package/dist/providers/stripe/components/StripeWalletSurface.internal.js +172 -0
- package/dist/providers/stripe/components/WalletSubscriptionCheckoutSlot.d.ts +26 -6
- package/dist/providers/stripe/components/WalletSubscriptionCheckoutSlot.js +5 -4
- package/dist/providers/stripe/components/index.d.ts +1 -0
- package/dist/providers/stripe/components/index.js +1 -0
- package/dist/providers/stripe/hooks/useStripeOneTimeCheckoutSession.d.ts +7 -4
- package/dist/providers/stripe/hooks/useStripeOneTimeCheckoutSession.js +33 -5
- package/dist/providers/stripe/hooks/useStripeSubscriptionCheckoutSession.js +6 -0
- package/dist/providers/stripe/services/stripe.service.d.ts +13 -0
- package/dist/providers/stripe/services/stripe.service.js +31 -16
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Read this file before editing checkout code. Deeper implementation docs:
|
|
|
13
13
|
|
|
14
14
|
## Current Checkout Path
|
|
15
15
|
|
|
16
|
-
Render every visible wallet placement with `StripeSubscriptionWalletSurface
|
|
16
|
+
Render every visible wallet placement with `StripeSubscriptionWalletSurface` or `StripeOneTimeWalletSurface`, matching the resolved plan's payment mode. They are the normal current path for Apple Pay and Google Pay:
|
|
17
17
|
|
|
18
18
|
- Each surface owns one private Checkout Session per simultaneously visible wallet placement, isolated by its own `surfaceId`.
|
|
19
19
|
- Simultaneously visible placements may use the same plan and coupon; nothing is shared because each surface keeps its own session.
|
|
@@ -29,6 +29,8 @@ Use these for new subscription paywalls:
|
|
|
29
29
|
|
|
30
30
|
Use these for new one-time paywall plans:
|
|
31
31
|
|
|
32
|
+
- `StripeOneTimeWalletSurface`
|
|
33
|
+
- `useStripeOneTimeCheckoutSession`
|
|
32
34
|
- `createStripeOneTimeCheckout`
|
|
33
35
|
- `SharedStripeCheckoutV2Dialog`
|
|
34
36
|
|
|
@@ -46,7 +48,7 @@ provider-neutral status endpoint finds canonical shared-ledger payment evidence.
|
|
|
46
48
|
|
|
47
49
|
## Advanced Wallet Primitives
|
|
48
50
|
|
|
49
|
-
`ApplePaySubscriptionCheckoutSlot`, `GooglePaySubscriptionCheckoutSlot`, and `WalletSubscriptionCheckoutSlot` stay exported and runtime-compatible. They are backward-compatible advanced low-level primitives: reach for them only when a placement needs wiring
|
|
51
|
+
`ApplePaySubscriptionCheckoutSlot`, `GooglePaySubscriptionCheckoutSlot`, and `WalletSubscriptionCheckoutSlot` stay exported and runtime-compatible. They are backward-compatible advanced low-level primitives: reach for them only when a placement needs wiring the shared wallet surfaces do not cover. Never share one checkout hook result across placements; give each visible placement its own session.
|
|
50
52
|
|
|
51
53
|
## Compatibility-Only Surfaces
|
|
52
54
|
|
|
@@ -5,8 +5,8 @@ export type ApplePaySubscriptionCheckoutSlotProps = Omit<WalletSubscriptionCheck
|
|
|
5
5
|
placeholderLabel?: string;
|
|
6
6
|
};
|
|
7
7
|
/**
|
|
8
|
-
* @deprecated Prefer StripeSubscriptionWalletSurface for visible
|
|
9
|
-
* exported and runtime-compatible as an advanced low-level
|
|
10
|
-
* never be shared across placements.
|
|
8
|
+
* @deprecated Prefer StripeSubscriptionWalletSurface or StripeOneTimeWalletSurface for visible
|
|
9
|
+
* wallet placements. This slot stays exported and runtime-compatible as an advanced low-level
|
|
10
|
+
* primitive; its checkout session must never be shared across placements.
|
|
11
11
|
*/
|
|
12
12
|
export declare function ApplePaySubscriptionCheckoutSlot({ options, placeholderLabel, ...slotProps }: ApplePaySubscriptionCheckoutSlotProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -37,9 +37,9 @@ const applePayExpressCheckoutOptions = {
|
|
|
37
37
|
},
|
|
38
38
|
};
|
|
39
39
|
/**
|
|
40
|
-
* @deprecated Prefer StripeSubscriptionWalletSurface for visible
|
|
41
|
-
* exported and runtime-compatible as an advanced low-level
|
|
42
|
-
* never be shared across placements.
|
|
40
|
+
* @deprecated Prefer StripeSubscriptionWalletSurface or StripeOneTimeWalletSurface for visible
|
|
41
|
+
* wallet placements. This slot stays exported and runtime-compatible as an advanced low-level
|
|
42
|
+
* primitive; its checkout session must never be shared across placements.
|
|
43
43
|
*/
|
|
44
44
|
export function ApplePaySubscriptionCheckoutSlot(_a) {
|
|
45
45
|
var _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
@@ -5,8 +5,8 @@ export type GooglePaySubscriptionCheckoutSlotProps = Omit<WalletSubscriptionChec
|
|
|
5
5
|
placeholderLabel?: string;
|
|
6
6
|
};
|
|
7
7
|
/**
|
|
8
|
-
* @deprecated Prefer StripeSubscriptionWalletSurface for visible
|
|
9
|
-
* exported and runtime-compatible as an advanced low-level
|
|
10
|
-
* never be shared across placements.
|
|
8
|
+
* @deprecated Prefer StripeSubscriptionWalletSurface or StripeOneTimeWalletSurface for visible
|
|
9
|
+
* wallet placements. This slot stays exported and runtime-compatible as an advanced low-level
|
|
10
|
+
* primitive; its checkout session must never be shared across placements.
|
|
11
11
|
*/
|
|
12
12
|
export declare function GooglePaySubscriptionCheckoutSlot({ options, placeholderLabel, ...slotProps }: GooglePaySubscriptionCheckoutSlotProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -37,9 +37,9 @@ const googlePayExpressCheckoutOptions = {
|
|
|
37
37
|
},
|
|
38
38
|
};
|
|
39
39
|
/**
|
|
40
|
-
* @deprecated Prefer StripeSubscriptionWalletSurface for visible
|
|
41
|
-
* exported and runtime-compatible as an advanced low-level
|
|
42
|
-
* never be shared across placements.
|
|
40
|
+
* @deprecated Prefer StripeSubscriptionWalletSurface or StripeOneTimeWalletSurface for visible
|
|
41
|
+
* wallet placements. This slot stays exported and runtime-compatible as an advanced low-level
|
|
42
|
+
* primitive; its checkout session must never be shared across placements.
|
|
43
43
|
*/
|
|
44
44
|
export function GooglePaySubscriptionCheckoutSlot(_a) {
|
|
45
45
|
var _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type StripeOneTimeCheckoutSessionInput } from '../hooks/useStripeOneTimeCheckoutSession.js';
|
|
2
|
+
import { type StripeWalletSurfaceAvailability, type StripeWalletSurfaceErrorContext, type StripeWalletSurfaceProps } from './StripeWalletSurface.internal.js';
|
|
3
|
+
export type StripeOneTimeWalletSurfaceAvailability = StripeWalletSurfaceAvailability;
|
|
4
|
+
export type StripeOneTimeWalletSurfaceErrorContext = StripeWalletSurfaceErrorContext;
|
|
5
|
+
export type StripeOneTimeWalletSurfaceCheckoutInput = Omit<StripeOneTimeCheckoutSessionInput, 'onError'> & {
|
|
6
|
+
customerName?: string | null;
|
|
7
|
+
};
|
|
8
|
+
export type StripeOneTimeWalletSurfaceProps = Omit<StripeWalletSurfaceProps, 'applePayOptions' | 'applePayPlaceholderLabel' | 'customerEmail' | 'customerName' | 'googlePayOptions' | 'googlePayPlaceholderLabel' | 'returnUrl' | 'session'> & {
|
|
9
|
+
applePayOptions?: StripeWalletSurfaceProps['applePayOptions'];
|
|
10
|
+
applePayPlaceholderLabel?: string;
|
|
11
|
+
checkout: StripeOneTimeWalletSurfaceCheckoutInput;
|
|
12
|
+
googlePayOptions?: StripeWalletSurfaceProps['googlePayOptions'];
|
|
13
|
+
googlePayPlaceholderLabel?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function StripeOneTimeWalletSurface({ applePayOptions, applePayPlaceholderLabel, checkout, googlePayOptions, googlePayPlaceholderLabel, surfaceId, ...surfaceProps }: StripeOneTimeWalletSurfaceProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
+
import { useMemo } from 'react';
|
|
15
|
+
import { useStripeOneTimeCheckoutSession, } from '../hooks/useStripeOneTimeCheckoutSession.js';
|
|
16
|
+
import { StripeWalletSurface, buildStripeWalletSurfaceAnalyticsMetadata, } from './StripeWalletSurface.internal.js';
|
|
17
|
+
export function StripeOneTimeWalletSurface(_a) {
|
|
18
|
+
var _b, _c;
|
|
19
|
+
var { applePayOptions, applePayPlaceholderLabel = 'Buy with Apple Pay', checkout, googlePayOptions, googlePayPlaceholderLabel = 'Buy with Google Pay', surfaceId } = _a, surfaceProps = __rest(_a, ["applePayOptions", "applePayPlaceholderLabel", "checkout", "googlePayOptions", "googlePayPlaceholderLabel", "surfaceId"]);
|
|
20
|
+
const normalizedSurfaceId = surfaceId.trim();
|
|
21
|
+
const { customerName } = checkout, checkoutSessionInput = __rest(checkout, ["customerName"]);
|
|
22
|
+
const surfaceAnalyticsMetadata = useMemo(() => {
|
|
23
|
+
var _a;
|
|
24
|
+
return buildStripeWalletSurfaceAnalyticsMetadata(Object.assign(Object.assign({}, ((_a = checkout.analyticsMetadata) !== null && _a !== void 0 ? _a : {})), { paymentMode: 'one_time' }), normalizedSurfaceId);
|
|
25
|
+
}, [checkout.analyticsMetadata, normalizedSurfaceId]);
|
|
26
|
+
const session = useStripeOneTimeCheckoutSession(Object.assign(Object.assign({}, checkoutSessionInput), { analyticsMetadata: surfaceAnalyticsMetadata }));
|
|
27
|
+
return (_jsx(StripeWalletSurface, Object.assign({}, surfaceProps, { applePayOptions: Object.assign(Object.assign({}, applePayOptions), { buttonType: Object.assign({ applePay: 'buy' }, ((_b = applePayOptions === null || applePayOptions === void 0 ? void 0 : applePayOptions.buttonType) !== null && _b !== void 0 ? _b : {})) }), applePayPlaceholderLabel: applePayPlaceholderLabel, customerEmail: checkout.customerEmail, customerName: customerName, googlePayOptions: Object.assign(Object.assign({}, googlePayOptions), { buttonType: Object.assign({ googlePay: 'buy' }, ((_c = googlePayOptions === null || googlePayOptions === void 0 ? void 0 : googlePayOptions.buttonType) !== null && _c !== void 0 ? _c : {})) }), googlePayPlaceholderLabel: googlePayPlaceholderLabel, returnUrl: checkout.returnUrl, session: session, surfaceId: normalizedSurfaceId })));
|
|
28
|
+
}
|
|
@@ -1,82 +1,11 @@
|
|
|
1
|
-
import { type ReactNode } from 'react';
|
|
2
|
-
import type { Appearance, StripeCheckoutExpressCheckoutElementOptions } from '@stripe/stripe-js';
|
|
3
|
-
import { type PlatformWalletPaymentMethod } from './walletPlatform.js';
|
|
4
|
-
import type { StripeSubscriptionCheckoutAnalyticsContext } from '../services/checkoutCompletionAnalytics.service.js';
|
|
5
1
|
import { type StripeSubscriptionCheckoutSessionInput } from '../hooks/useStripeSubscriptionCheckoutSession.js';
|
|
2
|
+
import { applyStripeWalletSurfaceMethodAvailability as applyStripeSubscriptionWalletSurfaceMethodAvailability, buildStripeWalletSurfaceAnalyticsMetadata as buildStripeSubscriptionWalletSurfaceAnalyticsMetadata, buildStripeWalletSurfaceAvailability as buildStripeSubscriptionWalletSurfaceAvailability, buildStripeWalletSurfaceCheckoutAnalytics as buildStripeSubscriptionWalletSurfaceCheckoutAnalytics, getStripeWalletSurfaceMethodAvailability as getStripeSubscriptionWalletSurfaceMethodAvailability, getStripeWalletSurfaceVisibleMethods as getStripeSubscriptionWalletSurfaceVisibleMethods, normalizeStripeWalletSurfaceMethods as normalizeStripeSubscriptionWalletSurfaceMethods, resolveStripeWalletSurfaceError as resolveStripeSubscriptionWalletSurfaceError, shouldRenderStripeWalletSurface as shouldRenderStripeSubscriptionWalletSurface, type StripeWalletSurfaceAvailability as StripeSubscriptionWalletSurfaceAvailability, type StripeWalletSurfaceAvailabilityState as StripeSubscriptionWalletSurfaceAvailabilityState, type StripeWalletSurfaceErrorContext as StripeSubscriptionWalletSurfaceErrorContext, type StripeWalletSurfaceErrorEmission as StripeSubscriptionWalletSurfaceErrorEmission, type StripeWalletSurfaceErrorState as StripeSubscriptionWalletSurfaceErrorState, type StripeWalletSurfaceProps, type StripeWalletSurfaceRenderStateInput as StripeSubscriptionWalletSurfaceRenderStateInput } from './StripeWalletSurface.internal.js';
|
|
3
|
+
export { applyStripeSubscriptionWalletSurfaceMethodAvailability, buildStripeSubscriptionWalletSurfaceAnalyticsMetadata, buildStripeSubscriptionWalletSurfaceAvailability, buildStripeSubscriptionWalletSurfaceCheckoutAnalytics, getStripeSubscriptionWalletSurfaceMethodAvailability, getStripeSubscriptionWalletSurfaceVisibleMethods, normalizeStripeSubscriptionWalletSurfaceMethods, resolveStripeSubscriptionWalletSurfaceError, shouldRenderStripeSubscriptionWalletSurface, };
|
|
4
|
+
export type { StripeSubscriptionWalletSurfaceAvailability, StripeSubscriptionWalletSurfaceAvailabilityState, StripeSubscriptionWalletSurfaceErrorContext, StripeSubscriptionWalletSurfaceErrorEmission, StripeSubscriptionWalletSurfaceErrorState, StripeSubscriptionWalletSurfaceRenderStateInput, };
|
|
6
5
|
export type StripeSubscriptionWalletSurfaceCheckoutInput = Omit<StripeSubscriptionCheckoutSessionInput, 'onError'> & {
|
|
7
6
|
customerName?: string | null;
|
|
8
7
|
};
|
|
9
|
-
export type
|
|
10
|
-
anyAvailable: boolean;
|
|
11
|
-
methods: Partial<Record<PlatformWalletPaymentMethod, boolean>>;
|
|
12
|
-
resolved: boolean;
|
|
13
|
-
};
|
|
14
|
-
export type StripeSubscriptionWalletSurfaceAvailabilityState = {
|
|
15
|
-
intentKey: string;
|
|
16
|
-
methods: Partial<Record<PlatformWalletPaymentMethod, boolean>>;
|
|
17
|
-
};
|
|
18
|
-
export type StripeSubscriptionWalletSurfaceErrorContext = {
|
|
19
|
-
paymentMethod?: PlatformWalletPaymentMethod;
|
|
20
|
-
surfaceId: string;
|
|
21
|
-
};
|
|
22
|
-
export type StripeSubscriptionWalletSurfaceErrorEmission = {
|
|
23
|
-
context: StripeSubscriptionWalletSurfaceErrorContext;
|
|
24
|
-
errorState: StripeSubscriptionWalletSurfaceErrorState;
|
|
25
|
-
message: string | null;
|
|
26
|
-
};
|
|
27
|
-
export type StripeSubscriptionWalletSurfaceErrorState = {
|
|
28
|
-
methodMessages: Partial<Record<PlatformWalletPaymentMethod, string>>;
|
|
29
|
-
surfaceMessage: string | null;
|
|
30
|
-
};
|
|
31
|
-
export type StripeSubscriptionWalletSurfaceRenderStateInput = {
|
|
32
|
-
anyAvailable: boolean;
|
|
33
|
-
configured: boolean;
|
|
34
|
-
paymentMethodCount: number;
|
|
35
|
-
resolved: boolean;
|
|
36
|
-
suspended: boolean;
|
|
37
|
-
};
|
|
38
|
-
export declare function buildStripeSubscriptionWalletSurfaceAnalyticsMetadata(analyticsMetadata: Record<string, unknown> | null | undefined, surfaceId: string): Record<string, unknown>;
|
|
39
|
-
export declare function buildStripeSubscriptionWalletSurfaceCheckoutAnalytics(checkoutAnalytics: StripeSubscriptionCheckoutAnalyticsContext | null | undefined, surfaceId: string): StripeSubscriptionCheckoutAnalyticsContext | null;
|
|
40
|
-
export declare function normalizeStripeSubscriptionWalletSurfaceMethods(paymentMethods: readonly PlatformWalletPaymentMethod[]): PlatformWalletPaymentMethod[];
|
|
41
|
-
export declare function getStripeSubscriptionWalletSurfaceVisibleMethods(paymentMethods: readonly PlatformWalletPaymentMethod[], methods: Partial<Record<PlatformWalletPaymentMethod, boolean>>): PlatformWalletPaymentMethod[];
|
|
42
|
-
export declare function getStripeSubscriptionWalletSurfaceMethodAvailability(state: StripeSubscriptionWalletSurfaceAvailabilityState, intentKey: string): Partial<Record<PlatformWalletPaymentMethod, boolean>>;
|
|
43
|
-
export declare function applyStripeSubscriptionWalletSurfaceMethodAvailability(state: StripeSubscriptionWalletSurfaceAvailabilityState, intentKey: string, method: PlatformWalletPaymentMethod, available: boolean): StripeSubscriptionWalletSurfaceAvailabilityState;
|
|
44
|
-
export declare function buildStripeSubscriptionWalletSurfaceAvailability(paymentMethods: readonly PlatformWalletPaymentMethod[], methods: Partial<Record<PlatformWalletPaymentMethod, boolean>>): StripeSubscriptionWalletSurfaceAvailability;
|
|
45
|
-
export declare function shouldRenderStripeSubscriptionWalletSurface({ anyAvailable, configured, paymentMethodCount, resolved, suspended, }: StripeSubscriptionWalletSurfaceRenderStateInput): boolean;
|
|
46
|
-
export declare function resolveStripeSubscriptionWalletSurfaceError({ errorState, message, paymentMethod, surfaceId, }: {
|
|
47
|
-
errorState: StripeSubscriptionWalletSurfaceErrorState;
|
|
48
|
-
message: string | null;
|
|
49
|
-
paymentMethod?: PlatformWalletPaymentMethod;
|
|
50
|
-
surfaceId: string;
|
|
51
|
-
}): StripeSubscriptionWalletSurfaceErrorEmission | null;
|
|
52
|
-
export type StripeSubscriptionWalletSurfaceProps = {
|
|
53
|
-
amountCents: number;
|
|
54
|
-
appearance?: Appearance;
|
|
55
|
-
applePayOptions?: Partial<StripeCheckoutExpressCheckoutElementOptions>;
|
|
56
|
-
applePayPlaceholderLabel?: string;
|
|
57
|
-
beforeConfirm?: () => Promise<string | null>;
|
|
8
|
+
export type StripeSubscriptionWalletSurfaceProps = Omit<StripeWalletSurfaceProps, 'customerEmail' | 'customerName' | 'returnUrl' | 'session'> & {
|
|
58
9
|
checkout: StripeSubscriptionWalletSurfaceCheckoutInput;
|
|
59
|
-
checkoutAnalytics?: StripeSubscriptionCheckoutAnalyticsContext | null;
|
|
60
|
-
className?: string;
|
|
61
|
-
containerClassName?: string;
|
|
62
|
-
disabled?: boolean;
|
|
63
|
-
googlePayOptions?: Partial<StripeCheckoutExpressCheckoutElementOptions>;
|
|
64
|
-
googlePayPlaceholderLabel?: string;
|
|
65
|
-
onAvailabilityChange?: (availability: StripeSubscriptionWalletSurfaceAvailability) => void;
|
|
66
|
-
onCancel?: () => void;
|
|
67
|
-
onError?: (message: string | null, context: StripeSubscriptionWalletSurfaceErrorContext) => void;
|
|
68
|
-
onPaymentInfoSubmitted?: () => void | Promise<void>;
|
|
69
|
-
onSuccess?: () => void | Promise<void>;
|
|
70
|
-
onUnavailableClick?: () => Promise<void> | void;
|
|
71
|
-
paymentMethods?: readonly PlatformWalletPaymentMethod[];
|
|
72
|
-
renderHeader?: (props: {
|
|
73
|
-
availability: StripeSubscriptionWalletSurfaceAvailability;
|
|
74
|
-
}) => ReactNode;
|
|
75
|
-
resolveMethodClassName?: (method: PlatformWalletPaymentMethod) => string | undefined;
|
|
76
|
-
resolveMethodWrapperClassName?: (method: PlatformWalletPaymentMethod) => string | undefined;
|
|
77
|
-
slotClassName?: string;
|
|
78
|
-
summaryLabel: string;
|
|
79
|
-
surfaceId: string;
|
|
80
|
-
suspended?: boolean;
|
|
81
10
|
};
|
|
82
|
-
export declare function StripeSubscriptionWalletSurface({
|
|
11
|
+
export declare function StripeSubscriptionWalletSurface({ checkout, surfaceId, ...surfaceProps }: StripeSubscriptionWalletSurfaceProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,179 +10,16 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
}
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
|
-
import { jsx as _jsx
|
|
14
|
-
import {
|
|
15
|
-
import { usePlatformWalletPaymentMethods, } from './walletPlatform.js';
|
|
16
|
-
import { ApplePaySubscriptionCheckoutSlot } from './ApplePaySubscriptionCheckoutSlot.js';
|
|
17
|
-
import { GooglePaySubscriptionCheckoutSlot } from './GooglePaySubscriptionCheckoutSlot.js';
|
|
13
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
+
import { useMemo } from 'react';
|
|
18
15
|
import { useStripeSubscriptionCheckoutSession, } from '../hooks/useStripeSubscriptionCheckoutSession.js';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (!checkoutAnalytics) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
return Object.assign(Object.assign({}, checkoutAnalytics), { metadata: buildStripeSubscriptionWalletSurfaceAnalyticsMetadata(checkoutAnalytics.metadata, surfaceId) });
|
|
27
|
-
}
|
|
28
|
-
export function normalizeStripeSubscriptionWalletSurfaceMethods(paymentMethods) {
|
|
29
|
-
return paymentMethods.filter((method, index) => paymentMethods.indexOf(method) === index);
|
|
30
|
-
}
|
|
31
|
-
export function getStripeSubscriptionWalletSurfaceVisibleMethods(paymentMethods, methods) {
|
|
32
|
-
return paymentMethods.filter((method) => methods[method] !== false);
|
|
33
|
-
}
|
|
34
|
-
export function getStripeSubscriptionWalletSurfaceMethodAvailability(state, intentKey) {
|
|
35
|
-
return state.intentKey === intentKey ? state.methods : {};
|
|
36
|
-
}
|
|
37
|
-
export function applyStripeSubscriptionWalletSurfaceMethodAvailability(state, intentKey, method, available) {
|
|
38
|
-
return {
|
|
39
|
-
intentKey,
|
|
40
|
-
methods: Object.assign(Object.assign({}, getStripeSubscriptionWalletSurfaceMethodAvailability(state, intentKey)), { [method]: available }),
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
export function buildStripeSubscriptionWalletSurfaceAvailability(paymentMethods, methods) {
|
|
44
|
-
const reportedMethods = paymentMethods.filter((method) => typeof methods[method] === 'boolean');
|
|
45
|
-
return {
|
|
46
|
-
anyAvailable: reportedMethods.some((method) => methods[method] === true),
|
|
47
|
-
methods: reportedMethods.reduce((current, method) => (Object.assign(Object.assign({}, current), { [method]: methods[method] === true })), {}),
|
|
48
|
-
resolved: reportedMethods.length === paymentMethods.length,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
export function shouldRenderStripeSubscriptionWalletSurface({ anyAvailable, configured, paymentMethodCount, resolved, suspended, }) {
|
|
52
|
-
return configured && !suspended && paymentMethodCount > 0 && (!resolved || anyAvailable);
|
|
53
|
-
}
|
|
54
|
-
export function resolveStripeSubscriptionWalletSurfaceError({ errorState, message, paymentMethod, surfaceId, }) {
|
|
55
|
-
if (paymentMethod && errorState.methodMessages[paymentMethod] === message) {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
if (!paymentMethod) {
|
|
59
|
-
const methodMessages = Object.values(errorState.methodMessages);
|
|
60
|
-
if (message === null) {
|
|
61
|
-
if (errorState.surfaceMessage === null && methodMessages.length === 0) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
else if (errorState.surfaceMessage === message || methodMessages.includes(message)) {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
const nextErrorState = message === null
|
|
70
|
-
? { methodMessages: {}, surfaceMessage: null }
|
|
71
|
-
: paymentMethod
|
|
72
|
-
? Object.assign(Object.assign({}, errorState), { methodMessages: Object.assign(Object.assign({}, errorState.methodMessages), { [paymentMethod]: message }) }) : Object.assign(Object.assign({}, errorState), { surfaceMessage: message });
|
|
73
|
-
return {
|
|
74
|
-
context: Object.assign(Object.assign({}, (paymentMethod ? { paymentMethod } : {})), { surfaceId }),
|
|
75
|
-
errorState: nextErrorState,
|
|
76
|
-
message,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
// Availability identity used to notify consumers only when the aggregate actually changed.
|
|
80
|
-
function buildAvailabilitySignature(availability) {
|
|
81
|
-
return [
|
|
82
|
-
availability.resolved ? 'resolved' : 'unresolved',
|
|
83
|
-
availability.anyAvailable ? 'available' : 'unavailable',
|
|
84
|
-
Object.entries(availability.methods)
|
|
85
|
-
.map(([method, available]) => `${method}:${available ? '1' : '0'}`)
|
|
86
|
-
.sort()
|
|
87
|
-
.join(','),
|
|
88
|
-
].join('|');
|
|
89
|
-
}
|
|
90
|
-
export function StripeSubscriptionWalletSurface({ amountCents, appearance, applePayOptions, applePayPlaceholderLabel, beforeConfirm, checkout, checkoutAnalytics, className, containerClassName, disabled, googlePayOptions, googlePayPlaceholderLabel, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onSuccess, onUnavailableClick, paymentMethods, renderHeader, resolveMethodClassName, resolveMethodWrapperClassName, slotClassName, summaryLabel, surfaceId, suspended = false, }) {
|
|
91
|
-
var _a;
|
|
92
|
-
const platformWalletPaymentMethods = usePlatformWalletPaymentMethods();
|
|
93
|
-
const walletPaymentMethods = normalizeStripeSubscriptionWalletSurfaceMethods(paymentMethods !== null && paymentMethods !== void 0 ? paymentMethods : platformWalletPaymentMethods);
|
|
16
|
+
import { StripeWalletSurface, applyStripeWalletSurfaceMethodAvailability as applyStripeSubscriptionWalletSurfaceMethodAvailability, buildStripeWalletSurfaceAnalyticsMetadata as buildStripeSubscriptionWalletSurfaceAnalyticsMetadata, buildStripeWalletSurfaceAvailability as buildStripeSubscriptionWalletSurfaceAvailability, buildStripeWalletSurfaceCheckoutAnalytics as buildStripeSubscriptionWalletSurfaceCheckoutAnalytics, getStripeWalletSurfaceMethodAvailability as getStripeSubscriptionWalletSurfaceMethodAvailability, getStripeWalletSurfaceVisibleMethods as getStripeSubscriptionWalletSurfaceVisibleMethods, normalizeStripeWalletSurfaceMethods as normalizeStripeSubscriptionWalletSurfaceMethods, resolveStripeWalletSurfaceError as resolveStripeSubscriptionWalletSurfaceError, shouldRenderStripeWalletSurface as shouldRenderStripeSubscriptionWalletSurface, } from './StripeWalletSurface.internal.js';
|
|
17
|
+
export { applyStripeSubscriptionWalletSurfaceMethodAvailability, buildStripeSubscriptionWalletSurfaceAnalyticsMetadata, buildStripeSubscriptionWalletSurfaceAvailability, buildStripeSubscriptionWalletSurfaceCheckoutAnalytics, getStripeSubscriptionWalletSurfaceMethodAvailability, getStripeSubscriptionWalletSurfaceVisibleMethods, normalizeStripeSubscriptionWalletSurfaceMethods, resolveStripeSubscriptionWalletSurfaceError, shouldRenderStripeSubscriptionWalletSurface, };
|
|
18
|
+
export function StripeSubscriptionWalletSurface(_a) {
|
|
19
|
+
var { checkout, surfaceId } = _a, surfaceProps = __rest(_a, ["checkout", "surfaceId"]);
|
|
94
20
|
const normalizedSurfaceId = surfaceId.trim();
|
|
95
21
|
const { customerName } = checkout, checkoutSessionInput = __rest(checkout, ["customerName"]);
|
|
96
22
|
const surfaceAnalyticsMetadata = useMemo(() => buildStripeSubscriptionWalletSurfaceAnalyticsMetadata(checkout.analyticsMetadata, normalizedSurfaceId), [checkout.analyticsMetadata, normalizedSurfaceId]);
|
|
97
23
|
const session = useStripeSubscriptionCheckoutSession(Object.assign(Object.assign({}, checkoutSessionInput), { analyticsMetadata: surfaceAnalyticsMetadata }));
|
|
98
|
-
|
|
99
|
-
const [availabilityState, setAvailabilityState] = useState({
|
|
100
|
-
intentKey: session.intentKey,
|
|
101
|
-
methods: {},
|
|
102
|
-
});
|
|
103
|
-
const availability = buildStripeSubscriptionWalletSurfaceAvailability(walletPaymentMethods, getStripeSubscriptionWalletSurfaceMethodAvailability(availabilityState, session.intentKey));
|
|
104
|
-
const availabilitySignature = buildAvailabilitySignature(availability);
|
|
105
|
-
const reportedAvailabilitySignatureRef = useRef(null);
|
|
106
|
-
const errorStateRef = useRef({
|
|
107
|
-
methodMessages: {},
|
|
108
|
-
surfaceMessage: null,
|
|
109
|
-
});
|
|
110
|
-
const emitError = useCallback((message, paymentMethod) => {
|
|
111
|
-
const emission = resolveStripeSubscriptionWalletSurfaceError({
|
|
112
|
-
errorState: errorStateRef.current,
|
|
113
|
-
message,
|
|
114
|
-
paymentMethod,
|
|
115
|
-
surfaceId: normalizedSurfaceId,
|
|
116
|
-
});
|
|
117
|
-
if (!emission) {
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
errorStateRef.current = emission.errorState;
|
|
121
|
-
onError === null || onError === void 0 ? void 0 : onError(emission.message, emission.context);
|
|
122
|
-
}, [normalizedSurfaceId, onError]);
|
|
123
|
-
useEffect(() => {
|
|
124
|
-
if (reportedAvailabilitySignatureRef.current === availabilitySignature) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
reportedAvailabilitySignatureRef.current = availabilitySignature;
|
|
128
|
-
onAvailabilityChange === null || onAvailabilityChange === void 0 ? void 0 : onAvailabilityChange(availability);
|
|
129
|
-
}, [availability, availabilitySignature, onAvailabilityChange]);
|
|
130
|
-
useEffect(() => {
|
|
131
|
-
emitError(session.error);
|
|
132
|
-
}, [emitError, session.error]);
|
|
133
|
-
const renderWalletMethod = (method) => {
|
|
134
|
-
var _a;
|
|
135
|
-
const slotProps = {
|
|
136
|
-
amountCents,
|
|
137
|
-
appearance,
|
|
138
|
-
beforeConfirm,
|
|
139
|
-
checkoutAnalytics: surfaceCheckoutAnalytics,
|
|
140
|
-
className: (_a = resolveMethodClassName === null || resolveMethodClassName === void 0 ? void 0 : resolveMethodClassName(method)) !== null && _a !== void 0 ? _a : className,
|
|
141
|
-
customerEmail: checkout.customerEmail,
|
|
142
|
-
customerName,
|
|
143
|
-
disabled,
|
|
144
|
-
onAvailabilityChange: (available) => setAvailabilityState((current) => applyStripeSubscriptionWalletSurfaceMethodAvailability(current, session.intentKey, method, available)),
|
|
145
|
-
onCancel,
|
|
146
|
-
onError: (message) => emitError(message, method),
|
|
147
|
-
onPaymentInfoSubmitted,
|
|
148
|
-
onSuccess,
|
|
149
|
-
onUnavailableClick,
|
|
150
|
-
returnUrl: checkout.returnUrl,
|
|
151
|
-
session,
|
|
152
|
-
slotClassName,
|
|
153
|
-
summaryLabel,
|
|
154
|
-
};
|
|
155
|
-
if (method === 'applePay') {
|
|
156
|
-
return (_jsx(ApplePaySubscriptionCheckoutSlot, Object.assign({}, slotProps, { options: applePayOptions, placeholderLabel: applePayPlaceholderLabel })));
|
|
157
|
-
}
|
|
158
|
-
if (method === 'googlePay') {
|
|
159
|
-
return (_jsx(GooglePaySubscriptionCheckoutSlot, Object.assign({}, slotProps, { options: googlePayOptions, placeholderLabel: googlePayPlaceholderLabel })));
|
|
160
|
-
}
|
|
161
|
-
return null;
|
|
162
|
-
};
|
|
163
|
-
const visibleWalletPaymentMethods = getStripeSubscriptionWalletSurfaceVisibleMethods(walletPaymentMethods, availability.methods);
|
|
164
|
-
const shouldRenderSurface = shouldRenderStripeSubscriptionWalletSurface({
|
|
165
|
-
anyAvailable: availability.anyAvailable,
|
|
166
|
-
configured: session.configured,
|
|
167
|
-
paymentMethodCount: walletPaymentMethods.length,
|
|
168
|
-
resolved: availability.resolved,
|
|
169
|
-
suspended,
|
|
170
|
-
});
|
|
171
|
-
if (!shouldRenderSurface) {
|
|
172
|
-
return null;
|
|
173
|
-
}
|
|
174
|
-
return (_jsxs("div", { className: [
|
|
175
|
-
'stripe-subscription-wallet-surface',
|
|
176
|
-
containerClassName !== null && containerClassName !== void 0 ? containerClassName : '',
|
|
177
|
-
]
|
|
178
|
-
.filter(Boolean)
|
|
179
|
-
.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) => {
|
|
180
|
-
var _a;
|
|
181
|
-
return (_jsx("div", { className: [
|
|
182
|
-
'stripe-subscription-wallet-surface__method',
|
|
183
|
-
(_a = resolveMethodWrapperClassName === null || resolveMethodWrapperClassName === void 0 ? void 0 : resolveMethodWrapperClassName(method)) !== null && _a !== void 0 ? _a : '',
|
|
184
|
-
]
|
|
185
|
-
.filter(Boolean)
|
|
186
|
-
.join(' '), "data-wallet-payment-method": method, children: renderWalletMethod(method) }, method));
|
|
187
|
-
})] }));
|
|
24
|
+
return (_jsx(StripeWalletSurface, Object.assign({}, surfaceProps, { customerEmail: checkout.customerEmail, customerName: customerName, returnUrl: checkout.returnUrl, session: session, surfaceId: normalizedSurfaceId })));
|
|
188
25
|
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { Appearance, StripeCheckoutExpressCheckoutElementOptions } from '@stripe/stripe-js';
|
|
3
|
+
import { type PlatformWalletPaymentMethod } from './walletPlatform.js';
|
|
4
|
+
import type { StripeSubscriptionCheckoutAnalyticsContext } from '../services/checkoutCompletionAnalytics.service.js';
|
|
5
|
+
import type { StripeWalletCheckoutSession } from './WalletSubscriptionCheckoutSlot.js';
|
|
6
|
+
export type StripeWalletSurfaceAvailability = {
|
|
7
|
+
anyAvailable: boolean;
|
|
8
|
+
methods: Partial<Record<PlatformWalletPaymentMethod, boolean>>;
|
|
9
|
+
resolved: boolean;
|
|
10
|
+
};
|
|
11
|
+
export type StripeWalletSurfaceAvailabilityState = {
|
|
12
|
+
intentKey: string;
|
|
13
|
+
methods: Partial<Record<PlatformWalletPaymentMethod, boolean>>;
|
|
14
|
+
};
|
|
15
|
+
export type StripeWalletSurfaceErrorContext = {
|
|
16
|
+
paymentMethod?: PlatformWalletPaymentMethod;
|
|
17
|
+
surfaceId: string;
|
|
18
|
+
};
|
|
19
|
+
export type StripeWalletSurfaceErrorEmission = {
|
|
20
|
+
context: StripeWalletSurfaceErrorContext;
|
|
21
|
+
errorState: StripeWalletSurfaceErrorState;
|
|
22
|
+
message: string | null;
|
|
23
|
+
};
|
|
24
|
+
export type StripeWalletSurfaceErrorState = {
|
|
25
|
+
methodMessages: Partial<Record<PlatformWalletPaymentMethod, string>>;
|
|
26
|
+
surfaceMessage: string | null;
|
|
27
|
+
};
|
|
28
|
+
export type StripeWalletSurfaceRenderStateInput = {
|
|
29
|
+
anyAvailable: boolean;
|
|
30
|
+
configured: boolean;
|
|
31
|
+
paymentMethodCount: number;
|
|
32
|
+
resolved: boolean;
|
|
33
|
+
suspended: boolean;
|
|
34
|
+
};
|
|
35
|
+
export declare function buildStripeWalletSurfaceAnalyticsMetadata(analyticsMetadata: Record<string, unknown> | null | undefined, surfaceId: string): Record<string, unknown>;
|
|
36
|
+
export declare function buildStripeWalletSurfaceCheckoutAnalytics(checkoutAnalytics: StripeSubscriptionCheckoutAnalyticsContext | null | undefined, surfaceId: string): StripeSubscriptionCheckoutAnalyticsContext | null;
|
|
37
|
+
export declare function normalizeStripeWalletSurfaceMethods(paymentMethods: readonly PlatformWalletPaymentMethod[]): PlatformWalletPaymentMethod[];
|
|
38
|
+
export declare function getStripeWalletSurfaceVisibleMethods(paymentMethods: readonly PlatformWalletPaymentMethod[], methods: Partial<Record<PlatformWalletPaymentMethod, boolean>>): PlatformWalletPaymentMethod[];
|
|
39
|
+
export declare function getStripeWalletSurfaceMethodAvailability(state: StripeWalletSurfaceAvailabilityState, intentKey: string): Partial<Record<PlatformWalletPaymentMethod, boolean>>;
|
|
40
|
+
export declare function applyStripeWalletSurfaceMethodAvailability(state: StripeWalletSurfaceAvailabilityState, intentKey: string, method: PlatformWalletPaymentMethod, available: boolean): StripeWalletSurfaceAvailabilityState;
|
|
41
|
+
export declare function buildStripeWalletSurfaceAvailability(paymentMethods: readonly PlatformWalletPaymentMethod[], methods: Partial<Record<PlatformWalletPaymentMethod, boolean>>): StripeWalletSurfaceAvailability;
|
|
42
|
+
export declare function shouldRenderStripeWalletSurface({ anyAvailable, configured, paymentMethodCount, resolved, suspended, }: StripeWalletSurfaceRenderStateInput): boolean;
|
|
43
|
+
export declare function resolveStripeWalletSurfaceError({ errorState, message, paymentMethod, surfaceId, }: {
|
|
44
|
+
errorState: StripeWalletSurfaceErrorState;
|
|
45
|
+
message: string | null;
|
|
46
|
+
paymentMethod?: PlatformWalletPaymentMethod;
|
|
47
|
+
surfaceId: string;
|
|
48
|
+
}): StripeWalletSurfaceErrorEmission | null;
|
|
49
|
+
export type StripeWalletSurfaceProps = {
|
|
50
|
+
amountCents: number;
|
|
51
|
+
appearance?: Appearance;
|
|
52
|
+
applePayOptions?: Partial<StripeCheckoutExpressCheckoutElementOptions>;
|
|
53
|
+
applePayPlaceholderLabel?: string;
|
|
54
|
+
beforeConfirm?: () => Promise<string | null>;
|
|
55
|
+
checkoutAnalytics?: StripeSubscriptionCheckoutAnalyticsContext | null;
|
|
56
|
+
className?: string;
|
|
57
|
+
containerClassName?: string;
|
|
58
|
+
customerEmail?: string | null;
|
|
59
|
+
customerName?: string | null;
|
|
60
|
+
disabled?: boolean;
|
|
61
|
+
googlePayOptions?: Partial<StripeCheckoutExpressCheckoutElementOptions>;
|
|
62
|
+
googlePayPlaceholderLabel?: string;
|
|
63
|
+
onAvailabilityChange?: (availability: StripeWalletSurfaceAvailability) => void;
|
|
64
|
+
onCancel?: () => void;
|
|
65
|
+
onError?: (message: string | null, context: StripeWalletSurfaceErrorContext) => void;
|
|
66
|
+
onPaymentInfoSubmitted?: () => void | Promise<void>;
|
|
67
|
+
onSuccess?: () => void | Promise<void>;
|
|
68
|
+
onUnavailableClick?: () => Promise<void> | void;
|
|
69
|
+
paymentMethods?: readonly PlatformWalletPaymentMethod[];
|
|
70
|
+
renderHeader?: (props: {
|
|
71
|
+
availability: StripeWalletSurfaceAvailability;
|
|
72
|
+
}) => ReactNode;
|
|
73
|
+
resolveMethodClassName?: (method: PlatformWalletPaymentMethod) => string | undefined;
|
|
74
|
+
resolveMethodWrapperClassName?: (method: PlatformWalletPaymentMethod) => string | undefined;
|
|
75
|
+
returnUrl: string;
|
|
76
|
+
session: StripeWalletCheckoutSession;
|
|
77
|
+
slotClassName?: string;
|
|
78
|
+
summaryLabel: string;
|
|
79
|
+
surfaceId: string;
|
|
80
|
+
suspended?: boolean;
|
|
81
|
+
};
|
|
82
|
+
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;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { usePlatformWalletPaymentMethods, } from './walletPlatform.js';
|
|
5
|
+
import { ApplePaySubscriptionCheckoutSlot } from './ApplePaySubscriptionCheckoutSlot.js';
|
|
6
|
+
import { GooglePaySubscriptionCheckoutSlot } from './GooglePaySubscriptionCheckoutSlot.js';
|
|
7
|
+
export function buildStripeWalletSurfaceAnalyticsMetadata(analyticsMetadata, surfaceId) {
|
|
8
|
+
return Object.assign(Object.assign({}, (analyticsMetadata !== null && analyticsMetadata !== void 0 ? analyticsMetadata : {})), { checkoutSurfaceId: surfaceId });
|
|
9
|
+
}
|
|
10
|
+
export function buildStripeWalletSurfaceCheckoutAnalytics(checkoutAnalytics, surfaceId) {
|
|
11
|
+
if (!checkoutAnalytics) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
return Object.assign(Object.assign({}, checkoutAnalytics), { metadata: buildStripeWalletSurfaceAnalyticsMetadata(checkoutAnalytics.metadata, surfaceId) });
|
|
15
|
+
}
|
|
16
|
+
export function normalizeStripeWalletSurfaceMethods(paymentMethods) {
|
|
17
|
+
return paymentMethods.filter((method, index) => paymentMethods.indexOf(method) === index);
|
|
18
|
+
}
|
|
19
|
+
export function getStripeWalletSurfaceVisibleMethods(paymentMethods, methods) {
|
|
20
|
+
return paymentMethods.filter((method) => methods[method] !== false);
|
|
21
|
+
}
|
|
22
|
+
export function getStripeWalletSurfaceMethodAvailability(state, intentKey) {
|
|
23
|
+
return state.intentKey === intentKey ? state.methods : {};
|
|
24
|
+
}
|
|
25
|
+
export function applyStripeWalletSurfaceMethodAvailability(state, intentKey, method, available) {
|
|
26
|
+
return {
|
|
27
|
+
intentKey,
|
|
28
|
+
methods: Object.assign(Object.assign({}, getStripeWalletSurfaceMethodAvailability(state, intentKey)), { [method]: available }),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function buildStripeWalletSurfaceAvailability(paymentMethods, methods) {
|
|
32
|
+
const reportedMethods = paymentMethods.filter((method) => typeof methods[method] === 'boolean');
|
|
33
|
+
return {
|
|
34
|
+
anyAvailable: reportedMethods.some((method) => methods[method] === true),
|
|
35
|
+
methods: reportedMethods.reduce((current, method) => (Object.assign(Object.assign({}, current), { [method]: methods[method] === true })), {}),
|
|
36
|
+
resolved: reportedMethods.length === paymentMethods.length,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function shouldRenderStripeWalletSurface({ anyAvailable, configured, paymentMethodCount, resolved, suspended, }) {
|
|
40
|
+
return configured && !suspended && paymentMethodCount > 0 && (!resolved || anyAvailable);
|
|
41
|
+
}
|
|
42
|
+
export function resolveStripeWalletSurfaceError({ errorState, message, paymentMethod, surfaceId, }) {
|
|
43
|
+
if (paymentMethod && errorState.methodMessages[paymentMethod] === message) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
if (!paymentMethod) {
|
|
47
|
+
const methodMessages = Object.values(errorState.methodMessages);
|
|
48
|
+
if (message === null) {
|
|
49
|
+
if (errorState.surfaceMessage === null && methodMessages.length === 0) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (errorState.surfaceMessage === message || methodMessages.includes(message)) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const nextErrorState = message === null
|
|
58
|
+
? { methodMessages: {}, surfaceMessage: null }
|
|
59
|
+
: paymentMethod
|
|
60
|
+
? Object.assign(Object.assign({}, errorState), { methodMessages: Object.assign(Object.assign({}, errorState.methodMessages), { [paymentMethod]: message }) }) : Object.assign(Object.assign({}, errorState), { surfaceMessage: message });
|
|
61
|
+
return {
|
|
62
|
+
context: Object.assign(Object.assign({}, (paymentMethod ? { paymentMethod } : {})), { surfaceId }),
|
|
63
|
+
errorState: nextErrorState,
|
|
64
|
+
message,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function buildAvailabilitySignature(availability) {
|
|
68
|
+
return [
|
|
69
|
+
availability.resolved ? 'resolved' : 'unresolved',
|
|
70
|
+
availability.anyAvailable ? 'available' : 'unavailable',
|
|
71
|
+
Object.entries(availability.methods)
|
|
72
|
+
.map(([method, available]) => `${method}:${available ? '1' : '0'}`)
|
|
73
|
+
.sort()
|
|
74
|
+
.join(','),
|
|
75
|
+
].join('|');
|
|
76
|
+
}
|
|
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
|
+
const platformWalletPaymentMethods = usePlatformWalletPaymentMethods();
|
|
80
|
+
const walletPaymentMethods = normalizeStripeWalletSurfaceMethods(paymentMethods !== null && paymentMethods !== void 0 ? paymentMethods : platformWalletPaymentMethods);
|
|
81
|
+
const normalizedSurfaceId = surfaceId.trim();
|
|
82
|
+
const surfaceCheckoutAnalytics = useMemo(() => buildStripeWalletSurfaceCheckoutAnalytics(checkoutAnalytics, normalizedSurfaceId), [checkoutAnalytics, normalizedSurfaceId]);
|
|
83
|
+
const [availabilityState, setAvailabilityState] = useState({
|
|
84
|
+
intentKey: session.intentKey,
|
|
85
|
+
methods: {},
|
|
86
|
+
});
|
|
87
|
+
const availability = buildStripeWalletSurfaceAvailability(walletPaymentMethods, getStripeWalletSurfaceMethodAvailability(availabilityState, session.intentKey));
|
|
88
|
+
const availabilitySignature = buildAvailabilitySignature(availability);
|
|
89
|
+
const reportedAvailabilitySignatureRef = useRef(null);
|
|
90
|
+
const errorStateRef = useRef({
|
|
91
|
+
methodMessages: {},
|
|
92
|
+
surfaceMessage: null,
|
|
93
|
+
});
|
|
94
|
+
const emitError = useCallback((message, paymentMethod) => {
|
|
95
|
+
const emission = resolveStripeWalletSurfaceError({
|
|
96
|
+
errorState: errorStateRef.current,
|
|
97
|
+
message,
|
|
98
|
+
paymentMethod,
|
|
99
|
+
surfaceId: normalizedSurfaceId,
|
|
100
|
+
});
|
|
101
|
+
if (!emission) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
errorStateRef.current = emission.errorState;
|
|
105
|
+
onError === null || onError === void 0 ? void 0 : onError(emission.message, emission.context);
|
|
106
|
+
}, [normalizedSurfaceId, onError]);
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (reportedAvailabilitySignatureRef.current === availabilitySignature) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
reportedAvailabilitySignatureRef.current = availabilitySignature;
|
|
112
|
+
onAvailabilityChange === null || onAvailabilityChange === void 0 ? void 0 : onAvailabilityChange(availability);
|
|
113
|
+
}, [availability, availabilitySignature, onAvailabilityChange]);
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
emitError(session.error);
|
|
116
|
+
}, [emitError, session.error]);
|
|
117
|
+
const renderWalletMethod = (method) => {
|
|
118
|
+
var _a;
|
|
119
|
+
const slotProps = {
|
|
120
|
+
amountCents,
|
|
121
|
+
appearance,
|
|
122
|
+
beforeConfirm,
|
|
123
|
+
checkoutAnalytics: surfaceCheckoutAnalytics,
|
|
124
|
+
className: (_a = resolveMethodClassName === null || resolveMethodClassName === void 0 ? void 0 : resolveMethodClassName(method)) !== null && _a !== void 0 ? _a : className,
|
|
125
|
+
customerEmail,
|
|
126
|
+
customerName,
|
|
127
|
+
disabled,
|
|
128
|
+
onAvailabilityChange: (available) => setAvailabilityState((current) => applyStripeWalletSurfaceMethodAvailability(current, session.intentKey, method, available)),
|
|
129
|
+
onCancel,
|
|
130
|
+
onError: (message) => emitError(message, method),
|
|
131
|
+
onPaymentInfoSubmitted,
|
|
132
|
+
onSuccess,
|
|
133
|
+
onUnavailableClick,
|
|
134
|
+
returnUrl,
|
|
135
|
+
session,
|
|
136
|
+
slotClassName,
|
|
137
|
+
summaryLabel,
|
|
138
|
+
};
|
|
139
|
+
if (method === 'applePay') {
|
|
140
|
+
return (_jsx(ApplePaySubscriptionCheckoutSlot, Object.assign({}, slotProps, { options: applePayOptions, placeholderLabel: applePayPlaceholderLabel })));
|
|
141
|
+
}
|
|
142
|
+
if (method === 'googlePay') {
|
|
143
|
+
return (_jsx(GooglePaySubscriptionCheckoutSlot, Object.assign({}, slotProps, { options: googlePayOptions, placeholderLabel: googlePayPlaceholderLabel })));
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
};
|
|
147
|
+
const visibleWalletPaymentMethods = getStripeWalletSurfaceVisibleMethods(walletPaymentMethods, availability.methods);
|
|
148
|
+
const shouldRenderSurface = shouldRenderStripeWalletSurface({
|
|
149
|
+
anyAvailable: availability.anyAvailable,
|
|
150
|
+
configured: session.configured,
|
|
151
|
+
paymentMethodCount: walletPaymentMethods.length,
|
|
152
|
+
resolved: availability.resolved,
|
|
153
|
+
suspended,
|
|
154
|
+
});
|
|
155
|
+
if (!shouldRenderSurface) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
return (_jsxs("div", { className: [
|
|
159
|
+
'stripe-subscription-wallet-surface',
|
|
160
|
+
containerClassName !== null && containerClassName !== void 0 ? containerClassName : '',
|
|
161
|
+
]
|
|
162
|
+
.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) => {
|
|
164
|
+
var _a;
|
|
165
|
+
return (_jsx("div", { className: [
|
|
166
|
+
'stripe-subscription-wallet-surface__method',
|
|
167
|
+
(_a = resolveMethodWrapperClassName === null || resolveMethodWrapperClassName === void 0 ? void 0 : resolveMethodWrapperClassName(method)) !== null && _a !== void 0 ? _a : '',
|
|
168
|
+
]
|
|
169
|
+
.filter(Boolean)
|
|
170
|
+
.join(' '), "data-wallet-payment-method": method, children: renderWalletMethod(method) }, method));
|
|
171
|
+
})] }));
|
|
172
|
+
}
|
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
-
import type { Appearance, AvailablePaymentMethods, StripeCheckoutExpressCheckoutElementOptions } from '@stripe/stripe-js';
|
|
2
|
+
import type { Appearance, AvailablePaymentMethods, Stripe, StripeCheckoutExpressCheckoutElementOptions } from '@stripe/stripe-js';
|
|
3
3
|
import { type StripeSubscriptionCheckoutAnalyticsContext } from '../services/checkoutCompletionAnalytics.service.js';
|
|
4
|
-
import {
|
|
4
|
+
import type { CheckoutPreparationLoading } from '../../paymentProvider.types.js';
|
|
5
|
+
export type StripeWalletCheckoutPreparationOptions = {
|
|
6
|
+
checkoutStartSource?: 'card_click' | 'checkout_render' | 'wallet_click' | 'wallet_render' | (string & {});
|
|
7
|
+
forceNew?: boolean;
|
|
8
|
+
paymentMethod?: unknown;
|
|
9
|
+
};
|
|
10
|
+
export type StripeWalletCheckoutSession = {
|
|
11
|
+
activeClientSecret: string | null;
|
|
12
|
+
activePlanKey?: string | null;
|
|
13
|
+
checkoutSessionId: string | null;
|
|
14
|
+
configured: boolean;
|
|
15
|
+
error: string | null;
|
|
16
|
+
intentKey: string;
|
|
17
|
+
loading: CheckoutPreparationLoading;
|
|
18
|
+
planKey: string;
|
|
19
|
+
prepareWalletCheckout: (options?: StripeWalletCheckoutPreparationOptions) => Promise<string | null>;
|
|
20
|
+
restartWalletCheckout: (options?: StripeWalletCheckoutPreparationOptions) => Promise<string | null>;
|
|
21
|
+
setError: (message: string | null) => void;
|
|
22
|
+
stripePromise: Promise<Stripe | null> | null;
|
|
23
|
+
updateCheckoutSessionPlan?: () => Promise<boolean>;
|
|
24
|
+
};
|
|
5
25
|
export type WalletSubscriptionCheckoutRenderStateInput = {
|
|
6
26
|
expressCheckoutAllowed: boolean;
|
|
7
27
|
hasActiveClientSecret: boolean;
|
|
@@ -44,16 +64,16 @@ export type WalletSubscriptionCheckoutSlotProps = {
|
|
|
44
64
|
renderPreparingPlaceholder?: (props: WalletPlaceholderButtonProps) => ReactNode;
|
|
45
65
|
renderPlaceholder: (props: WalletPlaceholderButtonProps) => ReactNode;
|
|
46
66
|
returnUrl: string;
|
|
47
|
-
session:
|
|
67
|
+
session: StripeWalletCheckoutSession;
|
|
48
68
|
slotClassName?: string;
|
|
49
69
|
summaryLabel: string;
|
|
50
70
|
suspended?: boolean;
|
|
51
71
|
};
|
|
52
72
|
export declare function WalletSubscriptionCheckoutLoadingPlaceholder({ className, label, }: Pick<WalletPlaceholderButtonProps, 'className' | 'label'>): import("react/jsx-runtime").JSX.Element;
|
|
53
73
|
/**
|
|
54
|
-
* @deprecated Prefer StripeSubscriptionWalletSurface for visible
|
|
55
|
-
* exported and runtime-compatible as an advanced low-level
|
|
56
|
-
* never be shared across placements.
|
|
74
|
+
* @deprecated Prefer StripeSubscriptionWalletSurface or StripeOneTimeWalletSurface for visible
|
|
75
|
+
* wallet placements. This slot stays exported and runtime-compatible as an advanced low-level
|
|
76
|
+
* primitive; its checkout session must never be shared across placements.
|
|
57
77
|
*/
|
|
58
78
|
export declare function WalletSubscriptionCheckoutSlot({ amountCents, appearance, availabilityPaymentMethod, beforeConfirm, checkoutAnalytics, className, customerEmail, customerName, disabled, expressCheckoutAllowed, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onSuccess, onUnavailableClick, options, placeholderLabel, renderPreparingPlaceholder, renderPlaceholder, returnUrl, session, slotClassName, summaryLabel, suspended, }: WalletSubscriptionCheckoutSlotProps): import("react/jsx-runtime").JSX.Element;
|
|
59
79
|
export {};
|
|
@@ -30,9 +30,9 @@ export function WalletSubscriptionCheckoutLoadingPlaceholder({ className, label,
|
|
|
30
30
|
.join(' '), "aria-label": label, role: 'status', children: [_jsx("span", { className: 'wallet-subscription-checkout-slot__loading-bar' }), _jsx("style", { children: walletSubscriptionCheckoutLoadingPlaceholderStyles })] }));
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
* @deprecated Prefer StripeSubscriptionWalletSurface for visible
|
|
34
|
-
* exported and runtime-compatible as an advanced low-level
|
|
35
|
-
* never be shared across placements.
|
|
33
|
+
* @deprecated Prefer StripeSubscriptionWalletSurface or StripeOneTimeWalletSurface for visible
|
|
34
|
+
* wallet placements. This slot stays exported and runtime-compatible as an advanced low-level
|
|
35
|
+
* primitive; its checkout session must never be shared across placements.
|
|
36
36
|
*/
|
|
37
37
|
export function WalletSubscriptionCheckoutSlot({ amountCents, appearance, availabilityPaymentMethod, beforeConfirm, checkoutAnalytics, className, customerEmail, customerName, disabled = false, expressCheckoutAllowed = true, onAvailabilityChange, onCancel, onError, onPaymentInfoSubmitted, onSuccess, onUnavailableClick, options, placeholderLabel, renderPreparingPlaceholder, renderPlaceholder, returnUrl, session, slotClassName, summaryLabel, suspended = false, }) {
|
|
38
38
|
const [walletAvailability, setWalletAvailability] = useState({
|
|
@@ -55,7 +55,8 @@ export function WalletSubscriptionCheckoutSlot({ amountCents, appearance, availa
|
|
|
55
55
|
walletAvailable,
|
|
56
56
|
walletPreparing: session.loading.wallet,
|
|
57
57
|
});
|
|
58
|
-
const serverUpdateKey = session.
|
|
58
|
+
const serverUpdateKey = session.updateCheckoutSessionPlan &&
|
|
59
|
+
session.activeClientSecret &&
|
|
59
60
|
session.checkoutSessionId &&
|
|
60
61
|
session.activePlanKey !== session.planKey
|
|
61
62
|
? session.planKey
|
|
@@ -7,6 +7,7 @@ export * from './SharedStripeCheckoutV2Dialog.js';
|
|
|
7
7
|
export * from './StripeCheckoutExpressCheckoutButton.js';
|
|
8
8
|
export * from './StripeExpressCheckoutButton.js';
|
|
9
9
|
export * from './StripeExpressCheckoutElement.js';
|
|
10
|
+
export * from './StripeOneTimeWalletSurface.js';
|
|
10
11
|
export * from './StripePlanSelector.js';
|
|
11
12
|
export * from './StripeSubscriptionWalletSurface.js';
|
|
12
13
|
export * from './WalletSubscriptionCheckoutSlot.js';
|
|
@@ -7,6 +7,7 @@ export * from './SharedStripeCheckoutV2Dialog.js';
|
|
|
7
7
|
export * from './StripeCheckoutExpressCheckoutButton.js';
|
|
8
8
|
export * from './StripeExpressCheckoutButton.js';
|
|
9
9
|
export * from './StripeExpressCheckoutElement.js';
|
|
10
|
+
export * from './StripeOneTimeWalletSurface.js';
|
|
10
11
|
export * from './StripePlanSelector.js';
|
|
11
12
|
export * from './StripeSubscriptionWalletSurface.js';
|
|
12
13
|
export * from './WalletSubscriptionCheckoutSlot.js';
|
|
@@ -2,8 +2,11 @@ import type { Stripe } from '@stripe/stripe-js';
|
|
|
2
2
|
import type { RuntimeMode } from '@funnelsgrove/runtime';
|
|
3
3
|
import { type CheckoutPreparationLoading, type CheckoutPreparationSource } from '../../paymentProvider.types.js';
|
|
4
4
|
import { type PaywallPlan, type StripeRuntimeConfigOverrides } from '../services/stripe.service.js';
|
|
5
|
-
type StripeOneTimeCheckoutPlanInput = Pick<PaywallPlan, 'amountCents' | 'analyticsPurchaseValue' | 'description' | 'id' | 'providerPlanId' | 'title'>;
|
|
5
|
+
type StripeOneTimeCheckoutPlanInput = Pick<PaywallPlan, 'amountCents' | 'analyticsPurchaseValue' | 'description' | 'id' | 'providerPlanId' | 'title' | 'funnelPlanKey' | 'offerSetId' | 'offerSetKey'>;
|
|
6
6
|
export type StripeOneTimeCheckoutSessionInput = {
|
|
7
|
+
runtimeConfigRevisionId?: string | null;
|
|
8
|
+
paymentProfileId?: string | null;
|
|
9
|
+
provider?: 'stripe' | null;
|
|
7
10
|
analyticsMetadata?: Record<string, unknown> | null;
|
|
8
11
|
checkoutMode: RuntimeMode;
|
|
9
12
|
couponId?: string | null;
|
|
@@ -40,10 +43,10 @@ export type StripeOneTimeCheckoutSession = {
|
|
|
40
43
|
stripePromise: Promise<Stripe | null> | null;
|
|
41
44
|
};
|
|
42
45
|
export declare const buildStripeOneTimeCheckoutPreparationAnalyticsMetadata: (analyticsMetadata: Record<string, unknown> | null | undefined, options?: StripeOneTimeCheckoutPreparationOptions) => Record<string, unknown> | null | undefined;
|
|
43
|
-
export type StripeOneTimeCheckoutIntentKeyInput = Pick<StripeOneTimeCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'plan' | 'returnUrl' | 'runtimeConfig' | 'stripePublishableKey' | 'userId'> & {
|
|
46
|
+
export type StripeOneTimeCheckoutIntentKeyInput = Pick<StripeOneTimeCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'plan' | 'returnUrl' | 'runtimeConfig' | 'stripePublishableKey' | 'userId' | 'runtimeConfigRevisionId' | 'paymentProfileId' | 'provider'> & {
|
|
44
47
|
analyticsMetadata?: Record<string, unknown> | null;
|
|
45
48
|
};
|
|
46
|
-
export declare function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutIntentKeyInput): string;
|
|
49
|
+
export declare function buildStripeOneTimeCheckoutIntentKey({ runtimeConfigRevisionId, paymentProfileId, provider, checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutIntentKeyInput): string;
|
|
47
50
|
export declare function shouldResetStripeOneTimeCheckoutSessionForIntentKey(previousIntentKey: string | null, nextIntentKey: string): boolean;
|
|
48
|
-
export declare function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutSessionInput): StripeOneTimeCheckoutSession;
|
|
51
|
+
export declare function useStripeOneTimeCheckoutSession({ runtimeConfigRevisionId, paymentProfileId, provider, analyticsMetadata, checkoutMode, couponId, customerEmail, enabled, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutSessionInput): StripeOneTimeCheckoutSession;
|
|
49
52
|
export {};
|
|
@@ -36,9 +36,13 @@ 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, stripePublishableKey, userId, }) {
|
|
40
|
-
var _a;
|
|
39
|
+
export function buildStripeOneTimeCheckoutIntentKey({ runtimeConfigRevisionId, paymentProfileId, provider, checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
|
|
40
|
+
var _a, _b, _c, _d;
|
|
41
41
|
const runtimeConfigSignature = [
|
|
42
|
+
(_a = runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.paymentsApiVersion) !== null && _a !== void 0 ? _a : 'v1',
|
|
43
|
+
runtimeConfigRevisionId !== null && runtimeConfigRevisionId !== void 0 ? runtimeConfigRevisionId : '',
|
|
44
|
+
paymentProfileId !== null && paymentProfileId !== void 0 ? paymentProfileId : '',
|
|
45
|
+
provider !== null && provider !== void 0 ? provider : '',
|
|
42
46
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.apiBaseUrl),
|
|
43
47
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelId),
|
|
44
48
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelVersionId),
|
|
@@ -46,9 +50,11 @@ export function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, cu
|
|
|
46
50
|
normalizeRuntimeConfigValue(stripePublishableKey),
|
|
47
51
|
].join('|');
|
|
48
52
|
const planSignature = [
|
|
53
|
+
(_b = plan === null || plan === void 0 ? void 0 : plan.offerSetId) !== null && _b !== void 0 ? _b : '',
|
|
54
|
+
(_c = plan === null || plan === void 0 ? void 0 : plan.funnelPlanKey) !== null && _c !== void 0 ? _c : '',
|
|
49
55
|
normalizeRuntimeConfigValue(plan === null || plan === void 0 ? void 0 : plan.id),
|
|
50
56
|
normalizeRuntimeConfigValue(plan === null || plan === void 0 ? void 0 : plan.providerPlanId),
|
|
51
|
-
(
|
|
57
|
+
(_d = plan === null || plan === void 0 ? void 0 : plan.amountCents) !== null && _d !== void 0 ? _d : '',
|
|
52
58
|
].join('|');
|
|
53
59
|
const customerEmailSignature = normalizeRuntimeConfigValue(customerEmail);
|
|
54
60
|
const userIdSignature = normalizeRuntimeConfigValue(userId);
|
|
@@ -66,7 +72,7 @@ export function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, cu
|
|
|
66
72
|
export function shouldResetStripeOneTimeCheckoutSessionForIntentKey(previousIntentKey, nextIntentKey) {
|
|
67
73
|
return previousIntentKey !== null && previousIntentKey !== nextIntentKey;
|
|
68
74
|
}
|
|
69
|
-
export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled = true, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
|
|
75
|
+
export function useStripeOneTimeCheckoutSession({ runtimeConfigRevisionId, paymentProfileId, provider, analyticsMetadata, checkoutMode, couponId, customerEmail, enabled = true, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
|
|
70
76
|
var _a, _b, _c;
|
|
71
77
|
const [clientSecret, setClientSecret] = useState(null);
|
|
72
78
|
const [clientSecretIntentKey, setClientSecretIntentKey] = useState(null);
|
|
@@ -76,11 +82,16 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
|
|
|
76
82
|
const [runtimeStripePublishableKey, setRuntimeStripePublishableKey] = useState(null);
|
|
77
83
|
const creatingIntentRef = useRef(null);
|
|
78
84
|
const requestIdRef = useRef(0);
|
|
85
|
+
const attemptRef = useRef(null);
|
|
86
|
+
const anonymousUserIdRef = useRef(null);
|
|
79
87
|
const configured = enabled &&
|
|
80
88
|
(isStripeConfigured(checkoutMode) ||
|
|
81
89
|
Boolean(normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey)) ||
|
|
82
90
|
Boolean(normalizeRuntimeConfigValue(stripePublishableKey)));
|
|
83
91
|
const intentKey = buildStripeOneTimeCheckoutIntentKey({
|
|
92
|
+
runtimeConfigRevisionId,
|
|
93
|
+
paymentProfileId,
|
|
94
|
+
provider,
|
|
84
95
|
checkoutMode,
|
|
85
96
|
couponId,
|
|
86
97
|
customerEmail,
|
|
@@ -124,6 +135,7 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
|
|
|
124
135
|
onError === null || onError === void 0 ? void 0 : onError(message);
|
|
125
136
|
}, [clearActiveCheckoutSession, onError]);
|
|
126
137
|
const reset = useCallback(() => {
|
|
138
|
+
attemptRef.current = null;
|
|
127
139
|
clearActiveCheckoutSession();
|
|
128
140
|
setLoading(createEmptyCheckoutPreparationLoading());
|
|
129
141
|
setRuntimeStripePublishableKey(null);
|
|
@@ -142,7 +154,7 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
|
|
|
142
154
|
: Object.assign(Object.assign({}, current), { [source]: value }));
|
|
143
155
|
}, []);
|
|
144
156
|
const createCheckoutSession = useCallback(async (options = {}) => {
|
|
145
|
-
var _a;
|
|
157
|
+
var _a, _b, _c;
|
|
146
158
|
const forceNew = options.forceNew === true;
|
|
147
159
|
if (!configured || !plan) {
|
|
148
160
|
return null;
|
|
@@ -155,6 +167,14 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
|
|
|
155
167
|
}
|
|
156
168
|
if (forceNew) {
|
|
157
169
|
clearActiveCheckoutSession();
|
|
170
|
+
attemptRef.current = null;
|
|
171
|
+
}
|
|
172
|
+
if ((runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.paymentsApiVersion) === 'v2' && ((_b = attemptRef.current) === null || _b === void 0 ? void 0 : _b.key) !== intentKey) {
|
|
173
|
+
attemptRef.current = { key: intentKey, id: crypto.randomUUID() };
|
|
174
|
+
}
|
|
175
|
+
const idempotencyKey = (_c = attemptRef.current) === null || _c === void 0 ? void 0 : _c.id;
|
|
176
|
+
if (idempotencyKey && !userId && !anonymousUserIdRef.current) {
|
|
177
|
+
anonymousUserIdRef.current = `anonymous_${crypto.randomUUID()}`;
|
|
158
178
|
}
|
|
159
179
|
const requestKey = intentKey;
|
|
160
180
|
const requestId = requestIdRef.current + 1;
|
|
@@ -163,6 +183,11 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
|
|
|
163
183
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
164
184
|
try {
|
|
165
185
|
const response = await createStripeOneTimeCheckout({
|
|
186
|
+
idempotencyKey,
|
|
187
|
+
anonymousUserId: anonymousUserIdRef.current,
|
|
188
|
+
runtimeConfigRevisionId,
|
|
189
|
+
paymentProfileId,
|
|
190
|
+
provider,
|
|
166
191
|
plan,
|
|
167
192
|
analyticsMetadata: buildStripeOneTimeCheckoutPreparationAnalyticsMetadata(analyticsMetadataRef.current, options),
|
|
168
193
|
couponId,
|
|
@@ -208,6 +233,9 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
|
|
|
208
233
|
return checkoutRequest;
|
|
209
234
|
}, [
|
|
210
235
|
activeClientSecret,
|
|
236
|
+
runtimeConfigRevisionId,
|
|
237
|
+
paymentProfileId,
|
|
238
|
+
provider,
|
|
211
239
|
checkoutMode,
|
|
212
240
|
clearActiveCheckoutSession,
|
|
213
241
|
configured,
|
|
@@ -278,6 +278,9 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
|
|
|
278
278
|
await updateStripeSubscriptionCheckoutPlan({
|
|
279
279
|
checkoutSessionId: activeCheckoutSessionId,
|
|
280
280
|
plan,
|
|
281
|
+
runtimeConfigRevisionId,
|
|
282
|
+
paymentProfileId,
|
|
283
|
+
provider,
|
|
281
284
|
analyticsMetadata: analyticsMetadataRef.current,
|
|
282
285
|
couponId,
|
|
283
286
|
customerEmail,
|
|
@@ -302,6 +305,9 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
|
|
|
302
305
|
displayPlan,
|
|
303
306
|
plan,
|
|
304
307
|
planKey,
|
|
308
|
+
runtimeConfigRevisionId,
|
|
309
|
+
paymentProfileId,
|
|
310
|
+
provider,
|
|
305
311
|
runtimeConfig,
|
|
306
312
|
setError,
|
|
307
313
|
userId,
|
|
@@ -68,6 +68,11 @@ type CreatePaymentIntentResponse = {
|
|
|
68
68
|
};
|
|
69
69
|
type CreateOneTimeCheckoutInput = {
|
|
70
70
|
plan: CheckoutSessionPlanInput;
|
|
71
|
+
runtimeConfigRevisionId?: string | null;
|
|
72
|
+
paymentProfileId?: string | null;
|
|
73
|
+
provider?: 'stripe' | null;
|
|
74
|
+
anonymousUserId?: string | null;
|
|
75
|
+
idempotencyKey?: string | null;
|
|
71
76
|
couponId?: string | null;
|
|
72
77
|
analyticsMetadata?: Record<string, unknown> | null;
|
|
73
78
|
customerEmail?: string | null;
|
|
@@ -93,6 +98,11 @@ export declare function createStripeOneTimeCheckout(input: CreateOneTimeCheckout
|
|
|
93
98
|
export declare function createStripePaymentIntent(input: CreatePaymentIntentInput): Promise<CreatePaymentIntentResponse>;
|
|
94
99
|
export type ChargeOneClickPaymentInput = {
|
|
95
100
|
planId: string;
|
|
101
|
+
planKey?: string | null;
|
|
102
|
+
offerSetId?: string | null;
|
|
103
|
+
runtimeConfigRevisionId?: string | null;
|
|
104
|
+
paymentProfileId?: string | null;
|
|
105
|
+
provider?: 'stripe' | null;
|
|
96
106
|
providerPlanId?: string | null;
|
|
97
107
|
amountCents: number;
|
|
98
108
|
analyticsMetadata?: Record<string, unknown> | null;
|
|
@@ -155,6 +165,9 @@ type CreateSubscriptionCheckoutResponse = {
|
|
|
155
165
|
type UpdateSubscriptionCheckoutPlanInput = {
|
|
156
166
|
checkoutSessionId: string;
|
|
157
167
|
plan: CheckoutSessionPlanInput;
|
|
168
|
+
runtimeConfigRevisionId?: string | null;
|
|
169
|
+
paymentProfileId?: string | null;
|
|
170
|
+
provider?: 'stripe' | null;
|
|
158
171
|
couponId?: string | null;
|
|
159
172
|
analyticsMetadata?: Record<string, unknown> | null;
|
|
160
173
|
customerEmail?: string | null;
|
|
@@ -299,20 +299,26 @@ const normalizeCheckoutAnalyticsMetadata = (metadata, plan) => {
|
|
|
299
299
|
return Object.assign(Object.assign({}, (normalized !== null && normalized !== void 0 ? normalized : {})), { analyticsPurchaseValue });
|
|
300
300
|
};
|
|
301
301
|
export async function createStripeOneTimeCheckout(input) {
|
|
302
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
302
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
303
303
|
return funnelSdkService.createOneTimeCheckout({
|
|
304
|
-
|
|
305
|
-
|
|
304
|
+
planKey: ((_a = input.plan.funnelPlanKey) === null || _a === void 0 ? void 0 : _a.trim()) || input.plan.id,
|
|
305
|
+
runtimeConfigRevisionId: input.runtimeConfigRevisionId,
|
|
306
|
+
paymentProfileId: input.paymentProfileId,
|
|
307
|
+
provider: input.provider,
|
|
308
|
+
anonymousUserId: input.anonymousUserId,
|
|
309
|
+
idempotencyKey: input.idempotencyKey,
|
|
310
|
+
offerSetId: ((_b = input.plan.offerSetId) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
|
|
311
|
+
offerSetKey: ((_c = input.plan.offerSetKey) === null || _c === void 0 ? void 0 : _c.trim()) || undefined,
|
|
306
312
|
planId: getPaywallPlanRequestId(input.plan),
|
|
307
|
-
providerPlanId: ((
|
|
313
|
+
providerPlanId: ((_d = input.plan.providerPlanId) === null || _d === void 0 ? void 0 : _d.trim()) || undefined,
|
|
308
314
|
title: input.plan.title,
|
|
309
|
-
description: ((
|
|
315
|
+
description: ((_e = input.plan.description) === null || _e === void 0 ? void 0 : _e.trim()) || undefined,
|
|
310
316
|
amountCents: input.plan.amountCents,
|
|
311
|
-
couponId: ((
|
|
317
|
+
couponId: ((_f = input.couponId) === null || _f === void 0 ? void 0 : _f.trim()) || undefined,
|
|
312
318
|
analyticsMetadata: normalizeCheckoutAnalyticsMetadata(input.analyticsMetadata, input.plan),
|
|
313
|
-
customerEmail: ((
|
|
319
|
+
customerEmail: ((_g = input.customerEmail) === null || _g === void 0 ? void 0 : _g.trim()) || undefined,
|
|
314
320
|
returnUrl: input.returnUrl,
|
|
315
|
-
userId: ((
|
|
321
|
+
userId: ((_h = input.user_id) === null || _h === void 0 ? void 0 : _h.trim()) || undefined,
|
|
316
322
|
environment: input.environment,
|
|
317
323
|
runtimeConfig: input.runtimeConfig,
|
|
318
324
|
});
|
|
@@ -337,6 +343,11 @@ export async function createStripePaymentIntent(input) {
|
|
|
337
343
|
export async function chargeStripeOneClickPayment(input) {
|
|
338
344
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
339
345
|
return funnelSdkService.chargeOneClickPayment({
|
|
346
|
+
planKey: input.planKey,
|
|
347
|
+
offerSetId: input.offerSetId,
|
|
348
|
+
runtimeConfigRevisionId: input.runtimeConfigRevisionId,
|
|
349
|
+
paymentProfileId: input.paymentProfileId,
|
|
350
|
+
provider: input.provider,
|
|
340
351
|
planId: input.planId,
|
|
341
352
|
providerPlanId: ((_a = input.providerPlanId) === null || _a === void 0 ? void 0 : _a.trim()) || undefined,
|
|
342
353
|
amountCents: input.amountCents,
|
|
@@ -417,7 +428,7 @@ export async function createStripeSubscriptionCheckout(input) {
|
|
|
417
428
|
});
|
|
418
429
|
}
|
|
419
430
|
export async function updateStripeSubscriptionCheckoutPlan(input) {
|
|
420
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
431
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
421
432
|
const recurring = resolveCheckoutPlanRecurringConfig(input.plan);
|
|
422
433
|
if (!recurring) {
|
|
423
434
|
throw new Error('Unable to resolve the recurring interval for the selected plan');
|
|
@@ -427,21 +438,25 @@ export async function updateStripeSubscriptionCheckoutPlan(input) {
|
|
|
427
438
|
offerSetId: ((_a = input.plan.offerSetId) === null || _a === void 0 ? void 0 : _a.trim()) || undefined,
|
|
428
439
|
offerSetKey: ((_b = input.plan.offerSetKey) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
|
|
429
440
|
planId: getPaywallPlanRequestId(input.plan),
|
|
430
|
-
|
|
441
|
+
planKey: ((_c = input.plan.funnelPlanKey) === null || _c === void 0 ? void 0 : _c.trim()) || input.plan.id,
|
|
442
|
+
providerPlanId: ((_d = input.plan.providerPlanId) === null || _d === void 0 ? void 0 : _d.trim()) || undefined,
|
|
443
|
+
provider: input.provider,
|
|
444
|
+
paymentProfileId: ((_e = input.paymentProfileId) === null || _e === void 0 ? void 0 : _e.trim()) || undefined,
|
|
445
|
+
runtimeConfigRevisionId: ((_f = input.runtimeConfigRevisionId) === null || _f === void 0 ? void 0 : _f.trim()) || undefined,
|
|
431
446
|
title: input.plan.title,
|
|
432
|
-
description: ((
|
|
447
|
+
description: ((_g = input.plan.description) === null || _g === void 0 ? void 0 : _g.trim()) || undefined,
|
|
433
448
|
amountCents: input.plan.amountCents,
|
|
434
449
|
billingInterval: recurring.interval,
|
|
435
450
|
billingIntervalCount: recurring.intervalCount,
|
|
436
|
-
followUpProviderPlanId: ((
|
|
437
|
-
followUpPlanTitle: ((
|
|
451
|
+
followUpProviderPlanId: ((_h = input.plan.followUpProviderPlanId) === null || _h === void 0 ? void 0 : _h.trim()) || undefined,
|
|
452
|
+
followUpPlanTitle: ((_j = input.plan.followUpPlanTitle) === null || _j === void 0 ? void 0 : _j.trim()) || undefined,
|
|
438
453
|
followUpBillingInterval: input.plan.followUpBillingInterval,
|
|
439
454
|
followUpBillingIntervalCount: input.plan.followUpBillingIntervalCount,
|
|
440
455
|
introIterations: input.plan.introIterations,
|
|
441
|
-
couponId: ((
|
|
456
|
+
couponId: ((_k = input.couponId) === null || _k === void 0 ? void 0 : _k.trim()) || undefined,
|
|
442
457
|
analyticsMetadata: normalizeCheckoutAnalyticsMetadata(input.analyticsMetadata, input.plan),
|
|
443
|
-
customerEmail: ((
|
|
444
|
-
userId: ((
|
|
458
|
+
customerEmail: ((_l = input.customerEmail) === null || _l === void 0 ? void 0 : _l.trim()) || undefined,
|
|
459
|
+
userId: ((_m = input.user_id) === null || _m === void 0 ? void 0 : _m.trim()) || undefined,
|
|
445
460
|
environment: input.environment,
|
|
446
461
|
runtimeConfig: input.runtimeConfig,
|
|
447
462
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@funnelsgrove/payments",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
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.
|
|
35
|
+
"@funnelsgrove/analytics": "^0.1.84",
|
|
36
|
+
"@funnelsgrove/runtime": "^0.11.0",
|
|
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",
|