@tagadapay/plugin-sdk 3.1.11 → 3.1.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.
Files changed (116) hide show
  1. package/README.md +1129 -1129
  2. package/build-cdn.js +231 -228
  3. package/dist/data/iso3166.d.ts +23 -33
  4. package/dist/data/iso3166.js +134 -198
  5. package/dist/data/languages.d.ts +5 -64
  6. package/dist/data/languages.js +23 -143
  7. package/dist/external-tracker.js +968 -102
  8. package/dist/external-tracker.min.js +2 -2
  9. package/dist/external-tracker.min.js.map +4 -4
  10. package/dist/react/hooks/useISOData.js +1 -1
  11. package/dist/react/hooks/usePaymentPolling.d.ts +3 -3
  12. package/dist/react/hooks/useShippingRates.d.ts +6 -0
  13. package/dist/react/hooks/useShippingRates.js +38 -0
  14. package/dist/react/providers/TagadaProvider.js +5 -5
  15. package/dist/react/services/apiService.d.ts +21 -0
  16. package/dist/react/services/apiService.js +10 -0
  17. package/dist/tagada-sdk.js +2079 -179
  18. package/dist/tagada-sdk.min.js +4 -2
  19. package/dist/tagada-sdk.min.js.map +4 -4
  20. package/dist/v2/core/client.d.ts +4 -2
  21. package/dist/v2/core/client.js +4 -3
  22. package/dist/v2/core/errors.d.ts +75 -0
  23. package/dist/v2/core/errors.js +104 -0
  24. package/dist/v2/core/funnelClient.d.ts +16 -15
  25. package/dist/v2/core/funnelClient.js +1 -1
  26. package/dist/v2/core/index.d.ts +1 -0
  27. package/dist/v2/core/index.js +2 -0
  28. package/dist/v2/core/pixelMapping.d.ts +49 -0
  29. package/dist/v2/core/pixelMapping.js +325 -0
  30. package/dist/v2/core/resources/apiClient.d.ts +2 -0
  31. package/dist/v2/core/resources/apiClient.js +52 -9
  32. package/dist/v2/core/resources/checkout.d.ts +89 -30
  33. package/dist/v2/core/resources/checkout.js +8 -0
  34. package/dist/v2/core/resources/customer.d.ts +20 -19
  35. package/dist/v2/core/resources/funnel.d.ts +17 -17
  36. package/dist/v2/core/resources/payments.d.ts +84 -13
  37. package/dist/v2/core/resources/payments.js +26 -9
  38. package/dist/v2/core/resources/shippingRates.d.ts +15 -0
  39. package/dist/v2/core/resources/shippingRates.js +11 -0
  40. package/dist/v2/core/types.d.ts +50 -12
  41. package/dist/v2/core/types.js +0 -3
  42. package/dist/v2/core/utils/checkout.d.ts +2 -2
  43. package/dist/v2/core/utils/checkout.js +7 -2
  44. package/dist/v2/core/utils/order.d.ts +11 -9
  45. package/dist/v2/core/utils/previewModeIndicator.js +101 -101
  46. package/dist/v2/index.d.ts +4 -2
  47. package/dist/v2/index.js +1 -1
  48. package/dist/v2/react/components/ApplePayButton.js +13 -4
  49. package/dist/v2/react/components/FunnelScriptInjector.js +51 -30
  50. package/dist/v2/react/components/WhopCheckout.d.ts +24 -0
  51. package/dist/v2/react/components/WhopCheckout.js +231 -0
  52. package/dist/v2/react/hooks/__examples__/FunnelContextExample.js +1 -1
  53. package/dist/v2/react/hooks/payment-actions/useAirwallexRadarAction.d.ts +14 -0
  54. package/dist/v2/react/hooks/payment-actions/useAirwallexRadarAction.js +181 -0
  55. package/dist/v2/react/hooks/payment-actions/useErrorAction.d.ts +9 -0
  56. package/dist/v2/react/hooks/payment-actions/useErrorAction.js +21 -0
  57. package/dist/v2/react/hooks/payment-actions/useFinixRadarAction.d.ts +14 -0
  58. package/dist/v2/react/hooks/payment-actions/useFinixRadarAction.js +187 -0
  59. package/dist/v2/react/hooks/payment-actions/useKessPayAction.d.ts +11 -0
  60. package/dist/v2/react/hooks/payment-actions/useKessPayAction.js +91 -0
  61. package/dist/v2/react/hooks/payment-actions/useMasterCardAction.d.ts +24 -0
  62. package/dist/v2/react/hooks/payment-actions/useMasterCardAction.js +221 -0
  63. package/dist/v2/react/hooks/payment-actions/usePaymentActionHandler.d.ts +15 -0
  64. package/dist/v2/react/hooks/payment-actions/usePaymentActionHandler.js +142 -0
  65. package/dist/v2/react/hooks/payment-actions/useProcessorAuthAction.d.ts +3 -0
  66. package/dist/v2/react/hooks/payment-actions/useProcessorAuthAction.js +13 -0
  67. package/dist/v2/react/hooks/payment-actions/useRedirectAction.d.ts +10 -0
  68. package/dist/v2/react/hooks/payment-actions/useRedirectAction.js +35 -0
  69. package/dist/v2/react/hooks/payment-actions/useStripeRadarAction.d.ts +14 -0
  70. package/dist/v2/react/hooks/payment-actions/useStripeRadarAction.js +192 -0
  71. package/dist/v2/react/hooks/payment-actions/useThreedsAuthAction.d.ts +14 -0
  72. package/dist/v2/react/hooks/payment-actions/useThreedsAuthAction.js +81 -0
  73. package/dist/v2/react/hooks/payment-actions/useTrustFlowAction.d.ts +11 -0
  74. package/dist/v2/react/hooks/payment-actions/useTrustFlowAction.js +84 -0
  75. package/dist/v2/react/hooks/payment-processing/usePaymentInstruments.d.ts +14 -0
  76. package/dist/v2/react/hooks/payment-processing/usePaymentInstruments.js +36 -0
  77. package/dist/v2/react/hooks/payment-processing/usePaymentProcessors.d.ts +31 -0
  78. package/dist/v2/react/hooks/payment-processing/usePaymentProcessors.js +212 -0
  79. package/dist/v2/react/hooks/payment-redirect/useAirwallex3dsReturn.d.ts +14 -0
  80. package/dist/v2/react/hooks/payment-redirect/useAirwallex3dsReturn.js +207 -0
  81. package/dist/v2/react/hooks/payment-redirect/useGenericPaymentReturn.d.ts +12 -0
  82. package/dist/v2/react/hooks/payment-redirect/useGenericPaymentReturn.js +101 -0
  83. package/dist/v2/react/hooks/useCheckoutQuery.d.ts +6 -0
  84. package/dist/v2/react/hooks/useCheckoutQuery.js +45 -0
  85. package/dist/v2/react/hooks/useFunnel.d.ts +1 -2
  86. package/dist/v2/react/hooks/useGeoLocation.d.ts +2 -1
  87. package/dist/v2/react/hooks/useGeoLocation.js +4 -2
  88. package/dist/v2/react/hooks/useGoogleAutocomplete.js +82 -33
  89. package/dist/v2/react/hooks/useISOData.js +1 -1
  90. package/dist/v2/react/hooks/usePaymentPolling.d.ts +3 -3
  91. package/dist/v2/react/hooks/usePaymentQuery.d.ts +18 -5
  92. package/dist/v2/react/hooks/usePaymentQuery.js +63 -1015
  93. package/dist/v2/react/hooks/usePaymentRetrieve.d.ts +3 -2
  94. package/dist/v2/react/hooks/usePaymentRetrieve.js +3 -1
  95. package/dist/v2/react/hooks/usePixelTracking.d.ts +5 -43
  96. package/dist/v2/react/hooks/usePixelTracking.js +213 -407
  97. package/dist/v2/react/hooks/useShippingRatesQuery.d.ts +6 -0
  98. package/dist/v2/react/hooks/useShippingRatesQuery.js +47 -4
  99. package/dist/v2/react/hooks/useStepConfig.d.ts +2 -8
  100. package/dist/v2/react/hooks/useStepConfig.js +1 -1
  101. package/dist/v2/react/hooks/useWhopPaymentPolling.d.ts +30 -0
  102. package/dist/v2/react/hooks/useWhopPaymentPolling.js +61 -0
  103. package/dist/v2/react/index.d.ts +7 -0
  104. package/dist/v2/react/index.js +4 -0
  105. package/dist/v2/react/providers/ExpressPaymentMethodsProvider.d.ts +2 -1
  106. package/dist/v2/react/providers/ExpressPaymentMethodsProvider.js +3 -1
  107. package/dist/v2/react/providers/TagadaProvider.js +76 -7
  108. package/dist/v2/standalone/external-tracker.d.ts +52 -46
  109. package/dist/v2/standalone/external-tracker.js +205 -98
  110. package/dist/v2/standalone/index.d.ts +22 -0
  111. package/dist/v2/standalone/index.js +125 -0
  112. package/package.json +112 -112
  113. package/dist/react/utils/__tests__/urlUtils.test.d.ts +0 -1
  114. package/dist/react/utils/__tests__/urlUtils.test.js +0 -189
  115. package/dist/v2/core/__tests__/pathRemapping.test.d.ts +0 -11
  116. package/dist/v2/core/__tests__/pathRemapping.test.js +0 -776
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Main payment action handler that routes to specific action handlers
3
+ */
4
+ import { useCallback, useRef } from 'react';
5
+ import { useThreedsAuthAction } from './useThreedsAuthAction';
6
+ import { useProcessorAuthAction } from './useProcessorAuthAction';
7
+ import { useRedirectAction } from './useRedirectAction';
8
+ import { useErrorAction } from './useErrorAction';
9
+ import { useFinixRadarAction } from './useFinixRadarAction';
10
+ import { useAirwallexRadarAction } from './useAirwallexRadarAction';
11
+ import { useStripeRadarAction } from './useStripeRadarAction';
12
+ import { useKessPayAction } from './useKessPayAction';
13
+ import { useTrustFlowAction } from './useTrustFlowAction';
14
+ import { useMasterCardAction } from './useMasterCardAction';
15
+ export function usePaymentActionHandler({ paymentsResource, startChallenge, startPolling, setIsLoading, setError, hookOptionsRef, }) {
16
+ // Track challenge in progress to prevent multiple challenges
17
+ const challengeInProgressRef = useRef(false);
18
+ // Initialize all action handlers
19
+ const { handleThreedsAuth } = useThreedsAuthAction({
20
+ startChallenge,
21
+ startPolling,
22
+ setIsLoading,
23
+ setError,
24
+ hookOptionsRef,
25
+ challengeInProgressRef,
26
+ });
27
+ const { handleProcessorAuth } = useProcessorAuthAction();
28
+ const { handleRedirect } = useRedirectAction({
29
+ setIsLoading,
30
+ hookOptionsRef,
31
+ });
32
+ const { handleError } = useErrorAction({
33
+ setError,
34
+ setIsLoading,
35
+ });
36
+ const { handleFinixRadar } = useFinixRadarAction({
37
+ paymentsResource,
38
+ startPolling,
39
+ setError,
40
+ setIsLoading,
41
+ hookOptionsRef,
42
+ });
43
+ const { handleAirwallexRadar } = useAirwallexRadarAction({
44
+ paymentsResource,
45
+ startPolling,
46
+ setError,
47
+ setIsLoading,
48
+ hookOptionsRef,
49
+ });
50
+ const { handleStripeRadar } = useStripeRadarAction({
51
+ paymentsResource,
52
+ startPolling,
53
+ setError,
54
+ setIsLoading,
55
+ hookOptionsRef,
56
+ });
57
+ const { handleKessPayAuth } = useKessPayAction({
58
+ setError,
59
+ setIsLoading,
60
+ hookOptionsRef,
61
+ });
62
+ const { handleTrustFlowAuth } = useTrustFlowAction({
63
+ setError,
64
+ setIsLoading,
65
+ hookOptionsRef,
66
+ });
67
+ const { handleMasterCardAuth } = useMasterCardAction({
68
+ paymentsResource,
69
+ startPolling,
70
+ setError,
71
+ setIsLoading,
72
+ hookOptionsRef,
73
+ });
74
+ // Main handler that routes to specific action handlers
75
+ const handlePaymentAction = useCallback(async (payment, options = {}) => {
76
+ if (payment.requireAction === 'none')
77
+ return;
78
+ if (payment?.requireActionData?.processed)
79
+ return;
80
+ const actionData = payment.requireActionData;
81
+ if (!actionData)
82
+ return;
83
+ // Mark action as processed
84
+ try {
85
+ await paymentsResource.markPaymentActionProcessed(payment.id);
86
+ }
87
+ catch (_error) {
88
+ // Error handling removed
89
+ }
90
+ // Route to appropriate action handler based on type
91
+ switch (actionData.type) {
92
+ case 'threeds_auth':
93
+ await handleThreedsAuth(payment, actionData, options);
94
+ break;
95
+ case 'processor_auth':
96
+ case 'redirect_to_payment':
97
+ await handleProcessorAuth(actionData);
98
+ break;
99
+ case 'redirect':
100
+ await handleRedirect(payment, actionData, options);
101
+ break;
102
+ case 'error':
103
+ await handleError(payment, actionData, options);
104
+ break;
105
+ case 'finix_radar':
106
+ await handleFinixRadar(payment, actionData, options, handlePaymentAction);
107
+ break;
108
+ case 'stripe_radar':
109
+ await handleStripeRadar(payment, actionData, options, handlePaymentAction);
110
+ break;
111
+ case 'kesspay_auth':
112
+ await handleKessPayAuth(payment, actionData, options);
113
+ break;
114
+ case 'trustflow_auth':
115
+ await handleTrustFlowAuth(payment, actionData, options);
116
+ break;
117
+ case 'mastercard_auth':
118
+ await handleMasterCardAuth(payment, actionData, options, handlePaymentAction);
119
+ break;
120
+ case 'radar':
121
+ // Check provider for specific implementation
122
+ if (actionData.metadata?.provider === 'airwallex') {
123
+ await handleAirwallexRadar(payment, actionData, options, handlePaymentAction);
124
+ }
125
+ break;
126
+ }
127
+ options.onRequireAction?.(payment);
128
+ }, [
129
+ paymentsResource,
130
+ handleThreedsAuth,
131
+ handleProcessorAuth,
132
+ handleRedirect,
133
+ handleError,
134
+ handleFinixRadar,
135
+ handleAirwallexRadar,
136
+ handleStripeRadar,
137
+ handleKessPayAuth,
138
+ handleTrustFlowAuth,
139
+ handleMasterCardAuth,
140
+ ]);
141
+ return { handlePaymentAction };
142
+ }
@@ -0,0 +1,3 @@
1
+ export declare function useProcessorAuthAction(): {
2
+ handleProcessorAuth: (actionData: any) => Promise<void>;
3
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Hook for handling processor-specific authentication redirects
3
+ */
4
+ import { useCallback } from 'react';
5
+ export function useProcessorAuthAction() {
6
+ const handleProcessorAuth = useCallback(async (actionData) => {
7
+ // Always auto-redirect for processor auth (e.g., 3DS, external payment flows)
8
+ if (actionData.metadata?.redirect?.redirectUrl) {
9
+ window.location.href = actionData.metadata.redirect.redirectUrl;
10
+ }
11
+ }, []);
12
+ return { handleProcessorAuth };
13
+ }
@@ -0,0 +1,10 @@
1
+ import type { Payment, PaymentOptions } from '../../../core/resources/payments';
2
+ import type { UsePaymentOptions } from '../usePaymentQuery';
3
+ interface UseRedirectActionParams {
4
+ setIsLoading: (loading: boolean) => void;
5
+ hookOptionsRef: React.MutableRefObject<UsePaymentOptions | undefined>;
6
+ }
7
+ export declare function useRedirectAction({ setIsLoading, hookOptionsRef }: UseRedirectActionParams): {
8
+ handleRedirect: (payment: Payment, actionData: any, options?: PaymentOptions) => Promise<void>;
9
+ };
10
+ export {};
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Hook for handling generic redirect actions
3
+ */
4
+ import { useCallback } from 'react';
5
+ export function useRedirectAction({ setIsLoading, hookOptionsRef }) {
6
+ const handleRedirect = useCallback(async (payment, actionData, options = {}) => {
7
+ // For redirect type, let funnel orchestrator handle navigation via callbacks
8
+ // Only auto-redirect if explicitly enabled (disableAutoRedirect: false)
9
+ const shouldAutoRedirect = options.disableAutoRedirect === false;
10
+ if (shouldAutoRedirect && actionData.metadata?.redirect?.redirectUrl) {
11
+ window.location.href = actionData.metadata.redirect.redirectUrl;
12
+ }
13
+ else if (payment.status === 'succeeded') {
14
+ // Payment succeeded - call success callbacks for funnel navigation
15
+ setIsLoading(false);
16
+ const response = {
17
+ paymentId: payment.id,
18
+ payment,
19
+ order: payment.order,
20
+ };
21
+ // Hook-level callback (universal handler)
22
+ if (hookOptionsRef.current?.onPaymentCompleted) {
23
+ await hookOptionsRef.current.onPaymentCompleted(payment, {
24
+ isRedirectReturn: false,
25
+ order: response.order,
26
+ });
27
+ }
28
+ // Legacy callback (backwards compatibility)
29
+ options.onSuccess?.(response);
30
+ // Funnel-aligned callback (recommended)
31
+ options.onPaymentSuccess?.(response);
32
+ }
33
+ }, [setIsLoading, hookOptionsRef]);
34
+ return { handleRedirect };
35
+ }
@@ -0,0 +1,14 @@
1
+ import type { Payment, PaymentOptions } from '../../../core/resources/payments';
2
+ import type { PaymentsResource } from '../../../core/resources/payments';
3
+ import type { UsePaymentOptions } from '../usePaymentQuery';
4
+ interface UseStripeRadarActionParams {
5
+ paymentsResource: PaymentsResource;
6
+ startPolling: any;
7
+ setError: (error: string | null) => void;
8
+ setIsLoading: (loading: boolean) => void;
9
+ hookOptionsRef: React.MutableRefObject<UsePaymentOptions | undefined>;
10
+ }
11
+ export declare function useStripeRadarAction({ paymentsResource, startPolling, setError, setIsLoading, hookOptionsRef, }: UseStripeRadarActionParams): {
12
+ handleStripeRadar: (payment: Payment, actionData: any, options: PaymentOptions | undefined, handlePaymentAction: any) => Promise<void>;
13
+ };
14
+ export {};
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Hook for handling Stripe Radar fraud detection
3
+ */
4
+ import { useCallback, useRef } from 'react';
5
+ export function useStripeRadarAction({ paymentsResource, startPolling, setError, setIsLoading, hookOptionsRef, }) {
6
+ const scriptLoadingRef = useRef(false);
7
+ const handleStripeRadar = useCallback(async (payment, actionData, options = {}, handlePaymentAction) => {
8
+ const radarConfig = actionData.metadata?.radar;
9
+ if (!radarConfig?.publishableKey) {
10
+ console.error('Stripe radar config missing from payment action');
11
+ setError('Missing Stripe Radar configuration');
12
+ setIsLoading(false);
13
+ options.onFailure?.('Missing Stripe Radar configuration');
14
+ options.onPaymentFailed?.({
15
+ code: 'STRIPE_RADAR_MISSING_CONFIG',
16
+ message: 'Missing Stripe Radar configuration',
17
+ payment,
18
+ });
19
+ return;
20
+ }
21
+ try {
22
+ // Load Stripe if not already loaded
23
+ if (typeof window !== 'undefined' && typeof window.Stripe !== 'function' && !scriptLoadingRef.current) {
24
+ console.log('Loading Stripe script...');
25
+ scriptLoadingRef.current = true;
26
+ // Check if script already exists
27
+ const existingScript = document.querySelector('script[src="https://js.stripe.com/v3/"]');
28
+ if (existingScript) {
29
+ console.log('Stripe script already exists, waiting for load...');
30
+ if (typeof window.Stripe === 'function') {
31
+ console.log('Stripe already loaded');
32
+ }
33
+ else {
34
+ // Wait for existing script to load
35
+ await new Promise((resolve, reject) => {
36
+ const checkStripe = () => {
37
+ if (typeof window.Stripe === 'function') {
38
+ resolve();
39
+ }
40
+ else {
41
+ setTimeout(checkStripe, 100);
42
+ }
43
+ };
44
+ checkStripe();
45
+ setTimeout(() => reject(new Error('Timeout waiting for Stripe')), 10000);
46
+ });
47
+ }
48
+ }
49
+ else {
50
+ const script = document.createElement('script');
51
+ script.src = 'https://js.stripe.com/v3/';
52
+ script.async = true;
53
+ document.head.appendChild(script);
54
+ await new Promise((resolve, reject) => {
55
+ script.onload = () => {
56
+ console.log('Stripe script loaded successfully');
57
+ scriptLoadingRef.current = false;
58
+ resolve();
59
+ };
60
+ script.onerror = () => {
61
+ scriptLoadingRef.current = false;
62
+ reject(new Error('Failed to load Stripe'));
63
+ };
64
+ });
65
+ }
66
+ }
67
+ console.log('Initializing Stripe with public key:', radarConfig.publishableKey);
68
+ const stripe = window.Stripe(radarConfig.publishableKey);
69
+ const result = await stripe.createRadarSession();
70
+ console.log('Stripe Radar result:', result);
71
+ if (result.error) {
72
+ const errorMessage = result.error.message || 'Failed to create Radar session';
73
+ console.error('Stripe Radar error:', errorMessage);
74
+ throw new Error(errorMessage);
75
+ }
76
+ if (!result.radarSession) {
77
+ const errorMessage = 'No radar session returned from Stripe';
78
+ console.error(errorMessage);
79
+ throw new Error(errorMessage);
80
+ }
81
+ console.log('Stripe Radar session created:', result.radarSession);
82
+ // Save radar session to database
83
+ await paymentsResource.saveRadarSession({
84
+ orderId: radarConfig.orderId,
85
+ stripeRadarSessionId: result.radarSession.id,
86
+ stripeRadarSessionData: result.radarSession,
87
+ });
88
+ console.log('Radar session saved to database');
89
+ // Resume payment by calling completePaymentAfterAction
90
+ const resumedPayment = await paymentsResource.completePaymentAfterAction(payment.id);
91
+ console.log('Payment resumed after Stripe radar:', resumedPayment);
92
+ // Handle the resumed payment response
93
+ if (resumedPayment.status === 'declined' || resumedPayment.status === 'failed') {
94
+ // Payment declined or failed - extract error message from response
95
+ const errorMsg = resumedPayment.error?.message
96
+ || resumedPayment.error?.processorMessage
97
+ || 'Payment declined';
98
+ console.error('❌ [usePayment] Payment declined after Stripe radar:', errorMsg);
99
+ setError(errorMsg);
100
+ setIsLoading(false);
101
+ options.onFailure?.(errorMsg);
102
+ options.onPaymentFailed?.({
103
+ code: resumedPayment.error?.code || 'PAYMENT_DECLINED',
104
+ message: errorMsg,
105
+ payment: resumedPayment,
106
+ });
107
+ // Hook-level callback (universal handler)
108
+ if (hookOptionsRef.current?.onPaymentFailed) {
109
+ hookOptionsRef.current.onPaymentFailed(errorMsg, {
110
+ isRedirectReturn: false,
111
+ });
112
+ }
113
+ }
114
+ else if (resumedPayment.status === 'succeeded') {
115
+ // Payment succeeded
116
+ setIsLoading(false);
117
+ const response = {
118
+ paymentId: resumedPayment.id,
119
+ payment: resumedPayment,
120
+ order: resumedPayment.order,
121
+ };
122
+ // Hook-level callback (universal handler)
123
+ if (hookOptionsRef.current?.onPaymentCompleted) {
124
+ await hookOptionsRef.current.onPaymentCompleted(resumedPayment, {
125
+ isRedirectReturn: false,
126
+ order: response.order,
127
+ });
128
+ }
129
+ options.onSuccess?.(response);
130
+ options.onPaymentSuccess?.(response);
131
+ }
132
+ else if (resumedPayment.requireAction !== 'none' && resumedPayment.requireActionData) {
133
+ // Payment requires another action (e.g., 3DS)
134
+ await handlePaymentAction(resumedPayment, options);
135
+ }
136
+ else {
137
+ // Start polling for final status
138
+ startPolling(resumedPayment.id, {
139
+ onRequireAction: (updatedPayment) => {
140
+ void handlePaymentAction(updatedPayment, options);
141
+ },
142
+ onSuccess: async (successPayment) => {
143
+ setIsLoading(false);
144
+ const response = {
145
+ paymentId: successPayment.id,
146
+ payment: successPayment,
147
+ order: successPayment.order,
148
+ };
149
+ // Hook-level callback (universal handler)
150
+ if (hookOptionsRef.current?.onPaymentCompleted) {
151
+ await hookOptionsRef.current.onPaymentCompleted(successPayment, {
152
+ isRedirectReturn: false,
153
+ order: response.order,
154
+ });
155
+ }
156
+ options.onSuccess?.(response);
157
+ options.onPaymentSuccess?.(response);
158
+ },
159
+ onFailure: async (errorMsg) => {
160
+ setError(errorMsg);
161
+ setIsLoading(false);
162
+ // Hook-level callback (universal handler)
163
+ if (hookOptionsRef.current?.onPaymentFailed) {
164
+ await hookOptionsRef.current.onPaymentFailed(errorMsg, {
165
+ isRedirectReturn: false,
166
+ });
167
+ }
168
+ options.onFailure?.(errorMsg);
169
+ options.onPaymentFailed?.({
170
+ code: 'PAYMENT_FAILED',
171
+ message: errorMsg,
172
+ payment,
173
+ });
174
+ },
175
+ });
176
+ }
177
+ }
178
+ catch (radarError) {
179
+ const errorMsg = radarError instanceof Error ? radarError.message : 'Stripe Radar failed';
180
+ console.error('Stripe radar error:', radarError);
181
+ setError(errorMsg);
182
+ setIsLoading(false);
183
+ options.onFailure?.(errorMsg);
184
+ options.onPaymentFailed?.({
185
+ code: 'STRIPE_RADAR_FAILED',
186
+ message: errorMsg,
187
+ payment,
188
+ });
189
+ }
190
+ }, [paymentsResource, startPolling, setError, setIsLoading, hookOptionsRef]);
191
+ return { handleStripeRadar };
192
+ }
@@ -0,0 +1,14 @@
1
+ import type { Payment, PaymentOptions } from '../../../core/resources/payments';
2
+ import type { UsePaymentOptions } from '../usePaymentQuery';
3
+ interface UseThreedsAuthActionParams {
4
+ startChallenge: any;
5
+ startPolling: any;
6
+ setIsLoading: (loading: boolean) => void;
7
+ setError: (error: string | null) => void;
8
+ hookOptionsRef: React.MutableRefObject<UsePaymentOptions | undefined>;
9
+ challengeInProgressRef: React.MutableRefObject<boolean>;
10
+ }
11
+ export declare function useThreedsAuthAction({ startChallenge, startPolling, setIsLoading, setError, hookOptionsRef, challengeInProgressRef, }: UseThreedsAuthActionParams): {
12
+ handleThreedsAuth: (payment: Payment, actionData: any, options?: PaymentOptions) => Promise<void>;
13
+ };
14
+ export {};
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Hook for handling 3DS authentication actions
3
+ */
4
+ import { useCallback } from 'react';
5
+ export function useThreedsAuthAction({ startChallenge, startPolling, setIsLoading, setError, hookOptionsRef, challengeInProgressRef, }) {
6
+ const handleThreedsAuth = useCallback(async (payment, actionData, options = {}) => {
7
+ if (actionData.metadata?.threedsSession && !challengeInProgressRef.current) {
8
+ try {
9
+ challengeInProgressRef.current = true;
10
+ await startChallenge({
11
+ sessionId: actionData.metadata.threedsSession.externalSessionId,
12
+ acsChallengeUrl: actionData.metadata.threedsSession.acsChallengeUrl,
13
+ acsTransactionId: actionData.metadata.threedsSession.acsTransID,
14
+ threeDSVersion: actionData.metadata.threedsSession.messageVersion,
15
+ }, { provider: options.threedsProvider || 'basis_theory' });
16
+ challengeInProgressRef.current = false;
17
+ // Start polling after challenge completion
18
+ if (payment.id) {
19
+ startPolling(payment.id, {
20
+ onRequireAction: (updatedPayment) => {
21
+ // Will be handled by parent
22
+ options.onRequireAction?.(updatedPayment);
23
+ },
24
+ onSuccess: async (successPayment) => {
25
+ setIsLoading(false);
26
+ const response = {
27
+ paymentId: successPayment.id,
28
+ payment: successPayment,
29
+ order: successPayment.order,
30
+ };
31
+ // Hook-level callback (universal handler)
32
+ if (hookOptionsRef.current?.onPaymentCompleted) {
33
+ await hookOptionsRef.current.onPaymentCompleted(successPayment, {
34
+ isRedirectReturn: false,
35
+ order: response.order,
36
+ });
37
+ }
38
+ // Legacy callback (backwards compatibility)
39
+ options.onSuccess?.(response);
40
+ // Funnel-aligned callback (recommended)
41
+ options.onPaymentSuccess?.(response);
42
+ },
43
+ onFailure: async (errorMsg) => {
44
+ setError(errorMsg);
45
+ setIsLoading(false);
46
+ // Hook-level callback (universal handler)
47
+ if (hookOptionsRef.current?.onPaymentFailed) {
48
+ await hookOptionsRef.current.onPaymentFailed(errorMsg, {
49
+ isRedirectReturn: false,
50
+ });
51
+ }
52
+ // Legacy callback (backwards compatibility)
53
+ options.onFailure?.(errorMsg);
54
+ // Funnel-aligned callback (recommended)
55
+ options.onPaymentFailed?.({
56
+ code: 'PAYMENT_FAILED',
57
+ message: errorMsg,
58
+ payment,
59
+ });
60
+ },
61
+ });
62
+ }
63
+ }
64
+ catch (_error) {
65
+ challengeInProgressRef.current = false;
66
+ const errorMsg = _error instanceof Error ? _error.message : 'Failed to start 3DS challenge';
67
+ setError(errorMsg);
68
+ setIsLoading(false);
69
+ // Legacy callback (backwards compatibility)
70
+ options.onFailure?.(errorMsg);
71
+ // Funnel-aligned callback (recommended)
72
+ options.onPaymentFailed?.({
73
+ code: '3DS_CHALLENGE_FAILED',
74
+ message: errorMsg,
75
+ payment,
76
+ });
77
+ }
78
+ }
79
+ }, [startChallenge, startPolling, setIsLoading, setError, hookOptionsRef, challengeInProgressRef]);
80
+ return { handleThreedsAuth };
81
+ }
@@ -0,0 +1,11 @@
1
+ import type { Payment, PaymentOptions } from '../../../core/resources/payments';
2
+ import type { UsePaymentOptions } from '../usePaymentQuery';
3
+ interface UseTrustFlowActionParams {
4
+ setError: (error: string | null) => void;
5
+ setIsLoading: (loading: boolean) => void;
6
+ hookOptionsRef: React.MutableRefObject<UsePaymentOptions | undefined>;
7
+ }
8
+ export declare function useTrustFlowAction({ setError, setIsLoading, hookOptionsRef, }: UseTrustFlowActionParams): {
9
+ handleTrustFlowAuth: (payment: Payment, actionData: any, options?: PaymentOptions) => Promise<void>;
10
+ };
11
+ export {};
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Hook for handling Trust Flow 3DS authentication
3
+ */
4
+ import { useCallback, useRef } from 'react';
5
+ export function useTrustFlowAction({ setError, setIsLoading, hookOptionsRef, }) {
6
+ const challengeInProgressRef = useRef(false);
7
+ const handleTrustFlowAuth = useCallback(async (payment, actionData, options = {}) => {
8
+ if (challengeInProgressRef.current) {
9
+ console.log('Trust Flow 3DS challenge already in progress');
10
+ return;
11
+ }
12
+ const authData = actionData?.metadata?.trustflow;
13
+ if (!authData?.appId || !authData?.txnId || !authData?.hash) {
14
+ const errorMsg = 'Missing Trust Flow 3DS authentication data';
15
+ console.error(errorMsg);
16
+ setError(errorMsg);
17
+ setIsLoading(false);
18
+ options.onFailure?.(errorMsg);
19
+ options.onPaymentFailed?.({
20
+ code: 'TRUSTFLOW_MISSING_DATA',
21
+ message: errorMsg,
22
+ payment,
23
+ });
24
+ return;
25
+ }
26
+ try {
27
+ challengeInProgressRef.current = true;
28
+ setIsLoading(false); // Stop loading before redirect
29
+ console.log('🔐 [Trust Flow] Starting 3DS authentication:', {
30
+ appId: authData.appId,
31
+ txnId: authData.txnId,
32
+ captureUrl: authData.captureUrl,
33
+ testMode: authData.testMode,
34
+ });
35
+ // Create form for Trust Flow 3DS capture request
36
+ const form = document.createElement('form');
37
+ form.method = 'POST';
38
+ form.action = authData.captureUrl;
39
+ form.style.display = 'none';
40
+ // Add required fields for Trust Flow capture
41
+ const appIdInput = document.createElement('input');
42
+ appIdInput.type = 'hidden';
43
+ appIdInput.name = 'APP_ID';
44
+ appIdInput.value = authData.appId;
45
+ form.appendChild(appIdInput);
46
+ const txnIdInput = document.createElement('input');
47
+ txnIdInput.type = 'hidden';
48
+ txnIdInput.name = 'TXN_ID';
49
+ txnIdInput.value = authData.txnId;
50
+ form.appendChild(txnIdInput);
51
+ const hashInput = document.createElement('input');
52
+ hashInput.type = 'hidden';
53
+ hashInput.name = 'HASH';
54
+ hashInput.value = authData.hash;
55
+ form.appendChild(hashInput);
56
+ // Add form to document and submit
57
+ document.body.appendChild(form);
58
+ form.submit();
59
+ console.log('🔐 [Trust Flow] Redirecting to 3DS challenge...');
60
+ // Note: Success callback will be triggered after redirect return
61
+ // Payment status will be updated via webhook
62
+ }
63
+ catch (error) {
64
+ challengeInProgressRef.current = false;
65
+ const errorMsg = error instanceof Error ? error.message : 'Failed to process Trust Flow 3DS authentication';
66
+ console.error('🔐 [Trust Flow] 3DS authentication error:', error);
67
+ setError(errorMsg);
68
+ setIsLoading(false);
69
+ options.onFailure?.(errorMsg);
70
+ options.onPaymentFailed?.({
71
+ code: 'TRUSTFLOW_AUTH_FAILED',
72
+ message: errorMsg,
73
+ payment,
74
+ });
75
+ // Hook-level callback (universal handler)
76
+ if (hookOptionsRef.current?.onPaymentFailed) {
77
+ hookOptionsRef.current.onPaymentFailed(errorMsg, {
78
+ isRedirectReturn: false,
79
+ });
80
+ }
81
+ }
82
+ }, [setError, setIsLoading, hookOptionsRef]);
83
+ return { handleTrustFlowAuth };
84
+ }
@@ -0,0 +1,14 @@
1
+ import type { CardPaymentMethod, ApplePayToken, GooglePayToken, BasisTheoryInstance, PaymentInstrumentResponse, PaymentInstrumentCustomerResponse } from '../../../core/resources/payments';
2
+ import type { PaymentsResource } from '../../../core/resources/payments';
3
+ interface UsePaymentInstrumentsParams {
4
+ basisTheory: BasisTheoryInstance | undefined;
5
+ paymentsResource: PaymentsResource;
6
+ setError: (error: string | null) => void;
7
+ }
8
+ export declare function usePaymentInstruments({ basisTheory, paymentsResource, setError, }: UsePaymentInstrumentsParams): {
9
+ createCardPaymentInstrument: (cardData: CardPaymentMethod) => Promise<PaymentInstrumentResponse>;
10
+ createApplePayPaymentInstrument: (applePayToken: ApplePayToken) => Promise<PaymentInstrumentResponse>;
11
+ createGooglePayPaymentInstrument: (googlePayToken: GooglePayToken) => Promise<PaymentInstrumentResponse>;
12
+ getCardPaymentInstruments: () => Promise<PaymentInstrumentCustomerResponse>;
13
+ };
14
+ export {};
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Hook for managing payment instruments
3
+ */
4
+ import { useCallback } from 'react';
5
+ export function usePaymentInstruments({ basisTheory, paymentsResource, setError, }) {
6
+ // Create card payment instrument
7
+ const createCardPaymentInstrument = useCallback((cardData) => {
8
+ return paymentsResource.createCardPaymentInstrument(basisTheory, cardData);
9
+ }, [basisTheory, paymentsResource]);
10
+ // Create Apple Pay payment instrument
11
+ const createApplePayPaymentInstrument = useCallback((applePayToken) => {
12
+ return paymentsResource.createApplePayPaymentInstrument(basisTheory, applePayToken);
13
+ }, [basisTheory, paymentsResource]);
14
+ // Create Google Pay payment instrument
15
+ const createGooglePayPaymentInstrument = useCallback((googlePayToken) => {
16
+ return paymentsResource.createGooglePayPaymentInstrument(basisTheory, googlePayToken);
17
+ }, [basisTheory, paymentsResource]);
18
+ // Get card payment instruments
19
+ const getCardPaymentInstruments = useCallback(async () => {
20
+ try {
21
+ const response = await paymentsResource.getCardPaymentInstruments();
22
+ return response;
23
+ }
24
+ catch (error) {
25
+ const errorMsg = error instanceof Error ? error.message : 'Failed to fetch payment instruments';
26
+ setError(errorMsg);
27
+ throw error;
28
+ }
29
+ }, [paymentsResource, setError]);
30
+ return {
31
+ createCardPaymentInstrument,
32
+ createApplePayPaymentInstrument,
33
+ createGooglePayPaymentInstrument,
34
+ getCardPaymentInstruments,
35
+ };
36
+ }