@funnelsgrove/payments 0.15.6 → 0.15.8

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.
Files changed (25) hide show
  1. package/README.md +20 -1
  2. package/dist/components/CheckoutEmailDialog.d.ts +15 -0
  3. package/dist/components/CheckoutEmailDialog.js +66 -0
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.js +2 -0
  6. package/dist/providers/stripe/components/SharedStripeCheckoutV2.styles.d.ts +1 -0
  7. package/dist/providers/stripe/components/SharedStripeCheckoutV2.styles.js +781 -0
  8. package/dist/providers/stripe/components/SharedStripeCheckoutV2Dialog.d.ts +5 -0
  9. package/dist/providers/stripe/components/SharedStripeCheckoutV2Dialog.js +8 -1092
  10. package/dist/providers/stripe/components/SharedStripeCheckoutV2Form.internal.d.ts +7 -0
  11. package/dist/providers/stripe/components/SharedStripeCheckoutV2Form.internal.js +272 -0
  12. package/dist/providers/stripe/components/SharedStripeCheckoutV2Summary.internal.d.ts +6 -0
  13. package/dist/providers/stripe/components/SharedStripeCheckoutV2Summary.internal.js +19 -0
  14. package/dist/providers/stripe/components/StripeCheckoutExpressCheckoutButton.js +10 -3
  15. package/dist/providers/stripe/components/StripeWalletSurface.internal.d.ts +5 -1
  16. package/dist/providers/stripe/components/StripeWalletSurface.internal.js +53 -4
  17. package/dist/providers/stripe/components/useCheckoutEmail.internal.d.ts +20 -0
  18. package/dist/providers/stripe/components/useCheckoutEmail.internal.js +74 -0
  19. package/dist/providers/stripe/services/checkoutCompletionAnalytics.service.d.ts +3 -1
  20. package/dist/providers/stripe/services/checkoutCompletionAnalytics.service.js +39 -1
  21. package/dist/providers/stripe/services/oneClick/completePayment.js +9 -4
  22. package/dist/providers/stripe/services/oneClick/types.d.ts +2 -0
  23. package/dist/services/checkoutEmail.d.ts +3 -0
  24. package/dist/services/checkoutEmail.js +20 -0
  25. package/package.json +2 -2
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { publicAnalyticsSdk, } from '@funnelsgrove/analytics';
13
- import { verifyStripeSubscriptionCheckoutPayment, } from './stripe.service.js';
13
+ import { verifyStripeSubscriptionCheckoutPayment } from './checkout/verifySubscriptionCheckoutPayment.js';
14
14
  import { toAnalyticsPaymentMethod } from '../../../services/paymentMethodAnalytics.service.js';
15
15
  const asRecord = (value) => {
16
16
  return value && typeof value === 'object' && !Array.isArray(value)
@@ -175,3 +175,41 @@ export async function trackPaidStripeSubscriptionCheckoutCompleted(input) {
175
175
  activeCheckoutCompletionKeys.delete(completionKey);
176
176
  }
177
177
  }
178
+ export async function trackPaidStripeOneClickPaymentCompleted(input, payment) {
179
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
180
+ const context = input.checkoutAnalytics;
181
+ const paymentIntentId = (_a = payment.paymentIntentId) === null || _a === void 0 ? void 0 : _a.trim();
182
+ if (!context || payment.status !== 'succeeded' || !paymentIntentId) {
183
+ return;
184
+ }
185
+ const runtimeConfig = (_b = input.runtimeConfig) !== null && _b !== void 0 ? _b : context.runtimeConfig;
186
+ const completionKey = buildCheckoutStorageKey('checkout_completed', paymentIntentId, runtimeConfig);
187
+ if (activeCheckoutCompletionKeys.has(completionKey)
188
+ || hasTrackedCheckoutSession('checkout_completed', paymentIntentId, runtimeConfig)) {
189
+ return;
190
+ }
191
+ activeCheckoutCompletionKeys.add(completionKey);
192
+ try {
193
+ const userId = ((_c = input.userId) === null || _c === void 0 ? void 0 : _c.trim()) || ((_d = input.user_id) === null || _d === void 0 ? void 0 : _d.trim());
194
+ const environment = (_f = (_e = payment.environment) !== null && _e !== void 0 ? _e : input.environment) !== null && _f !== void 0 ? _f : context.environment;
195
+ const eventId = publicAnalyticsSdk.trackCheckoutCompleted({
196
+ eventId: paymentIntentId,
197
+ userId,
198
+ environment,
199
+ stepId: context.stepId,
200
+ stepName: context.stepName,
201
+ stepType: context.stepType,
202
+ stepContractVersion: context.stepContractVersion,
203
+ featureFlags: context.featureFlags,
204
+ metadata: Object.assign(Object.assign(Object.assign({}, asRecord(input.analyticsMetadata)), asRecord(context.metadata)), { userId,
205
+ environment, amountCents: (_g = payment.amountCents) !== null && _g !== void 0 ? _g : input.amountCents, currency: (_j = (_h = payment.currency) !== null && _h !== void 0 ? _h : input.currency) !== null && _j !== void 0 ? _j : 'usd', planId: input.planId, providerPlanId: input.providerPlanId, payment_provider: 'stripe' }),
206
+ });
207
+ if (eventId) {
208
+ markCheckoutSessionTracked('checkout_completed', paymentIntentId, runtimeConfig);
209
+ await publicAnalyticsSdk.flush().catch(() => 0);
210
+ }
211
+ }
212
+ finally {
213
+ activeCheckoutCompletionKeys.delete(completionKey);
214
+ }
215
+ }
@@ -1,13 +1,18 @@
1
1
  import { chargeStripeOneClickPayment } from './chargePayment.js';
2
2
  import { confirmOneClickPayment } from './confirmation.js';
3
+ import { trackPaidStripeOneClickPaymentCompleted } from '../checkoutCompletionAnalytics.service.js';
3
4
  export const requiresStripeOneClickConfirmation = (status) => {
4
5
  return status === 'requires_action' || status === 'requires_confirmation';
5
6
  };
6
7
  export async function completeStripeOneClickPayment(input) {
7
8
  const payment = await chargeStripeOneClickPayment(input);
8
- if (!requiresStripeOneClickConfirmation(payment.status)) {
9
- return Object.assign(Object.assign({}, payment), { confirmationAttempted: false });
9
+ const confirmationAttempted = requiresStripeOneClickConfirmation(payment.status);
10
+ const result = Object.assign(Object.assign({}, payment), { status: confirmationAttempted ? await confirmOneClickPayment(payment, input) : payment.status, confirmationAttempted });
11
+ try {
12
+ await trackPaidStripeOneClickPaymentCompleted(input, result);
10
13
  }
11
- const status = await confirmOneClickPayment(payment, input);
12
- return Object.assign(Object.assign({}, payment), { status, confirmationAttempted: true });
14
+ catch (_a) {
15
+ // Analytics cannot turn a successful charge into a payment retry.
16
+ }
17
+ return result;
13
18
  }
@@ -1,5 +1,6 @@
1
1
  import type { RuntimeMode } from '@funnelsgrove/runtime';
2
2
  import type { StripeRuntimeConfigOverrides } from '../shared/types.js';
3
+ import type { StripeSubscriptionCheckoutAnalyticsContext } from '../checkoutCompletionAnalytics.service.js';
3
4
  export type ChargeOneClickPaymentInput = {
4
5
  planId: string;
5
6
  planKey?: string | null;
@@ -34,6 +35,7 @@ export type ChargeOneClickPaymentResponse = {
34
35
  };
35
36
  export type CompleteStripeOneClickPaymentInput = ChargeOneClickPaymentInput & {
36
37
  returnUrl: string;
38
+ checkoutAnalytics?: StripeSubscriptionCheckoutAnalyticsContext;
37
39
  };
38
40
  export type CompleteStripeOneClickPaymentResponse = ChargeOneClickPaymentResponse & {
39
41
  confirmationAttempted: boolean;
@@ -0,0 +1,3 @@
1
+ export declare const isValidCheckoutEmail: (value?: string | null) => boolean;
2
+ export declare const isCheckoutEmailError: (error: unknown) => boolean;
3
+ export declare const normalizeCheckoutEmailResult: (result: string | null | void, submittedEmail: string, invalidMessage?: string) => string;
@@ -0,0 +1,20 @@
1
+ export const isValidCheckoutEmail = (value) => { var _a; return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test((_a = value === null || value === void 0 ? void 0 : value.trim()) !== null && _a !== void 0 ? _a : ''); };
2
+ export const isCheckoutEmailError = (error) => {
3
+ const record = error && typeof error === 'object'
4
+ ? error
5
+ : null;
6
+ if ((record === null || record === void 0 ? void 0 : record.code) === 'email_invalid' || (record === null || record === void 0 ? void 0 : record.code) === 'stripe_email_invalid') {
7
+ return true;
8
+ }
9
+ const message = typeof error === 'string' ? error : record === null || record === void 0 ? void 0 : record.message;
10
+ return typeof message === 'string'
11
+ && /(?:invalid email|valid email address|email (?:address )?is (?:invalid|required))/i.test(message);
12
+ };
13
+ export const normalizeCheckoutEmailResult = (result, submittedEmail, invalidMessage = 'Enter a valid email address.') => {
14
+ if (result === null)
15
+ throw new Error('Unable to save your email. Please try again.');
16
+ const email = typeof result === 'string' ? result.trim() : submittedEmail.trim();
17
+ if (!isValidCheckoutEmail(email))
18
+ throw new Error(invalidMessage);
19
+ return email;
20
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funnelsgrove/payments",
3
- "version": "0.15.6",
3
+ "version": "0.15.8",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/The-Solid-Grove/funnelsgrove.git",
@@ -32,7 +32,7 @@
32
32
  "test:run": "vitest run --passWithNoTests"
33
33
  },
34
34
  "dependencies": {
35
- "@funnelsgrove/analytics": "0.1.103",
35
+ "@funnelsgrove/analytics": "0.1.104",
36
36
  "@funnelsgrove/runtime": "0.14.2",
37
37
  "@solidgate/react-sdk": "1.34.0",
38
38
  "@stripe/react-stripe-js": "^5.6.0",