@funnelsgrove/payments 0.7.22 → 0.9.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/dist/providers/stripe/hooks/index.d.ts +0 -1
- package/dist/providers/stripe/hooks/index.js +0 -1
- package/dist/providers/stripe/hooks/useStripeSubscriptionCheckoutSession.d.ts +6 -3
- package/dist/providers/stripe/hooks/useStripeSubscriptionCheckoutSession.js +26 -8
- package/dist/providers/stripe/services/stripe.service.d.ts +5 -6
- package/dist/providers/stripe/services/stripe.service.js +15 -264
- package/dist/services/planCatalog.service.d.ts +0 -22
- package/dist/services/planCatalog.service.js +0 -15
- package/dist/services/publishedBillingRuntime.service.d.ts +1 -0
- package/dist/services/publishedBillingRuntime.service.js +4 -3
- package/package.json +3 -3
- package/dist/providers/stripe/hooks/useResolvedPaywallPlans.d.ts +0 -15
- package/dist/providers/stripe/hooks/useResolvedPaywallPlans.js +0 -68
|
@@ -14,6 +14,9 @@ export type StripeSubscriptionCheckoutSessionInput = {
|
|
|
14
14
|
plan?: PaywallPlan | null;
|
|
15
15
|
returnUrl: string;
|
|
16
16
|
runtimeConfig?: StripeRuntimeConfigOverrides;
|
|
17
|
+
runtimeConfigRevisionId?: string | null;
|
|
18
|
+
paymentProfileId?: string | null;
|
|
19
|
+
provider?: 'stripe' | null;
|
|
17
20
|
stripePublishableKey?: string | null;
|
|
18
21
|
userId?: string | null;
|
|
19
22
|
};
|
|
@@ -43,10 +46,10 @@ export type StripeSubscriptionCheckoutSession = {
|
|
|
43
46
|
updateCheckoutSessionPlan: () => Promise<boolean>;
|
|
44
47
|
};
|
|
45
48
|
export declare const buildStripeSubscriptionCheckoutPreparationAnalyticsMetadata: (analyticsMetadata: Record<string, unknown> | null | undefined, options?: StripeSubscriptionCheckoutPreparationOptions) => Record<string, unknown> | null | undefined;
|
|
46
|
-
export type StripeSubscriptionCheckoutIntentKeyInput = Pick<StripeSubscriptionCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'returnUrl' | 'runtimeConfig' | 'stripePublishableKey' | 'userId'> & {
|
|
49
|
+
export type StripeSubscriptionCheckoutIntentKeyInput = Pick<StripeSubscriptionCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'paymentProfileId' | 'provider' | 'returnUrl' | 'runtimeConfig' | 'runtimeConfigRevisionId' | 'stripePublishableKey' | 'userId'> & {
|
|
47
50
|
analyticsMetadata?: Record<string, unknown> | null;
|
|
48
51
|
};
|
|
49
|
-
export declare function buildStripeSubscriptionCheckoutIntentKey({ checkoutMode, couponId, customerEmail, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeSubscriptionCheckoutIntentKeyInput): string;
|
|
52
|
+
export declare function buildStripeSubscriptionCheckoutIntentKey({ checkoutMode, couponId, customerEmail, returnUrl, runtimeConfig, runtimeConfigRevisionId, paymentProfileId, provider, stripePublishableKey, userId, }: StripeSubscriptionCheckoutIntentKeyInput): string;
|
|
50
53
|
export declare function shouldResetStripeSubscriptionCheckoutSessionForIntentKey(previousIntentKey: string | null, nextIntentKey: string): boolean;
|
|
51
54
|
export declare function isInactiveCheckoutSessionError(message?: string | null): boolean;
|
|
52
|
-
export declare function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeSubscriptionCheckoutSessionInput): StripeSubscriptionCheckoutSession;
|
|
55
|
+
export declare function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled, onError, plan, returnUrl, runtimeConfig, runtimeConfigRevisionId, paymentProfileId, provider, stripePublishableKey, userId, }: StripeSubscriptionCheckoutSessionInput): StripeSubscriptionCheckoutSession;
|
|
@@ -35,12 +35,17 @@ export const buildStripeSubscriptionCheckoutPreparationAnalyticsMetadata = (anal
|
|
|
35
35
|
const _b = analyticsMetadata !== null && analyticsMetadata !== void 0 ? analyticsMetadata : {}, { payment_method: _paymentMethod, paymentMethod: _camelCasePaymentMethod } = _b, metadata = __rest(_b, ["payment_method", "paymentMethod"]);
|
|
36
36
|
return Object.assign(Object.assign(Object.assign({}, metadata), (checkoutStartSource ? { checkoutStartSource } : {})), (paymentMethod ? { payment_method: paymentMethod } : {}));
|
|
37
37
|
};
|
|
38
|
-
export function buildStripeSubscriptionCheckoutIntentKey({ checkoutMode, couponId, customerEmail, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
|
|
38
|
+
export function buildStripeSubscriptionCheckoutIntentKey({ checkoutMode, couponId, customerEmail, returnUrl, runtimeConfig, runtimeConfigRevisionId, paymentProfileId, provider, stripePublishableKey, userId, }) {
|
|
39
|
+
var _a;
|
|
39
40
|
const runtimeConfigSignature = [
|
|
40
41
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.apiBaseUrl),
|
|
41
42
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelId),
|
|
42
43
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelVersionId),
|
|
43
44
|
normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey),
|
|
45
|
+
(_a = runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.paymentsApiVersion) !== null && _a !== void 0 ? _a : 'v1',
|
|
46
|
+
normalizeRuntimeConfigValue(runtimeConfigRevisionId),
|
|
47
|
+
normalizeRuntimeConfigValue(paymentProfileId),
|
|
48
|
+
provider !== null && provider !== void 0 ? provider : '',
|
|
44
49
|
normalizeRuntimeConfigValue(stripePublishableKey),
|
|
45
50
|
].join('|');
|
|
46
51
|
const customerEmailSignature = normalizeRuntimeConfigValue(customerEmail);
|
|
@@ -62,7 +67,7 @@ export function isInactiveCheckoutSessionError(message) {
|
|
|
62
67
|
var _a;
|
|
63
68
|
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 : '');
|
|
64
69
|
}
|
|
65
|
-
export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled = true, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
|
|
70
|
+
export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled = true, onError, plan, returnUrl, runtimeConfig, runtimeConfigRevisionId, paymentProfileId, provider, stripePublishableKey, userId, }) {
|
|
66
71
|
var _a, _b, _c, _d, _e;
|
|
67
72
|
const [clientSecret, setClientSecret] = useState(null);
|
|
68
73
|
const [clientSecretIntentKey, setClientSecretIntentKey] = useState(null);
|
|
@@ -73,6 +78,7 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
|
|
|
73
78
|
const [runtimeStripePublishableKey, setRuntimeStripePublishableKey] = useState(null);
|
|
74
79
|
const creatingIntentRef = useRef(null);
|
|
75
80
|
const requestIdRef = useRef(0);
|
|
81
|
+
const anonymousUserIdRef = useRef(null);
|
|
76
82
|
const configured = enabled &&
|
|
77
83
|
(isStripeConfigured(checkoutMode) ||
|
|
78
84
|
Boolean(normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey)) ||
|
|
@@ -83,6 +89,9 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
|
|
|
83
89
|
customerEmail,
|
|
84
90
|
returnUrl,
|
|
85
91
|
runtimeConfig,
|
|
92
|
+
runtimeConfigRevisionId,
|
|
93
|
+
paymentProfileId,
|
|
94
|
+
provider,
|
|
86
95
|
stripePublishableKey,
|
|
87
96
|
userId,
|
|
88
97
|
});
|
|
@@ -158,7 +167,7 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
|
|
|
158
167
|
const requestId = requestIdRef.current + 1;
|
|
159
168
|
requestIdRef.current = requestId;
|
|
160
169
|
const subscriptionRequest = (async () => {
|
|
161
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
170
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
162
171
|
try {
|
|
163
172
|
const response = await createStripeSubscriptionCheckout({
|
|
164
173
|
plan,
|
|
@@ -169,6 +178,10 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
|
|
|
169
178
|
user_id: userId,
|
|
170
179
|
environment: checkoutMode,
|
|
171
180
|
runtimeConfig,
|
|
181
|
+
runtimeConfigRevisionId,
|
|
182
|
+
paymentProfileId,
|
|
183
|
+
provider,
|
|
184
|
+
anonymousUserId: anonymousUserIdRef.current,
|
|
172
185
|
});
|
|
173
186
|
if (((_a = creatingIntentRef.current) === null || _a === void 0 ? void 0 : _a.key) !== requestKey ||
|
|
174
187
|
((_b = creatingIntentRef.current) === null || _b === void 0 ? void 0 : _b.id) !== requestId) {
|
|
@@ -178,22 +191,24 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
|
|
|
178
191
|
if (publishableKey) {
|
|
179
192
|
setRuntimeStripePublishableKey(publishableKey);
|
|
180
193
|
}
|
|
194
|
+
anonymousUserIdRef.current = ((_d = response.anonymousUserId) === null || _d === void 0 ? void 0 : _d.trim())
|
|
195
|
+
|| anonymousUserIdRef.current;
|
|
181
196
|
setClientSecret(response.clientSecret);
|
|
182
197
|
setClientSecretIntentKey(requestKey);
|
|
183
|
-
setCheckoutSessionId(((
|
|
198
|
+
setCheckoutSessionId(((_e = response.checkoutSessionId) === null || _e === void 0 ? void 0 : _e.trim()) || null);
|
|
184
199
|
setClientSecretPlanKey(requestPlanKey);
|
|
185
200
|
return response.clientSecret;
|
|
186
201
|
}
|
|
187
202
|
catch (subscriptionError) {
|
|
188
|
-
if (((
|
|
189
|
-
((
|
|
203
|
+
if (((_f = creatingIntentRef.current) === null || _f === void 0 ? void 0 : _f.key) === requestKey &&
|
|
204
|
+
((_g = creatingIntentRef.current) === null || _g === void 0 ? void 0 : _g.id) === requestId) {
|
|
190
205
|
setError(getFriendlyStripeCheckoutError(subscriptionError));
|
|
191
206
|
}
|
|
192
207
|
return null;
|
|
193
208
|
}
|
|
194
209
|
finally {
|
|
195
|
-
if (((
|
|
196
|
-
((
|
|
210
|
+
if (((_h = creatingIntentRef.current) === null || _h === void 0 ? void 0 : _h.key) === requestKey &&
|
|
211
|
+
((_j = creatingIntentRef.current) === null || _j === void 0 ? void 0 : _j.id) === requestId) {
|
|
197
212
|
creatingIntentRef.current = null;
|
|
198
213
|
}
|
|
199
214
|
}
|
|
@@ -217,6 +232,9 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
|
|
|
217
232
|
planKey,
|
|
218
233
|
returnUrl,
|
|
219
234
|
runtimeConfig,
|
|
235
|
+
runtimeConfigRevisionId,
|
|
236
|
+
paymentProfileId,
|
|
237
|
+
provider,
|
|
220
238
|
setError,
|
|
221
239
|
userId,
|
|
222
240
|
]);
|
|
@@ -2,7 +2,6 @@ import { type Stripe } from '@stripe/stripe-js';
|
|
|
2
2
|
import { type BillingFallbackPlanConfig, type BillingPlanCatalog, type BillingPlanInterval, type BillingPlanInputCatalog } from '../../../config/billing.config.js';
|
|
3
3
|
import { type FunnelSdkRuntimeConfigOverrides, type ResolvedCountryPricing } from '@funnelsgrove/runtime';
|
|
4
4
|
import type { RuntimeMode } from '@funnelsgrove/runtime';
|
|
5
|
-
import { type RemoteProjectBillingPlan } from '../../../services/planCatalog.service.js';
|
|
6
5
|
export type PaywallPlan = {
|
|
7
6
|
id: string;
|
|
8
7
|
funnelPlanKey?: string;
|
|
@@ -36,7 +35,6 @@ export type PaywallPlanResolutionOptions = {
|
|
|
36
35
|
locale?: string | null;
|
|
37
36
|
pricing?: ResolvedCountryPricing<string> | null;
|
|
38
37
|
};
|
|
39
|
-
export declare const buildPaywallPlanResolutionSignature: (options?: PaywallPlanResolutionOptions) => string;
|
|
40
38
|
export declare function buildConfigPaywallPlans(planCatalog?: BillingPlanCatalog | readonly BillingFallbackPlanConfig[], orderedPlanIds?: readonly string[]): readonly PaywallPlan[];
|
|
41
39
|
export declare function getFallbackPlans(planCatalog?: BillingPlanInputCatalog | readonly BillingFallbackPlanConfig[], options?: PaywallPlanResolutionOptions): readonly PaywallPlan[];
|
|
42
40
|
export declare function getOrderedPaywallPlans(plans: readonly PaywallPlan[], orderedPlanIds: readonly string[]): readonly PaywallPlan[];
|
|
@@ -44,12 +42,9 @@ export declare function getDefaultPlanId(plans: readonly PaywallPlan[], pricing?
|
|
|
44
42
|
export declare function getPaywallPlanSelectionValue(plan: Pick<PaywallPlan, 'id' | 'providerPlanId'>): string;
|
|
45
43
|
export declare function findPaywallPlan(plans: readonly PaywallPlan[], selectionValue: string | null | undefined): PaywallPlan | null;
|
|
46
44
|
export declare function getDefaultPlanSelectionValue(plans: readonly PaywallPlan[], pricing?: ResolvedCountryPricing<string> | null): string | null;
|
|
47
|
-
export declare function getStripeSyncedPlans(mode: RuntimeMode, planCatalog?: BillingPlanInputCatalog | readonly BillingFallbackPlanConfig[], options?: PaywallPlanResolutionOptions): Promise<readonly PaywallPlan[]>;
|
|
48
|
-
export declare function resolvePaywallPlansFromProjectPlans(projectPlans: readonly RemoteProjectBillingPlan[], planCatalog?: BillingPlanInputCatalog | readonly BillingFallbackPlanConfig[], options?: PaywallPlanResolutionOptions): readonly PaywallPlan[];
|
|
49
|
-
export declare function getPaywallPlans(mode: RuntimeMode, planCatalog?: BillingPlanInputCatalog | readonly BillingFallbackPlanConfig[], options?: PaywallPlanResolutionOptions): Promise<readonly PaywallPlan[]>;
|
|
50
45
|
export declare function isStripeConfigured(mode: RuntimeMode): boolean;
|
|
51
46
|
export declare function getStripePromise(_mode: RuntimeMode, runtimePublishableKey?: string | null): Promise<Stripe | null> | null;
|
|
52
|
-
type CheckoutSessionPlanInput = Pick<PaywallPlan, 'amountCents' | 'analyticsPurchaseValue' | 'billingInterval' | 'billingIntervalCount' | 'description' | 'id' | 'providerPlanId' | 'title' | 'followUpProviderPlanId' | 'followUpPlanTitle' | 'followUpBillingInterval' | 'followUpBillingIntervalCount' | 'introIterations' | 'offerSetId' | 'offerSetKey'>;
|
|
47
|
+
type CheckoutSessionPlanInput = Pick<PaywallPlan, 'amountCents' | 'analyticsPurchaseValue' | 'billingInterval' | 'billingIntervalCount' | 'description' | 'funnelPlanKey' | 'id' | 'providerPlanId' | 'title' | 'followUpProviderPlanId' | 'followUpPlanTitle' | 'followUpBillingInterval' | 'followUpBillingIntervalCount' | 'introIterations' | 'offerSetId' | 'offerSetKey'>;
|
|
53
48
|
type CheckoutPlanRecurringConfig = {
|
|
54
49
|
interval: BillingPlanInterval;
|
|
55
50
|
intervalCount: number;
|
|
@@ -134,6 +129,10 @@ export declare const requiresStripeOneClickConfirmation: (status: string) => boo
|
|
|
134
129
|
export declare function completeStripeOneClickPayment(input: CompleteStripeOneClickPaymentInput): Promise<CompleteStripeOneClickPaymentResponse>;
|
|
135
130
|
type CreateSubscriptionCheckoutInput = {
|
|
136
131
|
plan: CheckoutSessionPlanInput;
|
|
132
|
+
runtimeConfigRevisionId?: string | null;
|
|
133
|
+
paymentProfileId?: string | null;
|
|
134
|
+
provider?: 'stripe' | null;
|
|
135
|
+
anonymousUserId?: string | null;
|
|
137
136
|
couponId?: string | null;
|
|
138
137
|
analyticsMetadata?: Record<string, unknown> | null;
|
|
139
138
|
customerEmail?: string | null;
|
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
import { loadStripe } from '@stripe/stripe-js';
|
|
2
2
|
import { billingPlanList, } from '../../../config/billing.config.js';
|
|
3
|
-
import {
|
|
4
|
-
import { isBillingPlanMappingCatalog
|
|
3
|
+
import { FUNNEL_SDK_PUBLISHABLE_KEY, funnelSdkService, } from '@funnelsgrove/runtime';
|
|
4
|
+
import { isBillingPlanMappingCatalog } from '../../../services/planCatalog.service.js';
|
|
5
5
|
const stripePromiseByKey = new Map();
|
|
6
|
-
const syncedPlansPromiseByMode = new Map();
|
|
7
|
-
export const buildPaywallPlanResolutionSignature = (options) => {
|
|
8
|
-
var _a, _b, _c, _d;
|
|
9
|
-
const locale = ((_a = options === null || options === void 0 ? void 0 : options.locale) === null || _a === void 0 ? void 0 : _a.trim()) || '';
|
|
10
|
-
const pricing = options === null || options === void 0 ? void 0 : options.pricing;
|
|
11
|
-
const countryCode = ((_b = pricing === null || pricing === void 0 ? void 0 : pricing.countryCode) === null || _b === void 0 ? void 0 : _b.trim()) || '';
|
|
12
|
-
const defaultOfferKey = ((_c = pricing === null || pricing === void 0 ? void 0 : pricing.defaultOfferKey) === null || _c === void 0 ? void 0 : _c.trim()) || '';
|
|
13
|
-
const offerOrder = ((_d = pricing === null || pricing === void 0 ? void 0 : pricing.offerOrder) === null || _d === void 0 ? void 0 : _d.map((offerKey) => offerKey.trim()).join('|')) || '';
|
|
14
|
-
return [locale, countryCode, defaultOfferKey, offerOrder].join('::');
|
|
15
|
-
};
|
|
16
6
|
const isRecord = (value) => {
|
|
17
7
|
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
18
8
|
};
|
|
@@ -97,74 +87,6 @@ const toConfigPaywallPlan = (key, plan) => {
|
|
|
97
87
|
return Object.assign(Object.assign({}, plan), { id: ((_a = plan.id) === null || _a === void 0 ? void 0 : _a.trim()) || key.trim() || ((_b = plan.providerPlanId) === null || _b === void 0 ? void 0 : _b.trim()) || plan.projectPlanId.trim(), perDayLabel: ((_c = plan.perDayLabel) === null || _c === void 0 ? void 0 : _c.trim()) || 'per day', billingInterval: interval.interval, billingIntervalCount: interval.intervalCount, source: 'config' });
|
|
98
88
|
};
|
|
99
89
|
const fallbackPaywallPlans = buildConfigPaywallPlans(billingPlanList);
|
|
100
|
-
const toMinorAmount = (value) => {
|
|
101
|
-
const numeric = asFiniteNumberOrNull(value);
|
|
102
|
-
if (numeric === null || numeric <= 0) {
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
return Math.round(numeric);
|
|
106
|
-
};
|
|
107
|
-
const toPlainObject = (value) => {
|
|
108
|
-
return isRecord(value) ? value : {};
|
|
109
|
-
};
|
|
110
|
-
const toCurrencyCode = (value) => {
|
|
111
|
-
const raw = asTrimmedStringOrNull(value);
|
|
112
|
-
if (!raw) {
|
|
113
|
-
return 'USD';
|
|
114
|
-
}
|
|
115
|
-
return raw.toUpperCase();
|
|
116
|
-
};
|
|
117
|
-
const resolveFormattingLocale = (locale) => {
|
|
118
|
-
const trimmedLocale = typeof locale === 'string' ? locale.trim() : '';
|
|
119
|
-
return trimmedLocale || 'en-US';
|
|
120
|
-
};
|
|
121
|
-
const formatMoneyFromMinor = (amountMinor, currencyCode, locale) => {
|
|
122
|
-
return new Intl.NumberFormat(resolveFormattingLocale(locale), {
|
|
123
|
-
style: 'currency',
|
|
124
|
-
currency: currencyCode,
|
|
125
|
-
minimumFractionDigits: 2,
|
|
126
|
-
maximumFractionDigits: 2,
|
|
127
|
-
}).format(amountMinor / 100);
|
|
128
|
-
};
|
|
129
|
-
const formatMoneyFromMajor = (amountMajor, currencyCode, locale) => {
|
|
130
|
-
return new Intl.NumberFormat(resolveFormattingLocale(locale), {
|
|
131
|
-
style: 'currency',
|
|
132
|
-
currency: currencyCode,
|
|
133
|
-
minimumFractionDigits: 2,
|
|
134
|
-
maximumFractionDigits: 2,
|
|
135
|
-
}).format(amountMajor);
|
|
136
|
-
};
|
|
137
|
-
const getIntervalLabel = (interval, intervalCount) => {
|
|
138
|
-
if (!interval) {
|
|
139
|
-
return '';
|
|
140
|
-
}
|
|
141
|
-
const normalized = interval.toLowerCase();
|
|
142
|
-
const count = intervalCount && intervalCount > 0 ? intervalCount : 1;
|
|
143
|
-
if (count === 1) {
|
|
144
|
-
return normalized;
|
|
145
|
-
}
|
|
146
|
-
return `${count} ${normalized}s`;
|
|
147
|
-
};
|
|
148
|
-
const getIntervalDays = (interval, intervalCount) => {
|
|
149
|
-
if (!interval) {
|
|
150
|
-
return null;
|
|
151
|
-
}
|
|
152
|
-
const normalized = interval.toLowerCase();
|
|
153
|
-
const count = intervalCount && intervalCount > 0 ? intervalCount : 1;
|
|
154
|
-
if (normalized === 'day') {
|
|
155
|
-
return count;
|
|
156
|
-
}
|
|
157
|
-
if (normalized === 'week') {
|
|
158
|
-
return count * 7;
|
|
159
|
-
}
|
|
160
|
-
if (normalized === 'month') {
|
|
161
|
-
return count * 30;
|
|
162
|
-
}
|
|
163
|
-
if (normalized === 'year') {
|
|
164
|
-
return count * 365;
|
|
165
|
-
}
|
|
166
|
-
return null;
|
|
167
|
-
};
|
|
168
90
|
const reorderPlans = (plans, pricing) => {
|
|
169
91
|
if (!pricing || pricing.offerOrder.length === 0) {
|
|
170
92
|
return plans;
|
|
@@ -185,108 +107,6 @@ const reorderPlans = (plans, pricing) => {
|
|
|
185
107
|
return leftIndex - rightIndex;
|
|
186
108
|
});
|
|
187
109
|
};
|
|
188
|
-
const toRemoteProjectBillingPlan = (rawPlan) => {
|
|
189
|
-
var _a, _b;
|
|
190
|
-
const providerPlanId = asTrimmedStringOrNull(rawPlan.providerPlanId);
|
|
191
|
-
if (!providerPlanId) {
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
return {
|
|
195
|
-
id: asTrimmedStringOrNull(rawPlan.id) || providerPlanId,
|
|
196
|
-
key: asTrimmedStringOrNull(rawPlan.key) || providerPlanId,
|
|
197
|
-
offerSetId: asTrimmedStringOrNull(rawPlan.offerSetId) || undefined,
|
|
198
|
-
offerSetKey: asTrimmedStringOrNull(rawPlan.offerSetKey) || undefined,
|
|
199
|
-
projectPlanId: asTrimmedStringOrNull(rawPlan.projectPlanId),
|
|
200
|
-
providerPlanId,
|
|
201
|
-
displayName: asTrimmedStringOrNull(rawPlan.displayName),
|
|
202
|
-
description: asTrimmedStringOrNull(rawPlan.description),
|
|
203
|
-
interval: (_b = (_a = asTrimmedStringOrNull(rawPlan.interval)) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : null,
|
|
204
|
-
intervalCount: asPositiveIntOrNull(rawPlan.intervalCount),
|
|
205
|
-
trialPeriodDays: asPositiveIntOrNull(rawPlan.trialPeriodDays),
|
|
206
|
-
currency: asTrimmedStringOrNull(rawPlan.currency),
|
|
207
|
-
amountMinor: toMinorAmount(rawPlan.amountMinor),
|
|
208
|
-
amountDecimal: asTrimmedStringOrNull(rawPlan.amountDecimal),
|
|
209
|
-
metadata: toPlainObject(rawPlan.metadata),
|
|
210
|
-
isActive: rawPlan.isActive !== false,
|
|
211
|
-
};
|
|
212
|
-
};
|
|
213
|
-
const toPlanFromRemoteProjectPlan = (rawPlan, options, planIdOverride) => {
|
|
214
|
-
var _a;
|
|
215
|
-
const planId = (planIdOverride === null || planIdOverride === void 0 ? void 0 : planIdOverride.trim()) || rawPlan.id || rawPlan.key || rawPlan.providerPlanId;
|
|
216
|
-
if (!planId) {
|
|
217
|
-
return null;
|
|
218
|
-
}
|
|
219
|
-
if (!rawPlan.isActive) {
|
|
220
|
-
return null;
|
|
221
|
-
}
|
|
222
|
-
const amountMinor = rawPlan.amountMinor;
|
|
223
|
-
if (!amountMinor) {
|
|
224
|
-
return null;
|
|
225
|
-
}
|
|
226
|
-
const metadata = rawPlan.metadata;
|
|
227
|
-
const currencyCode = toCurrencyCode(rawPlan.currency);
|
|
228
|
-
const interval = rawPlan.interval;
|
|
229
|
-
const intervalCount = rawPlan.intervalCount;
|
|
230
|
-
const intervalLabel = getIntervalLabel(interval, intervalCount);
|
|
231
|
-
const intervalDays = getIntervalDays(interval, intervalCount);
|
|
232
|
-
const locale = options === null || options === void 0 ? void 0 : options.locale;
|
|
233
|
-
const title = rawPlan.displayName || planId;
|
|
234
|
-
const priceLabel = intervalLabel
|
|
235
|
-
? `${formatMoneyFromMinor(amountMinor, currencyCode, locale)}/${intervalLabel}`
|
|
236
|
-
: formatMoneyFromMinor(amountMinor, currencyCode, locale);
|
|
237
|
-
const perDayAmount = intervalDays
|
|
238
|
-
? formatMoneyFromMajor(amountMinor / 100 / intervalDays, currencyCode, locale)
|
|
239
|
-
: formatMoneyFromMinor(amountMinor, currencyCode, locale);
|
|
240
|
-
return {
|
|
241
|
-
id: planId,
|
|
242
|
-
offerSetId: rawPlan.offerSetId,
|
|
243
|
-
offerSetKey: rawPlan.offerSetKey,
|
|
244
|
-
title,
|
|
245
|
-
description: rawPlan.description || asTrimmedStringOrNull(metadata.description) || undefined,
|
|
246
|
-
providerPlanId: rawPlan.providerPlanId,
|
|
247
|
-
priceLabel,
|
|
248
|
-
oldPriceLabel: asTrimmedStringOrNull(metadata.oldPriceLabel) || undefined,
|
|
249
|
-
featuredTag: asTrimmedStringOrNull(metadata.featuredTag) || undefined,
|
|
250
|
-
perDayAmount,
|
|
251
|
-
perDayLabel: 'per day',
|
|
252
|
-
amountCents: amountMinor,
|
|
253
|
-
analyticsPurchaseValue: (_a = asNonNegativeNumberOrNull(metadata.analyticsPurchaseValue)) !== null && _a !== void 0 ? _a : undefined,
|
|
254
|
-
comparison: intervalDays
|
|
255
|
-
? {
|
|
256
|
-
perDay: `${perDayAmount}/day`,
|
|
257
|
-
perWeek: `${formatMoneyFromMajor(amountMinor / 100 / intervalDays * 7, currencyCode, locale)}/week`,
|
|
258
|
-
perMonth: interval === 'month' || interval === 'year'
|
|
259
|
-
? `${formatMoneyFromMajor(interval === 'year'
|
|
260
|
-
? amountMinor / 100 / ((intervalCount || 1) * 12)
|
|
261
|
-
: amountMinor / 100 / (intervalCount || 1), currencyCode, locale)}/month`
|
|
262
|
-
: `${formatMoneyFromMajor(amountMinor / 100 / intervalDays * 30, currencyCode, locale)}/month`,
|
|
263
|
-
perYear: interval === 'year'
|
|
264
|
-
? `${formatMoneyFromMinor(amountMinor / (intervalCount || 1), currencyCode, locale)}/year`
|
|
265
|
-
: `${formatMoneyFromMajor(amountMinor / 100 / intervalDays * 365, currencyCode, locale)}/year`,
|
|
266
|
-
}
|
|
267
|
-
: undefined,
|
|
268
|
-
checkoutOriginalAmountCents: asPositiveIntOrNull(metadata.checkoutOriginalAmountCents) || undefined,
|
|
269
|
-
checkoutSummaryLabel: asTrimmedStringOrNull(metadata.checkoutSummaryLabel) || undefined,
|
|
270
|
-
billingInterval: asBillingPlanIntervalOrNull(interval) || undefined,
|
|
271
|
-
billingIntervalCount: intervalCount || undefined,
|
|
272
|
-
followUpProviderPlanId: asTrimmedStringOrNull(metadata.followUpProviderPlanId) || undefined,
|
|
273
|
-
followUpPlanTitle: asTrimmedStringOrNull(metadata.followUpPlanTitle) || undefined,
|
|
274
|
-
followUpBillingInterval: asBillingPlanIntervalOrNull(metadata.followUpBillingInterval) || undefined,
|
|
275
|
-
followUpBillingIntervalCount: asPositiveIntOrNull(metadata.followUpBillingIntervalCount) || undefined,
|
|
276
|
-
introIterations: asPositiveIntOrNull(metadata.introIterations) || undefined,
|
|
277
|
-
source: 'stripe',
|
|
278
|
-
};
|
|
279
|
-
};
|
|
280
|
-
const addFeaturedTagFallback = (plans) => {
|
|
281
|
-
if (plans.length === 0) {
|
|
282
|
-
return plans;
|
|
283
|
-
}
|
|
284
|
-
if (plans.some((plan) => Boolean(plan.featuredTag))) {
|
|
285
|
-
return plans;
|
|
286
|
-
}
|
|
287
|
-
return plans.map((plan, index) => index === 0
|
|
288
|
-
? Object.assign(Object.assign({}, plan), { featuredTag: '🔥 Most Popular Choice' }) : plan);
|
|
289
|
-
};
|
|
290
110
|
export function buildConfigPaywallPlans(planCatalog, orderedPlanIds = []) {
|
|
291
111
|
const plans = Array.isArray(planCatalog)
|
|
292
112
|
? planCatalog.map((plan, index) => toConfigPaywallPlan(String(index), plan))
|
|
@@ -334,12 +154,6 @@ export function getOrderedPaywallPlans(plans, orderedPlanIds) {
|
|
|
334
154
|
}
|
|
335
155
|
return selectedPlans;
|
|
336
156
|
}
|
|
337
|
-
const shouldLoadStripePlans = (planCatalog) => {
|
|
338
|
-
if (!planCatalog) {
|
|
339
|
-
return true;
|
|
340
|
-
}
|
|
341
|
-
return !Array.isArray(planCatalog) && isBillingPlanMappingCatalog(planCatalog);
|
|
342
|
-
};
|
|
343
157
|
export function getDefaultPlanId(plans, pricing) {
|
|
344
158
|
var _a, _b;
|
|
345
159
|
if (plans.length === 0) {
|
|
@@ -376,74 +190,6 @@ export function getDefaultPlanSelectionValue(plans, pricing) {
|
|
|
376
190
|
}
|
|
377
191
|
return getPaywallPlanSelectionValue(plans.find((plan) => plan.id === defaultPlanId) || plans[0]);
|
|
378
192
|
}
|
|
379
|
-
const getStripeSyncedPlanRecords = async (mode, offerSet) => {
|
|
380
|
-
const cacheKey = `${mode}:${FUNNEL_ID || 'no-funnel'}:${FUNNEL_SDK_PUBLISHABLE_KEY}:${offerSet.offerSetId || ''}:${offerSet.offerSetKey || ''}`;
|
|
381
|
-
const cachedPromise = syncedPlansPromiseByMode.get(cacheKey);
|
|
382
|
-
if (cachedPromise) {
|
|
383
|
-
return cachedPromise;
|
|
384
|
-
}
|
|
385
|
-
const nextPromise = (async () => {
|
|
386
|
-
const payload = await funnelSdkService.listPaymentPlans({
|
|
387
|
-
environment: mode,
|
|
388
|
-
offerSetId: offerSet.offerSetId,
|
|
389
|
-
offerSetKey: offerSet.offerSetKey,
|
|
390
|
-
});
|
|
391
|
-
const rawPlans = Array.isArray(payload.plans) ? payload.plans : [];
|
|
392
|
-
return rawPlans
|
|
393
|
-
.filter((rawPlan) => isRecord(rawPlan))
|
|
394
|
-
.map((rawPlan) => toRemoteProjectBillingPlan(rawPlan))
|
|
395
|
-
.filter((rawPlan) => Boolean(rawPlan));
|
|
396
|
-
})();
|
|
397
|
-
syncedPlansPromiseByMode.set(cacheKey, nextPromise);
|
|
398
|
-
return nextPromise;
|
|
399
|
-
};
|
|
400
|
-
const resolvePlanCatalogOfferSet = (planCatalog) => {
|
|
401
|
-
const configuredPlans = planCatalog
|
|
402
|
-
? (Array.isArray(planCatalog) ? planCatalog : Object.values(planCatalog))
|
|
403
|
-
: [];
|
|
404
|
-
const offerSetIds = [...new Set(configuredPlans
|
|
405
|
-
.map((plan) => { var _a; return (_a = plan.offerSetId) === null || _a === void 0 ? void 0 : _a.trim(); })
|
|
406
|
-
.filter((value) => Boolean(value)))];
|
|
407
|
-
const offerSetKeys = [...new Set(configuredPlans
|
|
408
|
-
.map((plan) => { var _a; return (_a = plan.offerSetKey) === null || _a === void 0 ? void 0 : _a.trim(); })
|
|
409
|
-
.filter((value) => Boolean(value)))];
|
|
410
|
-
return {
|
|
411
|
-
offerSetId: offerSetIds.length === 1 ? offerSetIds[0] : undefined,
|
|
412
|
-
offerSetKey: offerSetKeys.length === 1 ? offerSetKeys[0] : undefined,
|
|
413
|
-
};
|
|
414
|
-
};
|
|
415
|
-
export async function getStripeSyncedPlans(mode, planCatalog, options) {
|
|
416
|
-
const rawPlans = await getStripeSyncedPlanRecords(mode, resolvePlanCatalogOfferSet(planCatalog));
|
|
417
|
-
const mappedPlans = (planCatalog && !Array.isArray(planCatalog) && isBillingPlanMappingCatalog(planCatalog)
|
|
418
|
-
? resolveMappedProjectPlans(planCatalog, rawPlans).map((rawPlan) => toPlanFromRemoteProjectPlan(rawPlan, options, rawPlan.funnelKey))
|
|
419
|
-
: rawPlans.map((rawPlan) => toPlanFromRemoteProjectPlan(rawPlan, options)))
|
|
420
|
-
.filter((plan) => Boolean(plan))
|
|
421
|
-
.sort((left, right) => left.amountCents - right.amountCents);
|
|
422
|
-
return reorderPlans(addFeaturedTagFallback(mappedPlans), options === null || options === void 0 ? void 0 : options.pricing);
|
|
423
|
-
}
|
|
424
|
-
export function resolvePaywallPlansFromProjectPlans(projectPlans, planCatalog, options) {
|
|
425
|
-
const mappedPlans = (planCatalog && !Array.isArray(planCatalog) && isBillingPlanMappingCatalog(planCatalog)
|
|
426
|
-
? resolveMappedProjectPlans(planCatalog, projectPlans).map((rawPlan) => toPlanFromRemoteProjectPlan(rawPlan, options, rawPlan.funnelKey))
|
|
427
|
-
: projectPlans.map((rawPlan) => toPlanFromRemoteProjectPlan(rawPlan, options)))
|
|
428
|
-
.filter((plan) => Boolean(plan))
|
|
429
|
-
.sort((left, right) => left.amountCents - right.amountCents);
|
|
430
|
-
return reorderPlans(addFeaturedTagFallback(mappedPlans), options === null || options === void 0 ? void 0 : options.pricing);
|
|
431
|
-
}
|
|
432
|
-
export async function getPaywallPlans(mode, planCatalog, options) {
|
|
433
|
-
if (!shouldLoadStripePlans(planCatalog)) {
|
|
434
|
-
return getFallbackPlans(planCatalog, options);
|
|
435
|
-
}
|
|
436
|
-
try {
|
|
437
|
-
const syncedPlans = resolvePaywallPlansFromProjectPlans(await getStripeSyncedPlanRecords(mode, resolvePlanCatalogOfferSet(planCatalog)), planCatalog, options);
|
|
438
|
-
if (syncedPlans.length > 0) {
|
|
439
|
-
return syncedPlans;
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
catch (_a) {
|
|
443
|
-
// fall through to config fallback plans
|
|
444
|
-
}
|
|
445
|
-
return getFallbackPlans(planCatalog, options);
|
|
446
|
-
}
|
|
447
193
|
export function isStripeConfigured(mode) {
|
|
448
194
|
void mode;
|
|
449
195
|
return FUNNEL_SDK_PUBLISHABLE_KEY.length > 0;
|
|
@@ -636,7 +382,7 @@ export async function completeStripeOneClickPayment(input) {
|
|
|
636
382
|
return Object.assign(Object.assign({}, payment), { status: (_f = (_e = confirmation.paymentIntent) === null || _e === void 0 ? void 0 : _e.status) !== null && _f !== void 0 ? _f : payment.status, confirmationAttempted: true });
|
|
637
383
|
}
|
|
638
384
|
export async function createStripeSubscriptionCheckout(input) {
|
|
639
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
385
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
640
386
|
const recurring = resolveCheckoutPlanRecurringConfig(input.plan);
|
|
641
387
|
if (!recurring) {
|
|
642
388
|
throw new Error('Unable to resolve the recurring interval for the selected plan');
|
|
@@ -645,22 +391,27 @@ export async function createStripeSubscriptionCheckout(input) {
|
|
|
645
391
|
offerSetId: ((_a = input.plan.offerSetId) === null || _a === void 0 ? void 0 : _a.trim()) || undefined,
|
|
646
392
|
offerSetKey: ((_b = input.plan.offerSetKey) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
|
|
647
393
|
planId: getPaywallPlanRequestId(input.plan),
|
|
648
|
-
|
|
394
|
+
planKey: ((_c = input.plan.funnelPlanKey) === null || _c === void 0 ? void 0 : _c.trim()) || input.plan.id,
|
|
395
|
+
providerPlanId: ((_d = input.plan.providerPlanId) === null || _d === void 0 ? void 0 : _d.trim()) || undefined,
|
|
396
|
+
provider: input.provider,
|
|
397
|
+
paymentProfileId: ((_e = input.paymentProfileId) === null || _e === void 0 ? void 0 : _e.trim()) || undefined,
|
|
398
|
+
runtimeConfigRevisionId: ((_f = input.runtimeConfigRevisionId) === null || _f === void 0 ? void 0 : _f.trim()) || undefined,
|
|
399
|
+
anonymousUserId: ((_g = input.anonymousUserId) === null || _g === void 0 ? void 0 : _g.trim()) || undefined,
|
|
649
400
|
title: input.plan.title,
|
|
650
|
-
description: ((
|
|
401
|
+
description: ((_h = input.plan.description) === null || _h === void 0 ? void 0 : _h.trim()) || undefined,
|
|
651
402
|
amountCents: input.plan.amountCents,
|
|
652
403
|
billingInterval: recurring.interval,
|
|
653
404
|
billingIntervalCount: recurring.intervalCount,
|
|
654
|
-
followUpProviderPlanId: ((
|
|
655
|
-
followUpPlanTitle: ((
|
|
405
|
+
followUpProviderPlanId: ((_j = input.plan.followUpProviderPlanId) === null || _j === void 0 ? void 0 : _j.trim()) || undefined,
|
|
406
|
+
followUpPlanTitle: ((_k = input.plan.followUpPlanTitle) === null || _k === void 0 ? void 0 : _k.trim()) || undefined,
|
|
656
407
|
followUpBillingInterval: input.plan.followUpBillingInterval,
|
|
657
408
|
followUpBillingIntervalCount: input.plan.followUpBillingIntervalCount,
|
|
658
409
|
introIterations: input.plan.introIterations,
|
|
659
|
-
couponId: ((
|
|
410
|
+
couponId: ((_l = input.couponId) === null || _l === void 0 ? void 0 : _l.trim()) || undefined,
|
|
660
411
|
analyticsMetadata: normalizeCheckoutAnalyticsMetadata(input.analyticsMetadata, input.plan),
|
|
661
|
-
customerEmail: ((
|
|
412
|
+
customerEmail: ((_m = input.customerEmail) === null || _m === void 0 ? void 0 : _m.trim()) || undefined,
|
|
662
413
|
returnUrl: input.returnUrl,
|
|
663
|
-
userId: ((
|
|
414
|
+
userId: ((_o = input.user_id) === null || _o === void 0 ? void 0 : _o.trim()) || undefined,
|
|
664
415
|
environment: input.environment,
|
|
665
416
|
runtimeConfig: input.runtimeConfig,
|
|
666
417
|
});
|
|
@@ -1,25 +1,4 @@
|
|
|
1
1
|
import type { BillingFallbackPlanConfig, BillingPlanCatalog, BillingPlanMappingCatalog } from '../config/billing.config.js';
|
|
2
|
-
export type RemoteProjectBillingPlan = {
|
|
3
|
-
id: string;
|
|
4
|
-
key: string;
|
|
5
|
-
offerSetId?: string;
|
|
6
|
-
offerSetKey?: string;
|
|
7
|
-
projectPlanId: string | null;
|
|
8
|
-
providerPlanId: string;
|
|
9
|
-
displayName: string | null;
|
|
10
|
-
description: string | null;
|
|
11
|
-
interval: string | null;
|
|
12
|
-
intervalCount: number | null;
|
|
13
|
-
trialPeriodDays: number | null;
|
|
14
|
-
currency: string | null;
|
|
15
|
-
amountMinor: number | null;
|
|
16
|
-
amountDecimal: string | null;
|
|
17
|
-
metadata: Record<string, unknown>;
|
|
18
|
-
isActive: boolean;
|
|
19
|
-
};
|
|
20
|
-
export type ResolvedMappedProjectBillingPlan = RemoteProjectBillingPlan & {
|
|
21
|
-
funnelKey: string;
|
|
22
|
-
};
|
|
23
2
|
export type BillingPlanListItem = BillingFallbackPlanConfig & {
|
|
24
3
|
key: string;
|
|
25
4
|
};
|
|
@@ -27,4 +6,3 @@ export declare const isBillingPlanMappingCatalog: (value: unknown) => value is B
|
|
|
27
6
|
export declare const buildBillingPlanMappingCatalog: (planCatalog: BillingPlanCatalog) => BillingPlanMappingCatalog;
|
|
28
7
|
export declare const buildBillingPlanList: (planCatalog: BillingPlanCatalog) => BillingPlanListItem[];
|
|
29
8
|
export declare const getFallbackBillingPlans: (planCatalog?: BillingPlanCatalog | readonly BillingFallbackPlanConfig[]) => BillingFallbackPlanConfig[];
|
|
30
|
-
export declare const resolveMappedProjectPlans: (mappingCatalog: BillingPlanMappingCatalog, projectPlans: readonly RemoteProjectBillingPlan[]) => ResolvedMappedProjectBillingPlan[];
|
|
@@ -46,18 +46,3 @@ export const getFallbackBillingPlans = (planCatalog) => {
|
|
|
46
46
|
}
|
|
47
47
|
return Object.values(planCatalog);
|
|
48
48
|
};
|
|
49
|
-
export const resolveMappedProjectPlans = (mappingCatalog, projectPlans) => {
|
|
50
|
-
const projectPlanById = new Map(projectPlans.flatMap((plan) => {
|
|
51
|
-
const keys = [plan.projectPlanId, plan.id].filter((key) => typeof key === 'string' && key.length > 0);
|
|
52
|
-
return keys.map((key) => [key, plan]);
|
|
53
|
-
}));
|
|
54
|
-
return Object.entries(mappingCatalog).flatMap(([funnelKey, mapping]) => {
|
|
55
|
-
const projectPlan = projectPlanById.get(mapping.projectPlanId) || null;
|
|
56
|
-
if (!projectPlan) {
|
|
57
|
-
return [];
|
|
58
|
-
}
|
|
59
|
-
return [
|
|
60
|
-
Object.assign(Object.assign({}, projectPlan), { funnelKey }),
|
|
61
|
-
];
|
|
62
|
-
});
|
|
63
|
-
};
|
|
@@ -4,6 +4,7 @@ import { type PaywallPlan } from '../providers/stripe/services/stripe.service.js
|
|
|
4
4
|
export type PublishedBillingPlan = BillingFallbackPlanConfig & OfferSetRuntimePlanOverrides;
|
|
5
5
|
export type ResolvedPublishedBillingRuntime = {
|
|
6
6
|
revisionId: string | null;
|
|
7
|
+
paymentsApiVersion: 'v1' | 'v2';
|
|
7
8
|
mode: RuntimeMode;
|
|
8
9
|
offerSetId: string;
|
|
9
10
|
paymentProfileId: string | null;
|
|
@@ -2,7 +2,7 @@ import { resolveGeneratedOfferSetRuntime, resolvePublishedOfferSetSelection, res
|
|
|
2
2
|
import { buildBillingDiscountCatalog } from './paywallOffer.service.js';
|
|
3
3
|
import { buildConfigPaywallPlans, } from '../providers/stripe/services/stripe.service.js';
|
|
4
4
|
export const resolvePublishedBillingRuntime = ({ config, featureFlags, mode, search = '', defaultOfferSetId, baseCatalogsByMode, fallbackDiscounts, resolvedExperiments = resolvePublishedRuntimeExperiments(config), }) => {
|
|
5
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
5
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
6
6
|
const offerSets = (_a = config === null || config === void 0 ? void 0 : config.offerSets) !== null && _a !== void 0 ? _a : [];
|
|
7
7
|
const selection = resolvePublishedOfferSetSelection({
|
|
8
8
|
offerSets,
|
|
@@ -26,12 +26,13 @@ export const resolvePublishedBillingRuntime = ({ config, featureFlags, mode, sea
|
|
|
26
26
|
const paymentProviderConfig = (_c = (_b = runtime.offerSet) === null || _b === void 0 ? void 0 : _b.paymentProviderConfigByMode) === null || _c === void 0 ? void 0 : _c[mode];
|
|
27
27
|
return {
|
|
28
28
|
revisionId: (_d = config === null || config === void 0 ? void 0 : config.revisionId) !== null && _d !== void 0 ? _d : null,
|
|
29
|
+
paymentsApiVersion: (_e = config === null || config === void 0 ? void 0 : config.paymentsApiVersion) !== null && _e !== void 0 ? _e : 'v1',
|
|
29
30
|
mode,
|
|
30
31
|
offerSetId: selection.offerSetId,
|
|
31
|
-
paymentProfileId: ((
|
|
32
|
+
paymentProfileId: ((_g = (_f = runtime.offerSet) === null || _f === void 0 ? void 0 : _f.paymentProfileId) === null || _g === void 0 ? void 0 : _g.trim()) || null,
|
|
32
33
|
provider,
|
|
33
34
|
stripePublishableKey: provider === 'stripe' && (paymentProviderConfig === null || paymentProviderConfig === void 0 ? void 0 : paymentProviderConfig.provider) === 'stripe'
|
|
34
|
-
? ((
|
|
35
|
+
? ((_h = paymentProviderConfig === null || paymentProviderConfig === void 0 ? void 0 : paymentProviderConfig.stripePublishableKey) === null || _h === void 0 ? void 0 : _h.trim()) || null
|
|
35
36
|
: null,
|
|
36
37
|
experimentId: selection.experimentId,
|
|
37
38
|
variantKey: selection.variantKey,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@funnelsgrove/payments",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.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.82",
|
|
36
|
+
"@funnelsgrove/runtime": "^0.9.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",
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { type RuntimeMode } from '@funnelsgrove/runtime';
|
|
2
|
-
import type { BillingFallbackPlanConfig, BillingPlanInputCatalog } from '../../../config/billing.config.js';
|
|
3
|
-
import { type PaywallPlan, type PaywallPlanResolutionOptions } from '../services/stripe.service.js';
|
|
4
|
-
type UseResolvedPaywallPlansInput = {
|
|
5
|
-
runtimeMode: RuntimeMode;
|
|
6
|
-
planCatalog?: BillingPlanInputCatalog | readonly BillingFallbackPlanConfig[];
|
|
7
|
-
resolutionOptions?: PaywallPlanResolutionOptions;
|
|
8
|
-
previewPlans?: readonly PaywallPlan[] | null;
|
|
9
|
-
};
|
|
10
|
-
export declare const useResolvedPaywallPlans: ({ runtimeMode, planCatalog, resolutionOptions, previewPlans, }: UseResolvedPaywallPlansInput) => {
|
|
11
|
-
plans: readonly PaywallPlan[];
|
|
12
|
-
loading: boolean;
|
|
13
|
-
error: string | null;
|
|
14
|
-
};
|
|
15
|
-
export {};
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
-
import { isPreviewFrameRuntime } from '@funnelsgrove/runtime';
|
|
4
|
-
import { getFallbackPlans, getPaywallPlans, } from '../services/stripe.service.js';
|
|
5
|
-
import { isBillingPlanMappingCatalog } from '../../../services/planCatalog.service.js';
|
|
6
|
-
export const useResolvedPaywallPlans = ({ runtimeMode, planCatalog, resolutionOptions, previewPlans, }) => {
|
|
7
|
-
const fallbackPlans = useMemo(() => getFallbackPlans(planCatalog, resolutionOptions), [planCatalog, resolutionOptions]);
|
|
8
|
-
const isMappingCatalog = Boolean(planCatalog) && !Array.isArray(planCatalog) && isBillingPlanMappingCatalog(planCatalog);
|
|
9
|
-
const shouldLoadRemotePlans = !planCatalog || isMappingCatalog;
|
|
10
|
-
const [plans, setPlans] = useState(() => (previewPlans === null || previewPlans === void 0 ? void 0 : previewPlans.length) ? previewPlans : fallbackPlans);
|
|
11
|
-
const [loading, setLoading] = useState(shouldLoadRemotePlans);
|
|
12
|
-
const [error, setError] = useState(null);
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
if (previewPlans === null || previewPlans === void 0 ? void 0 : previewPlans.length) {
|
|
15
|
-
setPlans(previewPlans);
|
|
16
|
-
setLoading(false);
|
|
17
|
-
setError(null);
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
if (!shouldLoadRemotePlans || (isPreviewFrameRuntime() && !isMappingCatalog)) {
|
|
21
|
-
setPlans(fallbackPlans);
|
|
22
|
-
setLoading(false);
|
|
23
|
-
setError(null);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
let isActive = true;
|
|
27
|
-
const load = async () => {
|
|
28
|
-
setLoading(true);
|
|
29
|
-
setError(null);
|
|
30
|
-
try {
|
|
31
|
-
const nextPlans = await getPaywallPlans(runtimeMode, planCatalog, resolutionOptions);
|
|
32
|
-
if (!isActive) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
setPlans(nextPlans);
|
|
36
|
-
}
|
|
37
|
-
catch (nextError) {
|
|
38
|
-
if (!isActive) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
setPlans(fallbackPlans);
|
|
42
|
-
setError(nextError instanceof Error ? nextError.message : 'Unable to load plans');
|
|
43
|
-
}
|
|
44
|
-
finally {
|
|
45
|
-
if (isActive) {
|
|
46
|
-
setLoading(false);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
void load();
|
|
51
|
-
return () => {
|
|
52
|
-
isActive = false;
|
|
53
|
-
};
|
|
54
|
-
}, [
|
|
55
|
-
fallbackPlans,
|
|
56
|
-
isMappingCatalog,
|
|
57
|
-
planCatalog,
|
|
58
|
-
previewPlans,
|
|
59
|
-
resolutionOptions,
|
|
60
|
-
runtimeMode,
|
|
61
|
-
shouldLoadRemotePlans,
|
|
62
|
-
]);
|
|
63
|
-
return {
|
|
64
|
-
plans,
|
|
65
|
-
loading,
|
|
66
|
-
error,
|
|
67
|
-
};
|
|
68
|
-
};
|