@funnelsgrove/payments 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/shared/StripeCheckoutExpressCheckoutButton.d.ts +3 -1
- package/dist/components/shared/StripeCheckoutExpressCheckoutButton.js +58 -2
- package/dist/providers/stripe/WalletSubscriptionCheckoutSlot.js +6 -1
- package/dist/providers/stripe/useStripeSubscriptionCheckoutSession.d.ts +4 -0
- package/dist/providers/stripe/useStripeSubscriptionCheckoutSession.js +67 -11
- package/dist/services/stripe.service.d.ts +14 -0
- package/dist/services/stripe.service.js +36 -0
- package/package.json +2 -2
|
@@ -11,8 +11,10 @@ export type StripeCheckoutExpressCheckoutButtonProps = {
|
|
|
11
11
|
availabilityPaymentMethods?: readonly (keyof AvailablePaymentMethods)[];
|
|
12
12
|
initialAvailable?: boolean | null;
|
|
13
13
|
keepInitialAvailableOnReady?: boolean;
|
|
14
|
+
serverUpdateKey?: string | null;
|
|
15
|
+
onServerUpdate?: () => Promise<boolean>;
|
|
14
16
|
onAvailabilityChange?: (available: boolean) => void;
|
|
15
17
|
onError?: (message: string | null) => void;
|
|
16
18
|
onSuccess?: () => void;
|
|
17
19
|
};
|
|
18
|
-
export declare function StripeCheckoutExpressCheckoutButton({ beforeConfirm, returnUrl, customerEmail, className, options, availabilityPaymentMethods, initialAvailable, keepInitialAvailableOnReady, onAvailabilityChange, onError, onSuccess, }: StripeCheckoutExpressCheckoutButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export declare function StripeCheckoutExpressCheckoutButton({ beforeConfirm, returnUrl, customerEmail, className, options, availabilityPaymentMethods, initialAvailable, keepInitialAvailableOnReady, serverUpdateKey, onServerUpdate, onAvailabilityChange, onError, onSuccess, }: StripeCheckoutExpressCheckoutButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useMemo, useState } from 'react';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { ExpressCheckoutElement, useCheckout, } from '@stripe/react-stripe-js/checkout';
|
|
5
5
|
const buildDefaultOptions = () => ({
|
|
6
6
|
buttonHeight: 55,
|
|
@@ -25,9 +25,12 @@ const buildDefaultOptions = () => ({
|
|
|
25
25
|
paypal: 'never',
|
|
26
26
|
},
|
|
27
27
|
});
|
|
28
|
-
export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, returnUrl, customerEmail, className, options, availabilityPaymentMethods = ['applePay'], initialAvailable, keepInitialAvailableOnReady = false, onAvailabilityChange, onError, onSuccess, }) {
|
|
28
|
+
export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, returnUrl, customerEmail, className, options, availabilityPaymentMethods = ['applePay'], initialAvailable, keepInitialAvailableOnReady = false, serverUpdateKey, onServerUpdate, onAvailabilityChange, onError, onSuccess, }) {
|
|
29
29
|
const checkoutState = useCheckout();
|
|
30
|
+
const appliedServerUpdateKeyRef = useRef('');
|
|
31
|
+
const serverUpdatePromiseRef = useRef(null);
|
|
30
32
|
const [walletAvailable, setWalletAvailable] = useState(initialAvailable !== null && initialAvailable !== void 0 ? initialAvailable : null);
|
|
33
|
+
const normalizedServerUpdateKey = (serverUpdateKey === null || serverUpdateKey === void 0 ? void 0 : serverUpdateKey.trim()) || '';
|
|
31
34
|
const effectiveWalletAvailable = initialAvailable === true && walletAvailable !== false
|
|
32
35
|
? true
|
|
33
36
|
: walletAvailable;
|
|
@@ -36,6 +39,52 @@ export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, returnUrl,
|
|
|
36
39
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
37
40
|
return Object.assign(Object.assign(Object.assign({}, baseOptions), (options !== null && options !== void 0 ? options : {})), { buttonTheme: Object.assign(Object.assign({}, ((_a = baseOptions.buttonTheme) !== null && _a !== void 0 ? _a : {})), ((_b = options === null || options === void 0 ? void 0 : options.buttonTheme) !== null && _b !== void 0 ? _b : {})), buttonType: Object.assign(Object.assign({}, ((_c = baseOptions.buttonType) !== null && _c !== void 0 ? _c : {})), ((_d = options === null || options === void 0 ? void 0 : options.buttonType) !== null && _d !== void 0 ? _d : {})), layout: Object.assign(Object.assign({}, ((_e = baseOptions.layout) !== null && _e !== void 0 ? _e : {})), ((_f = options === null || options === void 0 ? void 0 : options.layout) !== null && _f !== void 0 ? _f : {})), paymentMethods: Object.assign(Object.assign({}, ((_g = baseOptions.paymentMethods) !== null && _g !== void 0 ? _g : {})), ((_h = options === null || options === void 0 ? void 0 : options.paymentMethods) !== null && _h !== void 0 ? _h : {})), paymentMethodOrder: (_j = options === null || options === void 0 ? void 0 : options.paymentMethodOrder) !== null && _j !== void 0 ? _j : baseOptions.paymentMethodOrder });
|
|
38
41
|
}, [baseOptions, options]);
|
|
42
|
+
const ensureServerUpdated = useCallback(async () => {
|
|
43
|
+
if (!normalizedServerUpdateKey) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
if (appliedServerUpdateKeyRef.current === normalizedServerUpdateKey) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
if (!onServerUpdate || checkoutState.type !== 'success') {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
if (serverUpdatePromiseRef.current) {
|
|
53
|
+
return serverUpdatePromiseRef.current;
|
|
54
|
+
}
|
|
55
|
+
const updatePromise = (async () => {
|
|
56
|
+
const updateResult = await checkoutState.checkout.runServerUpdate(async () => {
|
|
57
|
+
const updated = await onServerUpdate();
|
|
58
|
+
if (!updated) {
|
|
59
|
+
throw new Error('Unable to update checkout session.');
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
if (updateResult.type === 'error') {
|
|
63
|
+
onError === null || onError === void 0 ? void 0 : onError(updateResult.error.message || 'Unable to update checkout session.');
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
appliedServerUpdateKeyRef.current = normalizedServerUpdateKey;
|
|
67
|
+
onError === null || onError === void 0 ? void 0 : onError(null);
|
|
68
|
+
return true;
|
|
69
|
+
})();
|
|
70
|
+
serverUpdatePromiseRef.current = updatePromise;
|
|
71
|
+
try {
|
|
72
|
+
return await updatePromise;
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
serverUpdatePromiseRef.current = null;
|
|
76
|
+
}
|
|
77
|
+
}, [checkoutState, normalizedServerUpdateKey, onError, onServerUpdate]);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (!normalizedServerUpdateKey) {
|
|
80
|
+
appliedServerUpdateKeyRef.current = '';
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (checkoutState.type !== 'success' || !onServerUpdate) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
void ensureServerUpdated();
|
|
87
|
+
}, [checkoutState.type, ensureServerUpdated, normalizedServerUpdateKey, onServerUpdate]);
|
|
39
88
|
const handleConfirm = async (event) => {
|
|
40
89
|
if (checkoutState.type !== 'success') {
|
|
41
90
|
const message = checkoutState.type === 'error'
|
|
@@ -46,6 +95,13 @@ export function StripeCheckoutExpressCheckoutButton({ beforeConfirm, returnUrl,
|
|
|
46
95
|
return;
|
|
47
96
|
}
|
|
48
97
|
onError === null || onError === void 0 ? void 0 : onError(null);
|
|
98
|
+
const updated = await ensureServerUpdated();
|
|
99
|
+
if (!updated) {
|
|
100
|
+
const message = 'Unable to update checkout session.';
|
|
101
|
+
onError === null || onError === void 0 ? void 0 : onError(message);
|
|
102
|
+
event.paymentFailed({ reason: 'fail', message });
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
49
105
|
let preparedCustomerEmail = (customerEmail === null || customerEmail === void 0 ? void 0 : customerEmail.trim()) || null;
|
|
50
106
|
if (beforeConfirm) {
|
|
51
107
|
try {
|
|
@@ -31,6 +31,11 @@ export function WalletSubscriptionCheckoutSlot({ amountCents, availabilityPaymen
|
|
|
31
31
|
expressCheckoutAllowed &&
|
|
32
32
|
walletAvailable === null;
|
|
33
33
|
const placeholderIsPreparing = shouldRenderPlaceholder;
|
|
34
|
+
const serverUpdateKey = session.activeClientSecret &&
|
|
35
|
+
session.checkoutSessionId &&
|
|
36
|
+
session.activePlanKey !== session.planKey
|
|
37
|
+
? session.planKey
|
|
38
|
+
: null;
|
|
34
39
|
const markWalletUnavailable = useCallback((intentKey) => {
|
|
35
40
|
setWalletAvailability({
|
|
36
41
|
available: false,
|
|
@@ -105,7 +110,7 @@ export function WalletSubscriptionCheckoutSlot({ amountCents, availabilityPaymen
|
|
|
105
110
|
.filter(Boolean)
|
|
106
111
|
.join(' '), "aria-busy": placeholderIsPreparing || undefined, children: [shouldRenderExpressCheckout &&
|
|
107
112
|
session.activeClientSecret &&
|
|
108
|
-
session.stripePromise ? (_jsx(StripeExpressCheckoutElement, { amountCents: amountCents, availabilityPaymentMethods: [availabilityPaymentMethod], beforeConfirm: beforeConfirm, className: className, clientSecret: session.activeClientSecret, customerEmail: customerEmail, customerName: customerName, onAvailabilityChange: handleAvailabilityChange, onError: handleError, onSuccess: onSuccess, options: options, returnUrl: returnUrl, stripePromise: session.stripePromise, summaryLabel: summaryLabel
|
|
113
|
+
session.stripePromise ? (_jsx(StripeExpressCheckoutElement, { amountCents: amountCents, availabilityPaymentMethods: [availabilityPaymentMethod], beforeConfirm: beforeConfirm, className: className, clientSecret: session.activeClientSecret, customerEmail: customerEmail, customerName: customerName, onAvailabilityChange: handleAvailabilityChange, onError: handleError, onSuccess: onSuccess, options: options, returnUrl: returnUrl, serverUpdateKey: serverUpdateKey, stripePromise: session.stripePromise, summaryLabel: summaryLabel, onServerUpdate: session.updateCheckoutSessionPlan })) : null, shouldRenderPlaceholder ? (_jsx("div", { className: 'wallet-subscription-checkout-slot__placeholder', children: (renderPreparingPlaceholder !== null && renderPreparingPlaceholder !== void 0 ? renderPreparingPlaceholder : renderPlaceholder)({
|
|
109
114
|
className,
|
|
110
115
|
disabled: slotDisabled,
|
|
111
116
|
label: placeholderLabel,
|
|
@@ -17,6 +17,8 @@ export type StripeSubscriptionCheckoutSessionInput = {
|
|
|
17
17
|
};
|
|
18
18
|
export type StripeSubscriptionCheckoutSession = {
|
|
19
19
|
activeClientSecret: string | null;
|
|
20
|
+
activePlanKey: string | null;
|
|
21
|
+
checkoutSessionId: string | null;
|
|
20
22
|
configured: boolean;
|
|
21
23
|
error: string | null;
|
|
22
24
|
intentKey: string;
|
|
@@ -27,8 +29,10 @@ export type StripeSubscriptionCheckoutSession = {
|
|
|
27
29
|
reset: () => void;
|
|
28
30
|
restartCardCheckout: () => Promise<string | null>;
|
|
29
31
|
restartWalletCheckout: () => Promise<string | null>;
|
|
32
|
+
planKey: string;
|
|
30
33
|
setError: (message: string | null) => void;
|
|
31
34
|
stripePromise: Promise<Stripe | null> | null;
|
|
35
|
+
updateCheckoutSessionPlan: () => Promise<boolean>;
|
|
32
36
|
};
|
|
33
37
|
export declare function isInactiveCheckoutSessionError(message?: string | null): boolean;
|
|
34
38
|
export declare function useStripeSubscriptionCheckoutSession({ checkoutMode, couponId, customerEmail, displayPlan, enabled, onError, plan, returnUrl, runtimeConfig, userId, }: StripeSubscriptionCheckoutSessionInput): StripeSubscriptionCheckoutSession;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
3
3
|
import { createEmptyCheckoutPreparationLoading, } from '../paymentProvider.types.js';
|
|
4
|
-
import { createStripeSubscriptionCheckout, getStripePromise, isStripeConfigured, } from '../../services/stripe.service.js';
|
|
4
|
+
import { createStripeSubscriptionCheckout, getStripePromise, isStripeConfigured, updateStripeSubscriptionCheckoutPlan, } from '../../services/stripe.service.js';
|
|
5
5
|
const getFriendlyStripeCheckoutError = (error) => {
|
|
6
6
|
const message = error instanceof Error ? error.message : 'Unable to initialize checkout';
|
|
7
7
|
return message === 'Internal server error'
|
|
@@ -14,9 +14,11 @@ export function isInactiveCheckoutSessionError(message) {
|
|
|
14
14
|
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 : '');
|
|
15
15
|
}
|
|
16
16
|
export function useStripeSubscriptionCheckoutSession({ checkoutMode, couponId, customerEmail, displayPlan, enabled = true, onError, plan, returnUrl, runtimeConfig, userId, }) {
|
|
17
|
-
var _a, _b, _c, _d;
|
|
17
|
+
var _a, _b, _c, _d, _e;
|
|
18
18
|
const [clientSecret, setClientSecret] = useState(null);
|
|
19
19
|
const [clientSecretIntentKey, setClientSecretIntentKey] = useState(null);
|
|
20
|
+
const [checkoutSessionId, setCheckoutSessionId] = useState(null);
|
|
21
|
+
const [clientSecretPlanKey, setClientSecretPlanKey] = useState(null);
|
|
20
22
|
const [error, setErrorState] = useState(null);
|
|
21
23
|
const [loading, setLoading] = useState(createEmptyCheckoutPreparationLoading);
|
|
22
24
|
const [runtimeStripePublishableKey, setRuntimeStripePublishableKey] = useState(null);
|
|
@@ -35,20 +37,27 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, couponId, c
|
|
|
35
37
|
'stripe',
|
|
36
38
|
checkoutMode,
|
|
37
39
|
runtimeConfigSignature,
|
|
38
|
-
(_a = plan === null || plan === void 0 ? void 0 : plan.id) !== null && _a !== void 0 ? _a : '',
|
|
39
|
-
(_b = plan === null || plan === void 0 ? void 0 : plan.amountCents) !== null && _b !== void 0 ? _b : '',
|
|
40
|
-
(_c = displayPlan === null || displayPlan === void 0 ? void 0 : displayPlan.id) !== null && _c !== void 0 ? _c : '',
|
|
41
|
-
(_d = displayPlan === null || displayPlan === void 0 ? void 0 : displayPlan.amountCents) !== null && _d !== void 0 ? _d : '',
|
|
42
40
|
(couponId === null || couponId === void 0 ? void 0 : couponId.trim()) || '',
|
|
43
41
|
returnUrl.trim(),
|
|
44
42
|
].join('|');
|
|
43
|
+
const planKey = [
|
|
44
|
+
(_a = plan === null || plan === void 0 ? void 0 : plan.id) !== null && _a !== void 0 ? _a : '',
|
|
45
|
+
(_b = plan === null || plan === void 0 ? void 0 : plan.providerPlanId) !== null && _b !== void 0 ? _b : '',
|
|
46
|
+
(_c = plan === null || plan === void 0 ? void 0 : plan.amountCents) !== null && _c !== void 0 ? _c : '',
|
|
47
|
+
(_d = displayPlan === null || displayPlan === void 0 ? void 0 : displayPlan.id) !== null && _d !== void 0 ? _d : '',
|
|
48
|
+
(_e = displayPlan === null || displayPlan === void 0 ? void 0 : displayPlan.amountCents) !== null && _e !== void 0 ? _e : '',
|
|
49
|
+
].join('|');
|
|
45
50
|
const activeClientSecret = clientSecretIntentKey === intentKey ? clientSecret : null;
|
|
51
|
+
const activeCheckoutSessionId = clientSecretIntentKey === intentKey ? checkoutSessionId : null;
|
|
52
|
+
const activePlanKey = clientSecretIntentKey === intentKey ? clientSecretPlanKey : null;
|
|
46
53
|
const stripePromise = useMemo(() => getStripePromise(checkoutMode, runtimeStripePublishableKey), [checkoutMode, runtimeStripePublishableKey]);
|
|
47
54
|
const clearActiveCheckoutSession = useCallback(() => {
|
|
48
55
|
requestIdRef.current += 1;
|
|
49
56
|
creatingIntentRef.current = null;
|
|
50
57
|
setClientSecret(null);
|
|
51
58
|
setClientSecretIntentKey(null);
|
|
59
|
+
setCheckoutSessionId(null);
|
|
60
|
+
setClientSecretPlanKey(null);
|
|
52
61
|
}, []);
|
|
53
62
|
const setError = useCallback((message) => {
|
|
54
63
|
if (isInactiveCheckoutSessionError(message)) {
|
|
@@ -89,10 +98,11 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, couponId, c
|
|
|
89
98
|
clearActiveCheckoutSession();
|
|
90
99
|
}
|
|
91
100
|
const requestKey = intentKey;
|
|
101
|
+
const requestPlanKey = planKey;
|
|
92
102
|
const requestId = requestIdRef.current + 1;
|
|
93
103
|
requestIdRef.current = requestId;
|
|
94
104
|
const subscriptionRequest = (async () => {
|
|
95
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
105
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
96
106
|
try {
|
|
97
107
|
const response = await createStripeSubscriptionCheckout({
|
|
98
108
|
plan,
|
|
@@ -113,18 +123,20 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, couponId, c
|
|
|
113
123
|
}
|
|
114
124
|
setClientSecret(response.clientSecret);
|
|
115
125
|
setClientSecretIntentKey(requestKey);
|
|
126
|
+
setCheckoutSessionId(((_d = response.checkoutSessionId) === null || _d === void 0 ? void 0 : _d.trim()) || null);
|
|
127
|
+
setClientSecretPlanKey(requestPlanKey);
|
|
116
128
|
return response.clientSecret;
|
|
117
129
|
}
|
|
118
130
|
catch (subscriptionError) {
|
|
119
|
-
if (((
|
|
120
|
-
((
|
|
131
|
+
if (((_e = creatingIntentRef.current) === null || _e === void 0 ? void 0 : _e.key) === requestKey &&
|
|
132
|
+
((_f = creatingIntentRef.current) === null || _f === void 0 ? void 0 : _f.id) === requestId) {
|
|
121
133
|
setError(getFriendlyStripeCheckoutError(subscriptionError));
|
|
122
134
|
}
|
|
123
135
|
return null;
|
|
124
136
|
}
|
|
125
137
|
finally {
|
|
126
|
-
if (((
|
|
127
|
-
((
|
|
138
|
+
if (((_g = creatingIntentRef.current) === null || _g === void 0 ? void 0 : _g.key) === requestKey &&
|
|
139
|
+
((_h = creatingIntentRef.current) === null || _h === void 0 ? void 0 : _h.id) === requestId) {
|
|
128
140
|
creatingIntentRef.current = null;
|
|
129
141
|
}
|
|
130
142
|
}
|
|
@@ -145,6 +157,7 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, couponId, c
|
|
|
145
157
|
displayPlan,
|
|
146
158
|
intentKey,
|
|
147
159
|
plan,
|
|
160
|
+
planKey,
|
|
148
161
|
returnUrl,
|
|
149
162
|
runtimeConfig,
|
|
150
163
|
setError,
|
|
@@ -178,8 +191,49 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, couponId, c
|
|
|
178
191
|
const prepareWalletCheckout = useCallback(() => prepareCheckout('wallet'), [prepareCheckout]);
|
|
179
192
|
const restartCardCheckout = useCallback(() => prepareCheckout('card', { forceNew: true }), [prepareCheckout]);
|
|
180
193
|
const restartWalletCheckout = useCallback(() => prepareCheckout('wallet', { forceNew: true }), [prepareCheckout]);
|
|
194
|
+
const updateCheckoutSessionPlan = useCallback(async () => {
|
|
195
|
+
if (!configured || !plan || !displayPlan || !activeCheckoutSessionId) {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
if (activePlanKey === planKey) {
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
setError(null);
|
|
202
|
+
try {
|
|
203
|
+
await updateStripeSubscriptionCheckoutPlan({
|
|
204
|
+
checkoutSessionId: activeCheckoutSessionId,
|
|
205
|
+
plan,
|
|
206
|
+
couponId,
|
|
207
|
+
customerEmail,
|
|
208
|
+
user_id: userId,
|
|
209
|
+
environment: checkoutMode,
|
|
210
|
+
runtimeConfig,
|
|
211
|
+
});
|
|
212
|
+
setClientSecretPlanKey(planKey);
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
catch (subscriptionError) {
|
|
216
|
+
setError(getFriendlyStripeCheckoutError(subscriptionError));
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}, [
|
|
220
|
+
activeCheckoutSessionId,
|
|
221
|
+
activePlanKey,
|
|
222
|
+
checkoutMode,
|
|
223
|
+
configured,
|
|
224
|
+
couponId,
|
|
225
|
+
customerEmail,
|
|
226
|
+
displayPlan,
|
|
227
|
+
plan,
|
|
228
|
+
planKey,
|
|
229
|
+
runtimeConfig,
|
|
230
|
+
setError,
|
|
231
|
+
userId,
|
|
232
|
+
]);
|
|
181
233
|
return {
|
|
182
234
|
activeClientSecret,
|
|
235
|
+
activePlanKey,
|
|
236
|
+
checkoutSessionId: activeCheckoutSessionId,
|
|
183
237
|
configured,
|
|
184
238
|
error,
|
|
185
239
|
intentKey,
|
|
@@ -190,7 +244,9 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, couponId, c
|
|
|
190
244
|
reset,
|
|
191
245
|
restartCardCheckout,
|
|
192
246
|
restartWalletCheckout,
|
|
247
|
+
planKey,
|
|
193
248
|
setError,
|
|
194
249
|
stripePromise,
|
|
250
|
+
updateCheckoutSessionPlan,
|
|
195
251
|
};
|
|
196
252
|
}
|
|
@@ -80,7 +80,21 @@ type CreateSubscriptionCheckoutResponse = {
|
|
|
80
80
|
stripePublishableKey?: string;
|
|
81
81
|
environment?: 'test' | 'live';
|
|
82
82
|
};
|
|
83
|
+
type UpdateSubscriptionCheckoutPlanInput = {
|
|
84
|
+
checkoutSessionId: string;
|
|
85
|
+
plan: CheckoutSessionPlanInput;
|
|
86
|
+
couponId?: string | null;
|
|
87
|
+
customerEmail?: string | null;
|
|
88
|
+
user_id?: string | null;
|
|
89
|
+
environment?: RuntimeMode;
|
|
90
|
+
runtimeConfig?: StripeRuntimeConfigOverrides;
|
|
91
|
+
};
|
|
92
|
+
type UpdateSubscriptionCheckoutPlanResponse = {
|
|
93
|
+
checkoutSessionId: string;
|
|
94
|
+
environment?: 'test' | 'live';
|
|
95
|
+
};
|
|
83
96
|
export declare function createStripeSubscriptionCheckout(input: CreateSubscriptionCheckoutInput): Promise<CreateSubscriptionCheckoutResponse>;
|
|
97
|
+
export declare function updateStripeSubscriptionCheckoutPlan(input: UpdateSubscriptionCheckoutPlanInput): Promise<UpdateSubscriptionCheckoutPlanResponse>;
|
|
84
98
|
type CreateCheckoutSessionInput = {
|
|
85
99
|
plan: CheckoutSessionPlanInput;
|
|
86
100
|
successUrl: string;
|
|
@@ -588,6 +588,42 @@ export async function createStripeSubscriptionCheckout(input) {
|
|
|
588
588
|
}
|
|
589
589
|
return (await response.json());
|
|
590
590
|
}
|
|
591
|
+
export async function updateStripeSubscriptionCheckoutPlan(input) {
|
|
592
|
+
var _a, _b, _c, _d, _e;
|
|
593
|
+
const recurring = resolveCheckoutPlanRecurringConfig(input.plan);
|
|
594
|
+
if (!recurring) {
|
|
595
|
+
throw new Error('Unable to resolve the recurring interval for the selected plan');
|
|
596
|
+
}
|
|
597
|
+
const runtimeConfig = resolveStripeRuntimeConfig(input.runtimeConfig);
|
|
598
|
+
const response = await fetch(buildStripeRuntimeApiUrl('/sdk/public/payments/subscriptions/update-plan', runtimeConfig), {
|
|
599
|
+
method: 'POST',
|
|
600
|
+
headers: buildStripeRuntimeHeaders(runtimeConfig, {
|
|
601
|
+
'Content-Type': 'application/json',
|
|
602
|
+
}),
|
|
603
|
+
body: JSON.stringify({
|
|
604
|
+
publishableKey: runtimeConfig.funnelSdkPublishableKey || undefined,
|
|
605
|
+
funnelId: runtimeConfig.funnelId || undefined,
|
|
606
|
+
funnelVersionId: runtimeConfig.funnelVersionId || undefined,
|
|
607
|
+
checkoutSessionId: input.checkoutSessionId.trim(),
|
|
608
|
+
planId: getPaywallPlanSelectionValue(input.plan),
|
|
609
|
+
providerPlanId: ((_a = input.plan.providerPlanId) === null || _a === void 0 ? void 0 : _a.trim()) || undefined,
|
|
610
|
+
title: input.plan.title,
|
|
611
|
+
description: ((_b = input.plan.description) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
|
|
612
|
+
amountCents: input.plan.amountCents,
|
|
613
|
+
billingInterval: recurring.interval,
|
|
614
|
+
billingIntervalCount: recurring.intervalCount,
|
|
615
|
+
couponId: ((_c = input.couponId) === null || _c === void 0 ? void 0 : _c.trim()) || undefined,
|
|
616
|
+
customerEmail: ((_d = input.customerEmail) === null || _d === void 0 ? void 0 : _d.trim()) || undefined,
|
|
617
|
+
user_id: ((_e = input.user_id) === null || _e === void 0 ? void 0 : _e.trim()) || undefined,
|
|
618
|
+
environment: input.environment || undefined,
|
|
619
|
+
}),
|
|
620
|
+
});
|
|
621
|
+
if (!response.ok) {
|
|
622
|
+
const errorMessage = await parseErrorMessage(response, 'Unable to update subscription checkout');
|
|
623
|
+
throw new Error(errorMessage);
|
|
624
|
+
}
|
|
625
|
+
return (await response.json());
|
|
626
|
+
}
|
|
591
627
|
export async function createStripeCheckoutSession(input) {
|
|
592
628
|
var _a, _b, _c, _d, _e;
|
|
593
629
|
const recurring = resolveCheckoutPlanRecurringConfig(input.plan);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@funnelsgrove/payments",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"test:run": "vitest run --passWithNoTests"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@funnelsgrove/runtime": "0.1.
|
|
29
|
+
"@funnelsgrove/runtime": "0.1.5",
|
|
30
30
|
"@stripe/react-stripe-js": "^5.6.0",
|
|
31
31
|
"@stripe/stripe-js": "^8.7.0",
|
|
32
32
|
"react": "19.2.3",
|