@funnelsgrove/payments 0.11.4 → 0.11.6
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 +20 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/providers/stripe/hooks/checkoutAttempt.d.ts +11 -0
- package/dist/providers/stripe/hooks/checkoutAttempt.js +10 -0
- package/dist/providers/stripe/hooks/useStripeOneTimeCheckoutSession.js +10 -5
- package/dist/providers/stripe/hooks/useStripeSubscriptionCheckoutSession.js +17 -1
- package/dist/providers/stripe/services/checkout/createOneTimeCheckout.d.ts +2 -0
- package/dist/providers/stripe/services/checkout/createOneTimeCheckout.js +5 -0
- package/dist/providers/stripe/services/checkout/createSubscriptionCheckout.d.ts +2 -0
- package/dist/providers/stripe/services/checkout/createSubscriptionCheckout.js +5 -0
- package/dist/providers/stripe/services/checkout/requests.d.ts +84 -0
- package/dist/providers/stripe/services/checkout/requests.js +100 -0
- package/dist/providers/stripe/services/checkout/types.d.ts +84 -0
- package/dist/providers/stripe/services/checkout/types.js +1 -0
- package/dist/providers/stripe/services/checkout/updateSubscriptionCheckoutPlan.d.ts +2 -0
- package/dist/providers/stripe/services/checkout/updateSubscriptionCheckoutPlan.js +5 -0
- package/dist/providers/stripe/services/checkout/verifySubscriptionCheckoutPayment.d.ts +2 -0
- package/dist/providers/stripe/services/checkout/verifySubscriptionCheckoutPayment.js +5 -0
- package/dist/providers/stripe/services/hostedCheckout/createCheckoutSession.d.ts +2 -0
- package/dist/providers/stripe/services/hostedCheckout/createCheckoutSession.js +5 -0
- package/dist/providers/stripe/services/hostedCheckout/redirectToCheckout.d.ts +2 -0
- package/dist/providers/stripe/services/hostedCheckout/redirectToCheckout.js +13 -0
- package/dist/providers/stripe/services/hostedCheckout/requests.d.ts +20 -0
- package/dist/providers/stripe/services/hostedCheckout/requests.js +26 -0
- package/dist/providers/stripe/services/hostedCheckout/types.d.ts +24 -0
- package/dist/providers/stripe/services/hostedCheckout/types.js +1 -0
- package/dist/providers/stripe/services/oneClick/chargePayment.d.ts +2 -0
- package/dist/providers/stripe/services/oneClick/chargePayment.js +5 -0
- package/dist/providers/stripe/services/oneClick/completePayment.d.ts +3 -0
- package/dist/providers/stripe/services/oneClick/completePayment.js +13 -0
- package/dist/providers/stripe/services/oneClick/confirmation.d.ts +6 -0
- package/dist/providers/stripe/services/oneClick/confirmation.js +22 -0
- package/dist/providers/stripe/services/oneClick/requests.d.ts +20 -0
- package/dist/providers/stripe/services/oneClick/requests.js +23 -0
- package/dist/providers/stripe/services/oneClick/types.d.ts +40 -0
- package/dist/providers/stripe/services/oneClick/types.js +1 -0
- package/dist/providers/stripe/services/paymentIntent/createPaymentIntent.d.ts +5 -0
- package/dist/providers/stripe/services/paymentIntent/createPaymentIntent.js +8 -0
- package/dist/providers/stripe/services/paymentIntent/requests.d.ts +12 -0
- package/dist/providers/stripe/services/paymentIntent/requests.js +15 -0
- package/dist/providers/stripe/services/paymentIntent/types.d.ts +18 -0
- package/dist/providers/stripe/services/paymentIntent/types.js +1 -0
- package/dist/providers/stripe/services/shared/checkout.validator.d.ts +3 -0
- package/dist/providers/stripe/services/shared/checkout.validator.js +15 -0
- package/dist/providers/stripe/services/shared/checkoutMetadata.d.ts +3 -0
- package/dist/providers/stripe/services/shared/checkoutMetadata.js +107 -0
- package/dist/providers/stripe/services/shared/types.d.ts +2 -0
- package/dist/providers/stripe/services/shared/types.js +1 -0
- package/dist/providers/stripe/services/stripe.service.d.ts +29 -221
- package/dist/providers/stripe/services/stripe.service.js +20 -546
- package/dist/providers/stripe/services/stripeClient.d.ts +4 -0
- package/dist/providers/stripe/services/stripeClient.js +19 -0
- package/dist/services/paywallOffer.service.d.ts +1 -1
- package/dist/services/paywallPlans/recurring.d.ts +2 -0
- package/dist/services/paywallPlans/recurring.js +72 -0
- package/dist/services/paywallPlans/selection.d.ts +11 -0
- package/dist/services/paywallPlans/selection.js +144 -0
- package/dist/services/paywallPlans/types.d.ts +39 -0
- package/dist/services/paywallPlans/types.js +1 -0
- package/dist/services/paywallPlans.service.d.ts +10 -0
- package/dist/services/paywallPlans.service.js +8 -0
- package/dist/services/publishedBillingRuntime.service.d.ts +1 -1
- package/dist/services/publishedBillingRuntime.service.js +1 -1
- package/package.json +1 -1
|
@@ -1,546 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
};
|
|
22
|
-
const asPositiveIntOrNull = (value) => {
|
|
23
|
-
const numeric = asFiniteNumberOrNull(value);
|
|
24
|
-
if (numeric === null || numeric <= 0) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
return Math.round(numeric);
|
|
28
|
-
};
|
|
29
|
-
const asNonNegativeNumberOrNull = (value) => {
|
|
30
|
-
const numeric = typeof value === 'number'
|
|
31
|
-
? value
|
|
32
|
-
: typeof value === 'string' && value.trim()
|
|
33
|
-
? Number(value.trim())
|
|
34
|
-
: null;
|
|
35
|
-
if (numeric === null || !Number.isFinite(numeric) || numeric < 0) {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
return Math.round(numeric * 100) / 100;
|
|
39
|
-
};
|
|
40
|
-
const asBillingPlanIntervalOrNull = (value) => {
|
|
41
|
-
var _a;
|
|
42
|
-
const normalized = (_a = asTrimmedStringOrNull(value)) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
43
|
-
if (normalized !== 'day' &&
|
|
44
|
-
normalized !== 'week' &&
|
|
45
|
-
normalized !== 'month' &&
|
|
46
|
-
normalized !== 'year') {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
return normalized;
|
|
50
|
-
};
|
|
51
|
-
const parseBillingIntervalFromText = (value) => {
|
|
52
|
-
const normalized = (value === null || value === void 0 ? void 0 : value.trim().toLowerCase()) || '';
|
|
53
|
-
if (!normalized) {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
const explicitMatch = normalized.match(/(?:^|[^a-z])(\d+)?\s*-?\s*(day|week|month|year)s?(?:[^a-z]|$)/);
|
|
57
|
-
if (explicitMatch === null || explicitMatch === void 0 ? void 0 : explicitMatch[2]) {
|
|
58
|
-
return {
|
|
59
|
-
interval: explicitMatch[2],
|
|
60
|
-
intervalCount: explicitMatch[1] ? Number(explicitMatch[1]) : 1,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
const slashMatch = normalized.match(/\/\s*(day|week|month|year)s?\b/);
|
|
64
|
-
if (slashMatch === null || slashMatch === void 0 ? void 0 : slashMatch[1]) {
|
|
65
|
-
return {
|
|
66
|
-
interval: slashMatch[1],
|
|
67
|
-
intervalCount: 1,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
return null;
|
|
71
|
-
};
|
|
72
|
-
const resolveConfigBillingInterval = (plan) => {
|
|
73
|
-
var _a, _b, _c, _d;
|
|
74
|
-
const inferred = (_a = parseBillingIntervalFromText(plan.priceLabel)) !== null && _a !== void 0 ? _a : parseBillingIntervalFromText(plan.title);
|
|
75
|
-
const interval = (_b = plan.billingInterval) !== null && _b !== void 0 ? _b : inferred === null || inferred === void 0 ? void 0 : inferred.interval;
|
|
76
|
-
if (!interval) {
|
|
77
|
-
return {};
|
|
78
|
-
}
|
|
79
|
-
return {
|
|
80
|
-
interval,
|
|
81
|
-
intervalCount: (_d = (_c = plan.billingIntervalCount) !== null && _c !== void 0 ? _c : inferred === null || inferred === void 0 ? void 0 : inferred.intervalCount) !== null && _d !== void 0 ? _d : 1,
|
|
82
|
-
};
|
|
83
|
-
};
|
|
84
|
-
const toConfigPaywallPlan = (key, plan) => {
|
|
85
|
-
var _a, _b, _c;
|
|
86
|
-
const interval = resolveConfigBillingInterval(plan);
|
|
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' });
|
|
88
|
-
};
|
|
89
|
-
const fallbackPaywallPlans = buildConfigPaywallPlans(billingPlanList);
|
|
90
|
-
const reorderPlans = (plans, pricing) => {
|
|
91
|
-
if (!pricing || pricing.offerOrder.length === 0) {
|
|
92
|
-
return plans;
|
|
93
|
-
}
|
|
94
|
-
const orderByPlanId = new Map(pricing.offerOrder.map((planId, index) => [planId, index]));
|
|
95
|
-
return [...plans].sort((left, right) => {
|
|
96
|
-
const leftIndex = orderByPlanId.get(left.id);
|
|
97
|
-
const rightIndex = orderByPlanId.get(right.id);
|
|
98
|
-
if (leftIndex === undefined && rightIndex === undefined) {
|
|
99
|
-
return 0;
|
|
100
|
-
}
|
|
101
|
-
if (leftIndex === undefined) {
|
|
102
|
-
return 1;
|
|
103
|
-
}
|
|
104
|
-
if (rightIndex === undefined) {
|
|
105
|
-
return -1;
|
|
106
|
-
}
|
|
107
|
-
return leftIndex - rightIndex;
|
|
108
|
-
});
|
|
109
|
-
};
|
|
110
|
-
export function buildConfigPaywallPlans(planCatalog, orderedPlanIds = []) {
|
|
111
|
-
const plans = Array.isArray(planCatalog)
|
|
112
|
-
? planCatalog.map((plan, index) => toConfigPaywallPlan(String(index), plan))
|
|
113
|
-
: Object.entries(planCatalog !== null && planCatalog !== void 0 ? planCatalog : {}).map(([key, plan]) => toConfigPaywallPlan(key, plan));
|
|
114
|
-
return getOrderedPaywallPlans(plans, orderedPlanIds);
|
|
115
|
-
}
|
|
116
|
-
const toFallbackPaywallPlans = (planCatalog, options) => {
|
|
117
|
-
const sourcePlans = buildConfigPaywallPlans(planCatalog);
|
|
118
|
-
return reorderPlans(sourcePlans.length > 0 ? sourcePlans : fallbackPaywallPlans, options === null || options === void 0 ? void 0 : options.pricing);
|
|
119
|
-
};
|
|
120
|
-
const isFallbackBillingPlanCatalog = (planCatalog) => {
|
|
121
|
-
return Array.isArray(planCatalog) || !isBillingPlanMappingCatalog(planCatalog);
|
|
122
|
-
};
|
|
123
|
-
export function getFallbackPlans(planCatalog, options) {
|
|
124
|
-
if (!planCatalog) {
|
|
125
|
-
return reorderPlans(fallbackPaywallPlans, options === null || options === void 0 ? void 0 : options.pricing);
|
|
126
|
-
}
|
|
127
|
-
if (!isFallbackBillingPlanCatalog(planCatalog)) {
|
|
128
|
-
return [];
|
|
129
|
-
}
|
|
130
|
-
return toFallbackPaywallPlans(planCatalog, options);
|
|
131
|
-
}
|
|
132
|
-
export function getOrderedPaywallPlans(plans, orderedPlanIds) {
|
|
133
|
-
if (orderedPlanIds.length === 0) {
|
|
134
|
-
return plans;
|
|
135
|
-
}
|
|
136
|
-
const planByKey = new Map();
|
|
137
|
-
for (const plan of plans) {
|
|
138
|
-
for (const key of [plan.id, plan.providerPlanId]) {
|
|
139
|
-
const normalizedKey = key === null || key === void 0 ? void 0 : key.trim();
|
|
140
|
-
if (normalizedKey && !planByKey.has(normalizedKey)) {
|
|
141
|
-
planByKey.set(normalizedKey, plan);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
const selectedPlans = [];
|
|
146
|
-
const selectedPlanIds = new Set();
|
|
147
|
-
for (const planId of orderedPlanIds) {
|
|
148
|
-
const plan = planByKey.get(planId.trim()) || null;
|
|
149
|
-
if (!plan || selectedPlanIds.has(plan.id)) {
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
selectedPlans.push(plan);
|
|
153
|
-
selectedPlanIds.add(plan.id);
|
|
154
|
-
}
|
|
155
|
-
return selectedPlans;
|
|
156
|
-
}
|
|
157
|
-
export function getDefaultPlanId(plans, pricing) {
|
|
158
|
-
var _a, _b;
|
|
159
|
-
if (plans.length === 0) {
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
|
-
const countryDefaultPlanId = (_a = pricing === null || pricing === void 0 ? void 0 : pricing.defaultOfferKey) === null || _a === void 0 ? void 0 : _a.trim();
|
|
163
|
-
if (countryDefaultPlanId && plans.some((plan) => plan.id === countryDefaultPlanId)) {
|
|
164
|
-
return countryDefaultPlanId;
|
|
165
|
-
}
|
|
166
|
-
return ((_b = plans[0]) === null || _b === void 0 ? void 0 : _b.id) || null;
|
|
167
|
-
}
|
|
168
|
-
export function getPaywallPlanSelectionValue(plan) {
|
|
169
|
-
var _a;
|
|
170
|
-
return ((_a = plan.providerPlanId) === null || _a === void 0 ? void 0 : _a.trim()) || plan.id;
|
|
171
|
-
}
|
|
172
|
-
// The API resolves offer-set mappings by the funnel plan key. Stripe's price id travels in
|
|
173
|
-
// providerPlanId; duplicating it into planId bypasses the configured test/live offer mapping.
|
|
174
|
-
const getPaywallPlanRequestId = (plan) => plan.id.trim() || getPaywallPlanSelectionValue(plan);
|
|
175
|
-
export function findPaywallPlan(plans, selectionValue) {
|
|
176
|
-
const normalizedSelectionValue = (selectionValue === null || selectionValue === void 0 ? void 0 : selectionValue.trim()) || '';
|
|
177
|
-
if (!normalizedSelectionValue) {
|
|
178
|
-
return null;
|
|
179
|
-
}
|
|
180
|
-
return (plans.find((plan) => {
|
|
181
|
-
var _a;
|
|
182
|
-
const providerPlanId = ((_a = plan.providerPlanId) === null || _a === void 0 ? void 0 : _a.trim()) || '';
|
|
183
|
-
return plan.id === normalizedSelectionValue || providerPlanId === normalizedSelectionValue;
|
|
184
|
-
}) || null);
|
|
185
|
-
}
|
|
186
|
-
export function getDefaultPlanSelectionValue(plans, pricing) {
|
|
187
|
-
const defaultPlanId = getDefaultPlanId(plans, pricing);
|
|
188
|
-
if (!defaultPlanId) {
|
|
189
|
-
return null;
|
|
190
|
-
}
|
|
191
|
-
return getPaywallPlanSelectionValue(plans.find((plan) => plan.id === defaultPlanId) || plans[0]);
|
|
192
|
-
}
|
|
193
|
-
export function isStripeConfigured(mode) {
|
|
194
|
-
void mode;
|
|
195
|
-
return FUNNEL_SDK_PUBLISHABLE_KEY.length > 0;
|
|
196
|
-
}
|
|
197
|
-
export function getStripePromise(_mode, runtimePublishableKey) {
|
|
198
|
-
const resolvedPublishableKey = (runtimePublishableKey === null || runtimePublishableKey === void 0 ? void 0 : runtimePublishableKey.trim()) || '';
|
|
199
|
-
if (!resolvedPublishableKey) {
|
|
200
|
-
return null;
|
|
201
|
-
}
|
|
202
|
-
let stripePromise = stripePromiseByKey.get(resolvedPublishableKey) || null;
|
|
203
|
-
if (!stripePromise) {
|
|
204
|
-
stripePromise = loadStripe(resolvedPublishableKey);
|
|
205
|
-
stripePromiseByKey.set(resolvedPublishableKey, stripePromise);
|
|
206
|
-
}
|
|
207
|
-
return stripePromise;
|
|
208
|
-
}
|
|
209
|
-
const inferCheckoutPlanRecurringFromText = (value) => {
|
|
210
|
-
const normalized = value === null || value === void 0 ? void 0 : value.trim().toLowerCase();
|
|
211
|
-
if (!normalized) {
|
|
212
|
-
return null;
|
|
213
|
-
}
|
|
214
|
-
const countedMatch = normalized.match(/(\d+)\s*[- ]?(day|week|month|year)s?\b/);
|
|
215
|
-
if (countedMatch) {
|
|
216
|
-
return {
|
|
217
|
-
interval: countedMatch[2],
|
|
218
|
-
intervalCount: Number.parseInt(countedMatch[1] || '1', 10) || 1,
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
if (normalized.includes('daily') || normalized.includes('day')) {
|
|
222
|
-
return { interval: 'day', intervalCount: 1 };
|
|
223
|
-
}
|
|
224
|
-
if (normalized.includes('weekly') || normalized.includes('week')) {
|
|
225
|
-
return { interval: 'week', intervalCount: 1 };
|
|
226
|
-
}
|
|
227
|
-
if (normalized.includes('monthly') || normalized.includes('month')) {
|
|
228
|
-
return { interval: 'month', intervalCount: 1 };
|
|
229
|
-
}
|
|
230
|
-
if (normalized.includes('yearly') || normalized.includes('annual') || normalized.includes('year')) {
|
|
231
|
-
return { interval: 'year', intervalCount: 1 };
|
|
232
|
-
}
|
|
233
|
-
return null;
|
|
234
|
-
};
|
|
235
|
-
export const resolveCheckoutPlanRecurringConfig = (plan) => {
|
|
236
|
-
const explicitInterval = asBillingPlanIntervalOrNull(plan.billingInterval);
|
|
237
|
-
if (explicitInterval) {
|
|
238
|
-
return {
|
|
239
|
-
interval: explicitInterval,
|
|
240
|
-
intervalCount: asPositiveIntOrNull(plan.billingIntervalCount) || 1,
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
return (inferCheckoutPlanRecurringFromText(plan.title) ||
|
|
244
|
-
inferCheckoutPlanRecurringFromText(plan.providerPlanId) ||
|
|
245
|
-
inferCheckoutPlanRecurringFromText(plan.id) ||
|
|
246
|
-
inferCheckoutPlanRecurringFromText(plan.description));
|
|
247
|
-
};
|
|
248
|
-
const SENSITIVE_CHECKOUT_URL_QUERY_KEYS = new Set([
|
|
249
|
-
'customeremail',
|
|
250
|
-
'customer_email',
|
|
251
|
-
'email',
|
|
252
|
-
'fullname',
|
|
253
|
-
'full_name',
|
|
254
|
-
'name',
|
|
255
|
-
'phone',
|
|
256
|
-
'phonenumber',
|
|
257
|
-
'phone_number',
|
|
258
|
-
]);
|
|
259
|
-
const sanitizeCheckoutUrl = (value) => {
|
|
260
|
-
if (typeof value !== 'string') {
|
|
261
|
-
return undefined;
|
|
262
|
-
}
|
|
263
|
-
const trimmed = value.trim();
|
|
264
|
-
if (!trimmed) {
|
|
265
|
-
return undefined;
|
|
266
|
-
}
|
|
267
|
-
try {
|
|
268
|
-
const parsed = new URL(trimmed, typeof window !== 'undefined' ? window.location.origin : 'https://example.invalid');
|
|
269
|
-
for (const key of Array.from(parsed.searchParams.keys())) {
|
|
270
|
-
if (SENSITIVE_CHECKOUT_URL_QUERY_KEYS.has(key.trim().toLowerCase())) {
|
|
271
|
-
parsed.searchParams.delete(key);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
return parsed.toString();
|
|
275
|
-
}
|
|
276
|
-
catch (_a) {
|
|
277
|
-
return trimmed;
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
const currentCheckoutUrl = () => {
|
|
281
|
-
var _a;
|
|
282
|
-
if (typeof window === 'undefined') {
|
|
283
|
-
return undefined;
|
|
284
|
-
}
|
|
285
|
-
return sanitizeCheckoutUrl((_a = window.location) === null || _a === void 0 ? void 0 : _a.href);
|
|
286
|
-
};
|
|
287
|
-
const readMetaCookieValue = (name) => {
|
|
288
|
-
var _a;
|
|
289
|
-
if (typeof document === 'undefined') {
|
|
290
|
-
return undefined;
|
|
291
|
-
}
|
|
292
|
-
let cookieHeader;
|
|
293
|
-
try {
|
|
294
|
-
cookieHeader = document.cookie;
|
|
295
|
-
}
|
|
296
|
-
catch (_b) {
|
|
297
|
-
return undefined;
|
|
298
|
-
}
|
|
299
|
-
const encodedValue = (_a = cookieHeader
|
|
300
|
-
.split(';')
|
|
301
|
-
.map((part) => part.trim())
|
|
302
|
-
.find((part) => part.startsWith(`${name}=`))) === null || _a === void 0 ? void 0 : _a.slice(name.length + 1);
|
|
303
|
-
if (!encodedValue) {
|
|
304
|
-
return undefined;
|
|
305
|
-
}
|
|
306
|
-
try {
|
|
307
|
-
const value = decodeURIComponent(encodedValue).trim();
|
|
308
|
-
return value && value.length <= 2048 ? value : undefined;
|
|
309
|
-
}
|
|
310
|
-
catch (_c) {
|
|
311
|
-
const value = encodedValue.trim();
|
|
312
|
-
return value && value.length <= 2048 ? value : undefined;
|
|
313
|
-
}
|
|
314
|
-
};
|
|
315
|
-
const normalizeAnalyticsMetadata = (metadata) => {
|
|
316
|
-
const normalized = Object.fromEntries(Object.entries(isRecord(metadata) ? metadata : {}).filter(([, value]) => value !== undefined && value !== null && value !== ''));
|
|
317
|
-
const fbc = asTrimmedStringOrNull(normalized.fbc)
|
|
318
|
-
|| asTrimmedStringOrNull(normalized._fbc)
|
|
319
|
-
|| readMetaCookieValue('_fbc');
|
|
320
|
-
const fbp = asTrimmedStringOrNull(normalized.fbp)
|
|
321
|
-
|| asTrimmedStringOrNull(normalized._fbp)
|
|
322
|
-
|| readMetaCookieValue('_fbp');
|
|
323
|
-
const checkoutUrl = sanitizeCheckoutUrl(normalized.url) || currentCheckoutUrl();
|
|
324
|
-
const withCheckoutUrl = Object.assign(Object.assign(Object.assign(Object.assign({}, normalized), (fbc ? { fbc } : {})), (fbp ? { fbp } : {})), (checkoutUrl ? { url: checkoutUrl } : {}));
|
|
325
|
-
return Object.keys(withCheckoutUrl).length > 0 ? withCheckoutUrl : undefined;
|
|
326
|
-
};
|
|
327
|
-
const normalizeCheckoutAnalyticsMetadata = (metadata, plan) => {
|
|
328
|
-
const normalized = normalizeAnalyticsMetadata(metadata);
|
|
329
|
-
const analyticsPurchaseValue = asNonNegativeNumberOrNull(plan.analyticsPurchaseValue);
|
|
330
|
-
if (analyticsPurchaseValue === null) {
|
|
331
|
-
return normalized;
|
|
332
|
-
}
|
|
333
|
-
return Object.assign(Object.assign({}, (normalized !== null && normalized !== void 0 ? normalized : {})), { analyticsPurchaseValue });
|
|
334
|
-
};
|
|
335
|
-
export async function createStripeOneTimeCheckout(input) {
|
|
336
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
337
|
-
return funnelSdkService.createOneTimeCheckout({
|
|
338
|
-
planKey: ((_a = input.plan.funnelPlanKey) === null || _a === void 0 ? void 0 : _a.trim()) || input.plan.id,
|
|
339
|
-
runtimeConfigRevisionId: input.runtimeConfigRevisionId,
|
|
340
|
-
paymentProfileId: input.paymentProfileId,
|
|
341
|
-
provider: input.provider,
|
|
342
|
-
anonymousUserId: input.anonymousUserId,
|
|
343
|
-
idempotencyKey: input.idempotencyKey,
|
|
344
|
-
offerSetId: ((_b = input.plan.offerSetId) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
|
|
345
|
-
offerSetKey: ((_c = input.plan.offerSetKey) === null || _c === void 0 ? void 0 : _c.trim()) || undefined,
|
|
346
|
-
planId: getPaywallPlanRequestId(input.plan),
|
|
347
|
-
providerPlanId: ((_d = input.plan.providerPlanId) === null || _d === void 0 ? void 0 : _d.trim()) || undefined,
|
|
348
|
-
title: input.plan.title,
|
|
349
|
-
description: ((_e = input.plan.description) === null || _e === void 0 ? void 0 : _e.trim()) || undefined,
|
|
350
|
-
amountCents: input.plan.amountCents,
|
|
351
|
-
couponId: ((_f = input.couponId) === null || _f === void 0 ? void 0 : _f.trim()) || undefined,
|
|
352
|
-
analyticsMetadata: normalizeCheckoutAnalyticsMetadata(input.analyticsMetadata, input.plan),
|
|
353
|
-
customerEmail: ((_g = input.customerEmail) === null || _g === void 0 ? void 0 : _g.trim()) || undefined,
|
|
354
|
-
returnUrl: input.returnUrl,
|
|
355
|
-
userId: ((_h = input.user_id) === null || _h === void 0 ? void 0 : _h.trim()) || undefined,
|
|
356
|
-
environment: input.environment,
|
|
357
|
-
runtimeConfig: input.runtimeConfig,
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
/**
|
|
361
|
-
* @deprecated Use createStripeOneTimeCheckout for one-time paywall checkout.
|
|
362
|
-
*/
|
|
363
|
-
export async function createStripePaymentIntent(input) {
|
|
364
|
-
var _a, _b, _c, _d;
|
|
365
|
-
return funnelSdkService.createOneTimePaymentIntent({
|
|
366
|
-
offerSetId: ((_a = input.offerSetId) === null || _a === void 0 ? void 0 : _a.trim()) || undefined,
|
|
367
|
-
offerSetKey: ((_b = input.offerSetKey) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
|
|
368
|
-
planId: input.planId,
|
|
369
|
-
amountCents: input.amountCents,
|
|
370
|
-
couponId: ((_c = input.couponId) === null || _c === void 0 ? void 0 : _c.trim()) || undefined,
|
|
371
|
-
analyticsMetadata: normalizeAnalyticsMetadata(input.analyticsMetadata),
|
|
372
|
-
userId: ((_d = input.user_id) === null || _d === void 0 ? void 0 : _d.trim()) || undefined,
|
|
373
|
-
environment: input.environment,
|
|
374
|
-
runtimeConfig: input.runtimeConfig,
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
export async function chargeStripeOneClickPayment(input) {
|
|
378
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
379
|
-
return funnelSdkService.chargeOneClickPayment({
|
|
380
|
-
planKey: input.planKey,
|
|
381
|
-
offerSetId: input.offerSetId,
|
|
382
|
-
runtimeConfigRevisionId: input.runtimeConfigRevisionId,
|
|
383
|
-
paymentProfileId: input.paymentProfileId,
|
|
384
|
-
provider: input.provider,
|
|
385
|
-
planId: input.planId,
|
|
386
|
-
providerPlanId: ((_a = input.providerPlanId) === null || _a === void 0 ? void 0 : _a.trim()) || undefined,
|
|
387
|
-
amountCents: input.amountCents,
|
|
388
|
-
currency: ((_b = input.currency) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
|
|
389
|
-
description: ((_c = input.description) === null || _c === void 0 ? void 0 : _c.trim()) || undefined,
|
|
390
|
-
analyticsMetadata: normalizeAnalyticsMetadata(input.analyticsMetadata),
|
|
391
|
-
userId: ((_d = input.userId) === null || _d === void 0 ? void 0 : _d.trim()) || ((_e = input.user_id) === null || _e === void 0 ? void 0 : _e.trim()) || undefined,
|
|
392
|
-
stripeCustomerId: ((_f = input.stripeCustomerId) === null || _f === void 0 ? void 0 : _f.trim()) || ((_g = input.stripe_customer_id) === null || _g === void 0 ? void 0 : _g.trim()) || undefined,
|
|
393
|
-
checkoutSessionId: ((_h = input.checkoutSessionId) === null || _h === void 0 ? void 0 : _h.trim()) || undefined,
|
|
394
|
-
idempotencyKey: ((_j = input.idempotencyKey) === null || _j === void 0 ? void 0 : _j.trim()) || undefined,
|
|
395
|
-
environment: input.environment,
|
|
396
|
-
runtimeConfig: input.runtimeConfig,
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
export const requiresStripeOneClickConfirmation = (status) => {
|
|
400
|
-
return status === 'requires_action' || status === 'requires_confirmation';
|
|
401
|
-
};
|
|
402
|
-
export async function completeStripeOneClickPayment(input) {
|
|
403
|
-
var _a, _b, _c, _d, _e, _f;
|
|
404
|
-
const payment = await chargeStripeOneClickPayment(input);
|
|
405
|
-
if (!requiresStripeOneClickConfirmation(payment.status)) {
|
|
406
|
-
return Object.assign(Object.assign({}, payment), { confirmationAttempted: false });
|
|
407
|
-
}
|
|
408
|
-
const clientSecret = (_a = payment.clientSecret) === null || _a === void 0 ? void 0 : _a.trim();
|
|
409
|
-
const stripePublishableKey = (_b = payment.stripePublishableKey) === null || _b === void 0 ? void 0 : _b.trim();
|
|
410
|
-
if (!clientSecret || !stripePublishableKey) {
|
|
411
|
-
throw new Error('One-click payment requires Stripe confirmation, but confirmation details are missing.');
|
|
412
|
-
}
|
|
413
|
-
const stripe = await getStripePromise((_d = (_c = payment.environment) !== null && _c !== void 0 ? _c : input.environment) !== null && _d !== void 0 ? _d : 'live', stripePublishableKey);
|
|
414
|
-
if (!stripe) {
|
|
415
|
-
throw new Error('Stripe could not be initialized for one-click payment confirmation.');
|
|
416
|
-
}
|
|
417
|
-
const confirmation = await stripe.confirmPayment({
|
|
418
|
-
clientSecret,
|
|
419
|
-
confirmParams: {
|
|
420
|
-
return_url: input.returnUrl,
|
|
421
|
-
},
|
|
422
|
-
redirect: 'if_required',
|
|
423
|
-
});
|
|
424
|
-
if (confirmation.error) {
|
|
425
|
-
throw new Error(confirmation.error.message || 'Unable to confirm one-click payment.');
|
|
426
|
-
}
|
|
427
|
-
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 });
|
|
428
|
-
}
|
|
429
|
-
export async function createStripeSubscriptionCheckout(input) {
|
|
430
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
431
|
-
const recurring = resolveCheckoutPlanRecurringConfig(input.plan);
|
|
432
|
-
if (!recurring) {
|
|
433
|
-
throw new Error('Unable to resolve the recurring interval for the selected plan');
|
|
434
|
-
}
|
|
435
|
-
return funnelSdkService.createSubscriptionCheckout({
|
|
436
|
-
offerSetId: ((_a = input.plan.offerSetId) === null || _a === void 0 ? void 0 : _a.trim()) || undefined,
|
|
437
|
-
offerSetKey: ((_b = input.plan.offerSetKey) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
|
|
438
|
-
planId: getPaywallPlanRequestId(input.plan),
|
|
439
|
-
planKey: ((_c = input.plan.funnelPlanKey) === null || _c === void 0 ? void 0 : _c.trim()) || input.plan.id,
|
|
440
|
-
providerPlanId: ((_d = input.plan.providerPlanId) === null || _d === void 0 ? void 0 : _d.trim()) || undefined,
|
|
441
|
-
provider: input.provider,
|
|
442
|
-
paymentProfileId: ((_e = input.paymentProfileId) === null || _e === void 0 ? void 0 : _e.trim()) || undefined,
|
|
443
|
-
runtimeConfigRevisionId: ((_f = input.runtimeConfigRevisionId) === null || _f === void 0 ? void 0 : _f.trim()) || undefined,
|
|
444
|
-
anonymousUserId: ((_g = input.anonymousUserId) === null || _g === void 0 ? void 0 : _g.trim()) || undefined,
|
|
445
|
-
title: input.plan.title,
|
|
446
|
-
description: ((_h = input.plan.description) === null || _h === void 0 ? void 0 : _h.trim()) || undefined,
|
|
447
|
-
amountCents: input.plan.amountCents,
|
|
448
|
-
billingInterval: recurring.interval,
|
|
449
|
-
billingIntervalCount: recurring.intervalCount,
|
|
450
|
-
followUpProviderPlanId: ((_j = input.plan.followUpProviderPlanId) === null || _j === void 0 ? void 0 : _j.trim()) || undefined,
|
|
451
|
-
followUpPlanTitle: ((_k = input.plan.followUpPlanTitle) === null || _k === void 0 ? void 0 : _k.trim()) || undefined,
|
|
452
|
-
followUpBillingInterval: input.plan.followUpBillingInterval,
|
|
453
|
-
followUpBillingIntervalCount: input.plan.followUpBillingIntervalCount,
|
|
454
|
-
introIterations: input.plan.introIterations,
|
|
455
|
-
couponId: ((_l = input.couponId) === null || _l === void 0 ? void 0 : _l.trim()) || undefined,
|
|
456
|
-
analyticsMetadata: normalizeCheckoutAnalyticsMetadata(input.analyticsMetadata, input.plan),
|
|
457
|
-
customerEmail: ((_m = input.customerEmail) === null || _m === void 0 ? void 0 : _m.trim()) || undefined,
|
|
458
|
-
returnUrl: input.returnUrl,
|
|
459
|
-
userId: ((_o = input.user_id) === null || _o === void 0 ? void 0 : _o.trim()) || undefined,
|
|
460
|
-
environment: input.environment,
|
|
461
|
-
runtimeConfig: input.runtimeConfig,
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
export async function updateStripeSubscriptionCheckoutPlan(input) {
|
|
465
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
466
|
-
const recurring = resolveCheckoutPlanRecurringConfig(input.plan);
|
|
467
|
-
if (!recurring) {
|
|
468
|
-
throw new Error('Unable to resolve the recurring interval for the selected plan');
|
|
469
|
-
}
|
|
470
|
-
return funnelSdkService.updateSubscriptionCheckoutPlan({
|
|
471
|
-
checkoutSessionId: input.checkoutSessionId.trim(),
|
|
472
|
-
offerSetId: ((_a = input.plan.offerSetId) === null || _a === void 0 ? void 0 : _a.trim()) || undefined,
|
|
473
|
-
offerSetKey: ((_b = input.plan.offerSetKey) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
|
|
474
|
-
planId: getPaywallPlanRequestId(input.plan),
|
|
475
|
-
planKey: ((_c = input.plan.funnelPlanKey) === null || _c === void 0 ? void 0 : _c.trim()) || input.plan.id,
|
|
476
|
-
providerPlanId: ((_d = input.plan.providerPlanId) === null || _d === void 0 ? void 0 : _d.trim()) || undefined,
|
|
477
|
-
provider: input.provider,
|
|
478
|
-
paymentProfileId: ((_e = input.paymentProfileId) === null || _e === void 0 ? void 0 : _e.trim()) || undefined,
|
|
479
|
-
runtimeConfigRevisionId: ((_f = input.runtimeConfigRevisionId) === null || _f === void 0 ? void 0 : _f.trim()) || undefined,
|
|
480
|
-
title: input.plan.title,
|
|
481
|
-
description: ((_g = input.plan.description) === null || _g === void 0 ? void 0 : _g.trim()) || undefined,
|
|
482
|
-
amountCents: input.plan.amountCents,
|
|
483
|
-
billingInterval: recurring.interval,
|
|
484
|
-
billingIntervalCount: recurring.intervalCount,
|
|
485
|
-
followUpProviderPlanId: ((_h = input.plan.followUpProviderPlanId) === null || _h === void 0 ? void 0 : _h.trim()) || undefined,
|
|
486
|
-
followUpPlanTitle: ((_j = input.plan.followUpPlanTitle) === null || _j === void 0 ? void 0 : _j.trim()) || undefined,
|
|
487
|
-
followUpBillingInterval: input.plan.followUpBillingInterval,
|
|
488
|
-
followUpBillingIntervalCount: input.plan.followUpBillingIntervalCount,
|
|
489
|
-
introIterations: input.plan.introIterations,
|
|
490
|
-
couponId: ((_k = input.couponId) === null || _k === void 0 ? void 0 : _k.trim()) || undefined,
|
|
491
|
-
analyticsMetadata: normalizeCheckoutAnalyticsMetadata(input.analyticsMetadata, input.plan),
|
|
492
|
-
customerEmail: ((_l = input.customerEmail) === null || _l === void 0 ? void 0 : _l.trim()) || undefined,
|
|
493
|
-
userId: ((_m = input.user_id) === null || _m === void 0 ? void 0 : _m.trim()) || undefined,
|
|
494
|
-
environment: input.environment,
|
|
495
|
-
runtimeConfig: input.runtimeConfig,
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
export async function verifyStripeSubscriptionCheckoutPayment(input) {
|
|
499
|
-
const checkoutSessionId = input.checkoutSessionId.trim();
|
|
500
|
-
if (!checkoutSessionId) {
|
|
501
|
-
throw new Error('checkoutSessionId is required');
|
|
502
|
-
}
|
|
503
|
-
return funnelSdkService.verifySubscriptionCheckout({
|
|
504
|
-
checkoutSessionId,
|
|
505
|
-
environment: input.environment,
|
|
506
|
-
runtimeConfig: input.runtimeConfig,
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
export async function createStripeCheckoutSession(input) {
|
|
510
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
511
|
-
const recurring = resolveCheckoutPlanRecurringConfig(input.plan);
|
|
512
|
-
if (!recurring) {
|
|
513
|
-
throw new Error('Unable to resolve the recurring interval for the selected plan');
|
|
514
|
-
}
|
|
515
|
-
return funnelSdkService.createHostedCheckoutSession({
|
|
516
|
-
offerSetId: ((_a = input.plan.offerSetId) === null || _a === void 0 ? void 0 : _a.trim()) || undefined,
|
|
517
|
-
offerSetKey: ((_b = input.plan.offerSetKey) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
|
|
518
|
-
planId: getPaywallPlanRequestId(input.plan),
|
|
519
|
-
providerPlanId: ((_c = input.plan.providerPlanId) === null || _c === void 0 ? void 0 : _c.trim()) || undefined,
|
|
520
|
-
title: input.plan.title,
|
|
521
|
-
description: ((_d = input.plan.description) === null || _d === void 0 ? void 0 : _d.trim()) || undefined,
|
|
522
|
-
amountCents: input.plan.amountCents,
|
|
523
|
-
billingInterval: recurring.interval,
|
|
524
|
-
billingIntervalCount: recurring.intervalCount,
|
|
525
|
-
couponId: ((_e = input.couponId) === null || _e === void 0 ? void 0 : _e.trim()) || undefined,
|
|
526
|
-
analyticsMetadata: normalizeCheckoutAnalyticsMetadata(input.analyticsMetadata, input.plan),
|
|
527
|
-
successUrl: input.successUrl,
|
|
528
|
-
cancelUrl: input.cancelUrl,
|
|
529
|
-
customerEmail: ((_f = input.customerEmail) === null || _f === void 0 ? void 0 : _f.trim()) || undefined,
|
|
530
|
-
userId: ((_g = input.user_id) === null || _g === void 0 ? void 0 : _g.trim()) || undefined,
|
|
531
|
-
environment: input.environment,
|
|
532
|
-
runtimeConfig: input.runtimeConfig,
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
export async function redirectToStripeCheckout(input) {
|
|
536
|
-
var _a;
|
|
537
|
-
const response = await createStripeCheckoutSession(input);
|
|
538
|
-
const checkoutUrl = (_a = response.url) === null || _a === void 0 ? void 0 : _a.trim();
|
|
539
|
-
if (!checkoutUrl) {
|
|
540
|
-
throw new Error('Stripe did not return a checkout url');
|
|
541
|
-
}
|
|
542
|
-
if (typeof window !== 'undefined') {
|
|
543
|
-
window.location.assign(checkoutUrl);
|
|
544
|
-
}
|
|
545
|
-
return checkoutUrl;
|
|
546
|
-
}
|
|
1
|
+
export { buildConfigPaywallPlans } from '../../../services/paywallPlans/selection.js';
|
|
2
|
+
export { getFallbackPlans } from '../../../services/paywallPlans/selection.js';
|
|
3
|
+
export { getOrderedPaywallPlans } from '../../../services/paywallPlans/selection.js';
|
|
4
|
+
export { getDefaultPlanId } from '../../../services/paywallPlans/selection.js';
|
|
5
|
+
export { getPaywallPlanSelectionValue } from '../../../services/paywallPlans/selection.js';
|
|
6
|
+
export { findPaywallPlan } from '../../../services/paywallPlans/selection.js';
|
|
7
|
+
export { getDefaultPlanSelectionValue } from '../../../services/paywallPlans/selection.js';
|
|
8
|
+
export { isStripeConfigured } from './stripeClient.js';
|
|
9
|
+
export { getStripePromise } from './stripeClient.js';
|
|
10
|
+
export { resolveCheckoutPlanRecurringConfig } from '../../../services/paywallPlans/recurring.js';
|
|
11
|
+
export { createStripeOneTimeCheckout } from './checkout/createOneTimeCheckout.js';
|
|
12
|
+
export { createStripePaymentIntent } from './paymentIntent/createPaymentIntent.js';
|
|
13
|
+
export { chargeStripeOneClickPayment } from './oneClick/chargePayment.js';
|
|
14
|
+
export { requiresStripeOneClickConfirmation } from './oneClick/completePayment.js';
|
|
15
|
+
export { completeStripeOneClickPayment } from './oneClick/completePayment.js';
|
|
16
|
+
export { createStripeSubscriptionCheckout } from './checkout/createSubscriptionCheckout.js';
|
|
17
|
+
export { updateStripeSubscriptionCheckoutPlan } from './checkout/updateSubscriptionCheckoutPlan.js';
|
|
18
|
+
export { verifyStripeSubscriptionCheckoutPayment } from './checkout/verifySubscriptionCheckoutPayment.js';
|
|
19
|
+
export { createStripeCheckoutSession } from './hostedCheckout/createCheckoutSession.js';
|
|
20
|
+
export { redirectToStripeCheckout } from './hostedCheckout/redirectToCheckout.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Stripe } from '@stripe/stripe-js';
|
|
2
|
+
import type { RuntimeMode } from '@funnelsgrove/runtime';
|
|
3
|
+
export declare function isStripeConfigured(mode: RuntimeMode): boolean;
|
|
4
|
+
export declare function getStripePromise(_mode: RuntimeMode, runtimePublishableKey?: string | null): Promise<Stripe | null> | null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FUNNEL_SDK_PUBLISHABLE_KEY } from '@funnelsgrove/runtime';
|
|
2
|
+
import { loadStripe } from '@stripe/stripe-js';
|
|
3
|
+
const stripePromiseByKey = new Map();
|
|
4
|
+
export function isStripeConfigured(mode) {
|
|
5
|
+
void mode;
|
|
6
|
+
return FUNNEL_SDK_PUBLISHABLE_KEY.length > 0;
|
|
7
|
+
}
|
|
8
|
+
export function getStripePromise(_mode, runtimePublishableKey) {
|
|
9
|
+
const resolvedPublishableKey = (runtimePublishableKey === null || runtimePublishableKey === void 0 ? void 0 : runtimePublishableKey.trim()) || '';
|
|
10
|
+
if (!resolvedPublishableKey) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
let stripePromise = stripePromiseByKey.get(resolvedPublishableKey) || null;
|
|
14
|
+
if (!stripePromise) {
|
|
15
|
+
stripePromise = loadStripe(resolvedPublishableKey);
|
|
16
|
+
stripePromiseByKey.set(resolvedPublishableKey, stripePromise);
|
|
17
|
+
}
|
|
18
|
+
return stripePromise;
|
|
19
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BillingDiscountCatalog, BillingDiscountList } from '../config/billing.config.js';
|
|
2
|
-
import type { PaywallPlan } from '
|
|
2
|
+
import type { PaywallPlan } from './paywallPlans.service.js';
|
|
3
3
|
export type PaywallDiscountCatalog = BillingDiscountCatalog;
|
|
4
4
|
export type PaywallDiscountStage = 'first' | 'second' | 'completed';
|
|
5
5
|
export type PaywallActiveDiscountStage = Exclude<PaywallDiscountStage, 'completed'>;
|