@funnelsgrove/payments 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,8 +2,11 @@ import type { Stripe } from '@stripe/stripe-js';
2
2
  import type { RuntimeMode } from '@funnelsgrove/runtime';
3
3
  import { type CheckoutPreparationLoading, type CheckoutPreparationSource } from '../../paymentProvider.types.js';
4
4
  import { type PaywallPlan, type StripeRuntimeConfigOverrides } from '../services/stripe.service.js';
5
- type StripeOneTimeCheckoutPlanInput = Pick<PaywallPlan, 'amountCents' | 'analyticsPurchaseValue' | 'description' | 'id' | 'providerPlanId' | 'title'>;
5
+ type StripeOneTimeCheckoutPlanInput = Pick<PaywallPlan, 'amountCents' | 'analyticsPurchaseValue' | 'description' | 'id' | 'providerPlanId' | 'title' | 'funnelPlanKey' | 'offerSetId' | 'offerSetKey'>;
6
6
  export type StripeOneTimeCheckoutSessionInput = {
7
+ runtimeConfigRevisionId?: string | null;
8
+ paymentProfileId?: string | null;
9
+ provider?: 'stripe' | null;
7
10
  analyticsMetadata?: Record<string, unknown> | null;
8
11
  checkoutMode: RuntimeMode;
9
12
  couponId?: string | null;
@@ -40,10 +43,10 @@ export type StripeOneTimeCheckoutSession = {
40
43
  stripePromise: Promise<Stripe | null> | null;
41
44
  };
42
45
  export declare const buildStripeOneTimeCheckoutPreparationAnalyticsMetadata: (analyticsMetadata: Record<string, unknown> | null | undefined, options?: StripeOneTimeCheckoutPreparationOptions) => Record<string, unknown> | null | undefined;
43
- export type StripeOneTimeCheckoutIntentKeyInput = Pick<StripeOneTimeCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'plan' | 'returnUrl' | 'runtimeConfig' | 'stripePublishableKey' | 'userId'> & {
46
+ export type StripeOneTimeCheckoutIntentKeyInput = Pick<StripeOneTimeCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'plan' | 'returnUrl' | 'runtimeConfig' | 'stripePublishableKey' | 'userId' | 'runtimeConfigRevisionId' | 'paymentProfileId' | 'provider'> & {
44
47
  analyticsMetadata?: Record<string, unknown> | null;
45
48
  };
46
- export declare function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutIntentKeyInput): string;
49
+ export declare function buildStripeOneTimeCheckoutIntentKey({ runtimeConfigRevisionId, paymentProfileId, provider, checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutIntentKeyInput): string;
47
50
  export declare function shouldResetStripeOneTimeCheckoutSessionForIntentKey(previousIntentKey: string | null, nextIntentKey: string): boolean;
48
- export declare function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutSessionInput): StripeOneTimeCheckoutSession;
51
+ export declare function useStripeOneTimeCheckoutSession({ runtimeConfigRevisionId, paymentProfileId, provider, analyticsMetadata, checkoutMode, couponId, customerEmail, enabled, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutSessionInput): StripeOneTimeCheckoutSession;
49
52
  export {};
@@ -36,9 +36,13 @@ export const buildStripeOneTimeCheckoutPreparationAnalyticsMetadata = (analytics
36
36
  const _b = analyticsMetadata !== null && analyticsMetadata !== void 0 ? analyticsMetadata : {}, { payment_method: _paymentMethod, paymentMethod: _camelCasePaymentMethod } = _b, metadata = __rest(_b, ["payment_method", "paymentMethod"]);
37
37
  return Object.assign(Object.assign(Object.assign({}, metadata), (checkoutStartSource ? { checkoutStartSource } : {})), (paymentMethod ? { payment_method: paymentMethod } : {}));
38
38
  };
39
- export function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
40
- var _a;
39
+ export function buildStripeOneTimeCheckoutIntentKey({ runtimeConfigRevisionId, paymentProfileId, provider, checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
40
+ var _a, _b, _c, _d;
41
41
  const runtimeConfigSignature = [
42
+ (_a = runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.paymentsApiVersion) !== null && _a !== void 0 ? _a : 'v1',
43
+ runtimeConfigRevisionId !== null && runtimeConfigRevisionId !== void 0 ? runtimeConfigRevisionId : '',
44
+ paymentProfileId !== null && paymentProfileId !== void 0 ? paymentProfileId : '',
45
+ provider !== null && provider !== void 0 ? provider : '',
42
46
  normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.apiBaseUrl),
43
47
  normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelId),
44
48
  normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelVersionId),
@@ -46,9 +50,11 @@ export function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, cu
46
50
  normalizeRuntimeConfigValue(stripePublishableKey),
47
51
  ].join('|');
48
52
  const planSignature = [
53
+ (_b = plan === null || plan === void 0 ? void 0 : plan.offerSetId) !== null && _b !== void 0 ? _b : '',
54
+ (_c = plan === null || plan === void 0 ? void 0 : plan.funnelPlanKey) !== null && _c !== void 0 ? _c : '',
49
55
  normalizeRuntimeConfigValue(plan === null || plan === void 0 ? void 0 : plan.id),
50
56
  normalizeRuntimeConfigValue(plan === null || plan === void 0 ? void 0 : plan.providerPlanId),
51
- (_a = plan === null || plan === void 0 ? void 0 : plan.amountCents) !== null && _a !== void 0 ? _a : '',
57
+ (_d = plan === null || plan === void 0 ? void 0 : plan.amountCents) !== null && _d !== void 0 ? _d : '',
52
58
  ].join('|');
53
59
  const customerEmailSignature = normalizeRuntimeConfigValue(customerEmail);
54
60
  const userIdSignature = normalizeRuntimeConfigValue(userId);
@@ -66,7 +72,7 @@ export function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, cu
66
72
  export function shouldResetStripeOneTimeCheckoutSessionForIntentKey(previousIntentKey, nextIntentKey) {
67
73
  return previousIntentKey !== null && previousIntentKey !== nextIntentKey;
68
74
  }
69
- export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled = true, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
75
+ export function useStripeOneTimeCheckoutSession({ runtimeConfigRevisionId, paymentProfileId, provider, analyticsMetadata, checkoutMode, couponId, customerEmail, enabled = true, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
70
76
  var _a, _b, _c;
71
77
  const [clientSecret, setClientSecret] = useState(null);
72
78
  const [clientSecretIntentKey, setClientSecretIntentKey] = useState(null);
@@ -76,11 +82,16 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
76
82
  const [runtimeStripePublishableKey, setRuntimeStripePublishableKey] = useState(null);
77
83
  const creatingIntentRef = useRef(null);
78
84
  const requestIdRef = useRef(0);
85
+ const attemptRef = useRef(null);
86
+ const anonymousUserIdRef = useRef(null);
79
87
  const configured = enabled &&
80
88
  (isStripeConfigured(checkoutMode) ||
81
89
  Boolean(normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey)) ||
82
90
  Boolean(normalizeRuntimeConfigValue(stripePublishableKey)));
83
91
  const intentKey = buildStripeOneTimeCheckoutIntentKey({
92
+ runtimeConfigRevisionId,
93
+ paymentProfileId,
94
+ provider,
84
95
  checkoutMode,
85
96
  couponId,
86
97
  customerEmail,
@@ -124,6 +135,7 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
124
135
  onError === null || onError === void 0 ? void 0 : onError(message);
125
136
  }, [clearActiveCheckoutSession, onError]);
126
137
  const reset = useCallback(() => {
138
+ attemptRef.current = null;
127
139
  clearActiveCheckoutSession();
128
140
  setLoading(createEmptyCheckoutPreparationLoading());
129
141
  setRuntimeStripePublishableKey(null);
@@ -142,7 +154,7 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
142
154
  : Object.assign(Object.assign({}, current), { [source]: value }));
143
155
  }, []);
144
156
  const createCheckoutSession = useCallback(async (options = {}) => {
145
- var _a;
157
+ var _a, _b, _c;
146
158
  const forceNew = options.forceNew === true;
147
159
  if (!configured || !plan) {
148
160
  return null;
@@ -155,6 +167,14 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
155
167
  }
156
168
  if (forceNew) {
157
169
  clearActiveCheckoutSession();
170
+ attemptRef.current = null;
171
+ }
172
+ if ((runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.paymentsApiVersion) === 'v2' && ((_b = attemptRef.current) === null || _b === void 0 ? void 0 : _b.key) !== intentKey) {
173
+ attemptRef.current = { key: intentKey, id: crypto.randomUUID() };
174
+ }
175
+ const idempotencyKey = (_c = attemptRef.current) === null || _c === void 0 ? void 0 : _c.id;
176
+ if (idempotencyKey && !userId && !anonymousUserIdRef.current) {
177
+ anonymousUserIdRef.current = `anonymous_${crypto.randomUUID()}`;
158
178
  }
159
179
  const requestKey = intentKey;
160
180
  const requestId = requestIdRef.current + 1;
@@ -163,6 +183,11 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
163
183
  var _a, _b, _c, _d, _e, _f, _g, _h;
164
184
  try {
165
185
  const response = await createStripeOneTimeCheckout({
186
+ idempotencyKey,
187
+ anonymousUserId: anonymousUserIdRef.current,
188
+ runtimeConfigRevisionId,
189
+ paymentProfileId,
190
+ provider,
166
191
  plan,
167
192
  analyticsMetadata: buildStripeOneTimeCheckoutPreparationAnalyticsMetadata(analyticsMetadataRef.current, options),
168
193
  couponId,
@@ -208,6 +233,9 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
208
233
  return checkoutRequest;
209
234
  }, [
210
235
  activeClientSecret,
236
+ runtimeConfigRevisionId,
237
+ paymentProfileId,
238
+ provider,
211
239
  checkoutMode,
212
240
  clearActiveCheckoutSession,
213
241
  configured,
@@ -68,6 +68,11 @@ type CreatePaymentIntentResponse = {
68
68
  };
69
69
  type CreateOneTimeCheckoutInput = {
70
70
  plan: CheckoutSessionPlanInput;
71
+ runtimeConfigRevisionId?: string | null;
72
+ paymentProfileId?: string | null;
73
+ provider?: 'stripe' | null;
74
+ anonymousUserId?: string | null;
75
+ idempotencyKey?: string | null;
71
76
  couponId?: string | null;
72
77
  analyticsMetadata?: Record<string, unknown> | null;
73
78
  customerEmail?: string | null;
@@ -93,6 +98,11 @@ export declare function createStripeOneTimeCheckout(input: CreateOneTimeCheckout
93
98
  export declare function createStripePaymentIntent(input: CreatePaymentIntentInput): Promise<CreatePaymentIntentResponse>;
94
99
  export type ChargeOneClickPaymentInput = {
95
100
  planId: string;
101
+ planKey?: string | null;
102
+ offerSetId?: string | null;
103
+ runtimeConfigRevisionId?: string | null;
104
+ paymentProfileId?: string | null;
105
+ provider?: 'stripe' | null;
96
106
  providerPlanId?: string | null;
97
107
  amountCents: number;
98
108
  analyticsMetadata?: Record<string, unknown> | null;
@@ -299,20 +299,26 @@ const normalizeCheckoutAnalyticsMetadata = (metadata, plan) => {
299
299
  return Object.assign(Object.assign({}, (normalized !== null && normalized !== void 0 ? normalized : {})), { analyticsPurchaseValue });
300
300
  };
301
301
  export async function createStripeOneTimeCheckout(input) {
302
- var _a, _b, _c, _d, _e, _f, _g;
302
+ var _a, _b, _c, _d, _e, _f, _g, _h;
303
303
  return funnelSdkService.createOneTimeCheckout({
304
- offerSetId: ((_a = input.plan.offerSetId) === null || _a === void 0 ? void 0 : _a.trim()) || undefined,
305
- offerSetKey: ((_b = input.plan.offerSetKey) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
304
+ planKey: ((_a = input.plan.funnelPlanKey) === null || _a === void 0 ? void 0 : _a.trim()) || input.plan.id,
305
+ runtimeConfigRevisionId: input.runtimeConfigRevisionId,
306
+ paymentProfileId: input.paymentProfileId,
307
+ provider: input.provider,
308
+ anonymousUserId: input.anonymousUserId,
309
+ idempotencyKey: input.idempotencyKey,
310
+ offerSetId: ((_b = input.plan.offerSetId) === null || _b === void 0 ? void 0 : _b.trim()) || undefined,
311
+ offerSetKey: ((_c = input.plan.offerSetKey) === null || _c === void 0 ? void 0 : _c.trim()) || undefined,
306
312
  planId: getPaywallPlanRequestId(input.plan),
307
- providerPlanId: ((_c = input.plan.providerPlanId) === null || _c === void 0 ? void 0 : _c.trim()) || undefined,
313
+ providerPlanId: ((_d = input.plan.providerPlanId) === null || _d === void 0 ? void 0 : _d.trim()) || undefined,
308
314
  title: input.plan.title,
309
- description: ((_d = input.plan.description) === null || _d === void 0 ? void 0 : _d.trim()) || undefined,
315
+ description: ((_e = input.plan.description) === null || _e === void 0 ? void 0 : _e.trim()) || undefined,
310
316
  amountCents: input.plan.amountCents,
311
- couponId: ((_e = input.couponId) === null || _e === void 0 ? void 0 : _e.trim()) || undefined,
317
+ couponId: ((_f = input.couponId) === null || _f === void 0 ? void 0 : _f.trim()) || undefined,
312
318
  analyticsMetadata: normalizeCheckoutAnalyticsMetadata(input.analyticsMetadata, input.plan),
313
- customerEmail: ((_f = input.customerEmail) === null || _f === void 0 ? void 0 : _f.trim()) || undefined,
319
+ customerEmail: ((_g = input.customerEmail) === null || _g === void 0 ? void 0 : _g.trim()) || undefined,
314
320
  returnUrl: input.returnUrl,
315
- userId: ((_g = input.user_id) === null || _g === void 0 ? void 0 : _g.trim()) || undefined,
321
+ userId: ((_h = input.user_id) === null || _h === void 0 ? void 0 : _h.trim()) || undefined,
316
322
  environment: input.environment,
317
323
  runtimeConfig: input.runtimeConfig,
318
324
  });
@@ -337,6 +343,11 @@ export async function createStripePaymentIntent(input) {
337
343
  export async function chargeStripeOneClickPayment(input) {
338
344
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
339
345
  return funnelSdkService.chargeOneClickPayment({
346
+ planKey: input.planKey,
347
+ offerSetId: input.offerSetId,
348
+ runtimeConfigRevisionId: input.runtimeConfigRevisionId,
349
+ paymentProfileId: input.paymentProfileId,
350
+ provider: input.provider,
340
351
  planId: input.planId,
341
352
  providerPlanId: ((_a = input.providerPlanId) === null || _a === void 0 ? void 0 : _a.trim()) || undefined,
342
353
  amountCents: input.amountCents,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funnelsgrove/payments",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/The-Solid-Grove/funnelsgrove.git",
@@ -32,8 +32,8 @@
32
32
  "test:run": "vitest run --passWithNoTests"
33
33
  },
34
34
  "dependencies": {
35
- "@funnelsgrove/analytics": "^0.1.83",
36
- "@funnelsgrove/runtime": "^0.10.0",
35
+ "@funnelsgrove/analytics": "^0.1.84",
36
+ "@funnelsgrove/runtime": "^0.11.0",
37
37
  "@solidgate/react-sdk": "1.34.0",
38
38
  "@stripe/react-stripe-js": "^5.6.0",
39
39
  "@stripe/stripe-js": "^8.7.0",