@funnelsgrove/payments 0.7.21 → 0.7.22

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 CHANGED
@@ -98,7 +98,7 @@ When a live funnel still uses one of these, migrate the funnel deliberately with
98
98
  - `providers/solidgate/components/*`: the official-SDK checkout dialog and canonical verification lifecycle.
99
99
  - `components/ManageSubscriptionScreen`: provider-neutral subscription management UI.
100
100
 
101
- Funnels should call `resolvePublishedBillingRuntime` once at their runtime-provider boundary. Screens consume its resolved view and should not parse offer sets or pricing-experiment variants themselves.
101
+ Funnels should call `resolvePublishedBillingRuntime` once at their runtime-provider boundary. Screens consume its resolved view and should not parse offer sets or pricing-experiment variants themselves. Pass the resolved `stripePublishableKey` into shared Stripe checkout hooks so Stripe.js can load while the Checkout Session request is still in flight; the key returned by that request remains the compatibility fallback.
102
102
 
103
103
  ## Engineering Rules
104
104
 
@@ -13,6 +13,7 @@ export type StripeOneTimeCheckoutSessionInput = {
13
13
  plan?: StripeOneTimeCheckoutPlanInput | null;
14
14
  returnUrl: string;
15
15
  runtimeConfig?: StripeRuntimeConfigOverrides;
16
+ stripePublishableKey?: string | null;
16
17
  userId?: string | null;
17
18
  };
18
19
  export type StripeOneTimeCheckoutPreparationOptions = {
@@ -39,10 +40,10 @@ export type StripeOneTimeCheckoutSession = {
39
40
  stripePromise: Promise<Stripe | null> | null;
40
41
  };
41
42
  export declare const buildStripeOneTimeCheckoutPreparationAnalyticsMetadata: (analyticsMetadata: Record<string, unknown> | null | undefined, options?: StripeOneTimeCheckoutPreparationOptions) => Record<string, unknown> | null | undefined;
42
- export type StripeOneTimeCheckoutIntentKeyInput = Pick<StripeOneTimeCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'plan' | 'returnUrl' | 'runtimeConfig' | 'userId'> & {
43
+ export type StripeOneTimeCheckoutIntentKeyInput = Pick<StripeOneTimeCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'plan' | 'returnUrl' | 'runtimeConfig' | 'stripePublishableKey' | 'userId'> & {
43
44
  analyticsMetadata?: Record<string, unknown> | null;
44
45
  };
45
- export declare function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, userId, }: StripeOneTimeCheckoutIntentKeyInput): string;
46
+ export declare function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutIntentKeyInput): string;
46
47
  export declare function shouldResetStripeOneTimeCheckoutSessionForIntentKey(previousIntentKey: string | null, nextIntentKey: string): boolean;
47
- export declare function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled, onError, plan, returnUrl, runtimeConfig, userId, }: StripeOneTimeCheckoutSessionInput): StripeOneTimeCheckoutSession;
48
+ export declare function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeOneTimeCheckoutSessionInput): StripeOneTimeCheckoutSession;
48
49
  export {};
@@ -36,13 +36,14 @@ 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, userId, }) {
39
+ export function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, customerEmail, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
40
40
  var _a;
41
41
  const runtimeConfigSignature = [
42
42
  normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.apiBaseUrl),
43
43
  normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelId),
44
44
  normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelVersionId),
45
45
  normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey),
46
+ normalizeRuntimeConfigValue(stripePublishableKey),
46
47
  ].join('|');
47
48
  const planSignature = [
48
49
  normalizeRuntimeConfigValue(plan === null || plan === void 0 ? void 0 : plan.id),
@@ -65,7 +66,7 @@ export function buildStripeOneTimeCheckoutIntentKey({ checkoutMode, couponId, cu
65
66
  export function shouldResetStripeOneTimeCheckoutSessionForIntentKey(previousIntentKey, nextIntentKey) {
66
67
  return previousIntentKey !== null && previousIntentKey !== nextIntentKey;
67
68
  }
68
- export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled = true, onError, plan, returnUrl, runtimeConfig, userId, }) {
69
+ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMode, couponId, customerEmail, enabled = true, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
69
70
  var _a, _b, _c;
70
71
  const [clientSecret, setClientSecret] = useState(null);
71
72
  const [clientSecretIntentKey, setClientSecretIntentKey] = useState(null);
@@ -77,7 +78,8 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
77
78
  const requestIdRef = useRef(0);
78
79
  const configured = enabled &&
79
80
  (isStripeConfigured(checkoutMode) ||
80
- Boolean(normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey)));
81
+ Boolean(normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey)) ||
82
+ Boolean(normalizeRuntimeConfigValue(stripePublishableKey)));
81
83
  const intentKey = buildStripeOneTimeCheckoutIntentKey({
82
84
  checkoutMode,
83
85
  couponId,
@@ -85,6 +87,7 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
85
87
  plan,
86
88
  returnUrl,
87
89
  runtimeConfig,
90
+ stripePublishableKey,
88
91
  userId,
89
92
  });
90
93
  const planKey = [
@@ -94,7 +97,10 @@ export function useStripeOneTimeCheckoutSession({ analyticsMetadata, checkoutMod
94
97
  ].join('|');
95
98
  const activeClientSecret = clientSecretIntentKey === intentKey ? clientSecret : null;
96
99
  const activeCheckoutSessionId = clientSecretIntentKey === intentKey ? checkoutSessionId : null;
97
- const stripePromise = useMemo(() => getStripePromise(checkoutMode, runtimeStripePublishableKey !== null && runtimeStripePublishableKey !== void 0 ? runtimeStripePublishableKey : runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey), [checkoutMode, runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey, runtimeStripePublishableKey]);
100
+ const stripePromise = useMemo(() => {
101
+ var _a;
102
+ return getStripePromise(checkoutMode, (_a = runtimeStripePublishableKey !== null && runtimeStripePublishableKey !== void 0 ? runtimeStripePublishableKey : stripePublishableKey) !== null && _a !== void 0 ? _a : runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey);
103
+ }, [checkoutMode, runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey, runtimeStripePublishableKey, stripePublishableKey]);
98
104
  const previousIntentKeyRef = useRef(intentKey);
99
105
  const analyticsMetadataRef = useRef(analyticsMetadata);
100
106
  useEffect(() => {
@@ -14,6 +14,7 @@ export type StripeSubscriptionCheckoutSessionInput = {
14
14
  plan?: PaywallPlan | null;
15
15
  returnUrl: string;
16
16
  runtimeConfig?: StripeRuntimeConfigOverrides;
17
+ stripePublishableKey?: string | null;
17
18
  userId?: string | null;
18
19
  };
19
20
  export type StripeSubscriptionCheckoutPreparationOptions = {
@@ -42,10 +43,10 @@ export type StripeSubscriptionCheckoutSession = {
42
43
  updateCheckoutSessionPlan: () => Promise<boolean>;
43
44
  };
44
45
  export declare const buildStripeSubscriptionCheckoutPreparationAnalyticsMetadata: (analyticsMetadata: Record<string, unknown> | null | undefined, options?: StripeSubscriptionCheckoutPreparationOptions) => Record<string, unknown> | null | undefined;
45
- export type StripeSubscriptionCheckoutIntentKeyInput = Pick<StripeSubscriptionCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'returnUrl' | 'runtimeConfig' | 'userId'> & {
46
+ export type StripeSubscriptionCheckoutIntentKeyInput = Pick<StripeSubscriptionCheckoutSessionInput, 'checkoutMode' | 'couponId' | 'customerEmail' | 'returnUrl' | 'runtimeConfig' | 'stripePublishableKey' | 'userId'> & {
46
47
  analyticsMetadata?: Record<string, unknown> | null;
47
48
  };
48
- export declare function buildStripeSubscriptionCheckoutIntentKey({ checkoutMode, couponId, customerEmail, returnUrl, runtimeConfig, userId, }: StripeSubscriptionCheckoutIntentKeyInput): string;
49
+ export declare function buildStripeSubscriptionCheckoutIntentKey({ checkoutMode, couponId, customerEmail, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeSubscriptionCheckoutIntentKeyInput): string;
49
50
  export declare function shouldResetStripeSubscriptionCheckoutSessionForIntentKey(previousIntentKey: string | null, nextIntentKey: string): boolean;
50
51
  export declare function isInactiveCheckoutSessionError(message?: string | null): boolean;
51
- export declare function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled, onError, plan, returnUrl, runtimeConfig, userId, }: StripeSubscriptionCheckoutSessionInput): StripeSubscriptionCheckoutSession;
52
+ export declare function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }: StripeSubscriptionCheckoutSessionInput): StripeSubscriptionCheckoutSession;
@@ -35,12 +35,13 @@ 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, userId, }) {
38
+ export function buildStripeSubscriptionCheckoutIntentKey({ checkoutMode, couponId, customerEmail, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
39
39
  const runtimeConfigSignature = [
40
40
  normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.apiBaseUrl),
41
41
  normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelId),
42
42
  normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelVersionId),
43
43
  normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey),
44
+ normalizeRuntimeConfigValue(stripePublishableKey),
44
45
  ].join('|');
45
46
  const customerEmailSignature = normalizeRuntimeConfigValue(customerEmail);
46
47
  const userIdSignature = normalizeRuntimeConfigValue(userId);
@@ -61,7 +62,7 @@ export function isInactiveCheckoutSessionError(message) {
61
62
  var _a;
62
63
  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 : '');
63
64
  }
64
- export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled = true, onError, plan, returnUrl, runtimeConfig, userId, }) {
65
+ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMetadata, couponId, customerEmail, displayPlan, enabled = true, onError, plan, returnUrl, runtimeConfig, stripePublishableKey, userId, }) {
65
66
  var _a, _b, _c, _d, _e;
66
67
  const [clientSecret, setClientSecret] = useState(null);
67
68
  const [clientSecretIntentKey, setClientSecretIntentKey] = useState(null);
@@ -74,13 +75,15 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
74
75
  const requestIdRef = useRef(0);
75
76
  const configured = enabled &&
76
77
  (isStripeConfigured(checkoutMode) ||
77
- Boolean(normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey)));
78
+ Boolean(normalizeRuntimeConfigValue(runtimeConfig === null || runtimeConfig === void 0 ? void 0 : runtimeConfig.funnelSdkPublishableKey)) ||
79
+ Boolean(normalizeRuntimeConfigValue(stripePublishableKey)));
78
80
  const intentKey = buildStripeSubscriptionCheckoutIntentKey({
79
81
  checkoutMode,
80
82
  couponId,
81
83
  customerEmail,
82
84
  returnUrl,
83
85
  runtimeConfig,
86
+ stripePublishableKey,
84
87
  userId,
85
88
  });
86
89
  const planKey = [
@@ -93,7 +96,7 @@ export function useStripeSubscriptionCheckoutSession({ checkoutMode, analyticsMe
93
96
  const activeClientSecret = clientSecretIntentKey === intentKey ? clientSecret : null;
94
97
  const activeCheckoutSessionId = clientSecretIntentKey === intentKey ? checkoutSessionId : null;
95
98
  const activePlanKey = clientSecretIntentKey === intentKey ? clientSecretPlanKey : null;
96
- const stripePromise = useMemo(() => getStripePromise(checkoutMode, runtimeStripePublishableKey), [checkoutMode, runtimeStripePublishableKey]);
99
+ const stripePromise = useMemo(() => getStripePromise(checkoutMode, runtimeStripePublishableKey !== null && runtimeStripePublishableKey !== void 0 ? runtimeStripePublishableKey : stripePublishableKey), [checkoutMode, runtimeStripePublishableKey, stripePublishableKey]);
97
100
  const previousIntentKeyRef = useRef(intentKey);
98
101
  const analyticsMetadataRef = useRef(analyticsMetadata);
99
102
  useEffect(() => {
@@ -8,6 +8,7 @@ export type ResolvedPublishedBillingRuntime = {
8
8
  offerSetId: string;
9
9
  paymentProfileId: string | null;
10
10
  provider: 'stripe' | 'solidgate';
11
+ stripePublishableKey: string | null;
11
12
  experimentId: string | null;
12
13
  variantKey: string | null;
13
14
  experiments: readonly FunnelExperimentDefinition[];
@@ -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;
5
+ var _a, _b, _c, _d, _e, _f, _g;
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,
@@ -22,12 +22,17 @@ export const resolvePublishedBillingRuntime = ({ config, featureFlags, mode, sea
22
22
  .map((key) => planCatalog[key])
23
23
  .filter((plan) => Boolean(plan));
24
24
  const discountList = runtime.getDiscountList(mode);
25
+ const provider = runtime.getPaymentProvider(mode);
26
+ const paymentProviderConfig = (_c = (_b = runtime.offerSet) === null || _b === void 0 ? void 0 : _b.paymentProviderConfigByMode) === null || _c === void 0 ? void 0 : _c[mode];
25
27
  return {
26
- revisionId: (_b = config === null || config === void 0 ? void 0 : config.revisionId) !== null && _b !== void 0 ? _b : null,
28
+ revisionId: (_d = config === null || config === void 0 ? void 0 : config.revisionId) !== null && _d !== void 0 ? _d : null,
27
29
  mode,
28
30
  offerSetId: selection.offerSetId,
29
- paymentProfileId: ((_d = (_c = runtime.offerSet) === null || _c === void 0 ? void 0 : _c.paymentProfileId) === null || _d === void 0 ? void 0 : _d.trim()) || null,
30
- provider: runtime.getPaymentProvider(mode),
31
+ paymentProfileId: ((_f = (_e = runtime.offerSet) === null || _e === void 0 ? void 0 : _e.paymentProfileId) === null || _f === void 0 ? void 0 : _f.trim()) || null,
32
+ provider,
33
+ stripePublishableKey: provider === 'stripe' && (paymentProviderConfig === null || paymentProviderConfig === void 0 ? void 0 : paymentProviderConfig.provider) === 'stripe'
34
+ ? ((_g = paymentProviderConfig === null || paymentProviderConfig === void 0 ? void 0 : paymentProviderConfig.stripePublishableKey) === null || _g === void 0 ? void 0 : _g.trim()) || null
35
+ : null,
31
36
  experimentId: selection.experimentId,
32
37
  variantKey: selection.variantKey,
33
38
  experiments: resolvedExperiments.experiments,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funnelsgrove/payments",
3
- "version": "0.7.21",
3
+ "version": "0.7.22",
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.78",
36
- "@funnelsgrove/runtime": "^0.7.29",
35
+ "@funnelsgrove/analytics": "^0.1.79",
36
+ "@funnelsgrove/runtime": "^0.7.30",
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",