@tagadapay/plugin-sdk 3.1.12 โ 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.
- package/build-cdn.js +129 -11
- package/dist/data/iso3166.d.ts +23 -33
- package/dist/data/iso3166.js +134 -198
- package/dist/data/languages.d.ts +5 -64
- package/dist/data/languages.js +23 -143
- package/dist/external-tracker.js +968 -101
- package/dist/external-tracker.min.js +2 -2
- package/dist/external-tracker.min.js.map +4 -4
- package/dist/react/hooks/useISOData.js +1 -1
- package/dist/react/hooks/usePaymentPolling.d.ts +3 -3
- package/dist/tagada-sdk.js +12066 -0
- package/dist/tagada-sdk.min.js +50 -0
- package/dist/tagada-sdk.min.js.map +7 -0
- package/dist/v2/core/client.d.ts +4 -2
- package/dist/v2/core/client.js +4 -3
- package/dist/v2/core/errors.d.ts +75 -0
- package/dist/v2/core/errors.js +104 -0
- package/dist/v2/core/funnelClient.d.ts +2 -0
- package/dist/v2/core/index.d.ts +1 -0
- package/dist/v2/core/index.js +2 -0
- package/dist/v2/core/pixelMapping.d.ts +49 -0
- package/dist/v2/core/pixelMapping.js +325 -0
- package/dist/v2/core/resources/apiClient.d.ts +2 -0
- package/dist/v2/core/resources/apiClient.js +52 -9
- package/dist/v2/core/resources/checkout.d.ts +89 -30
- package/dist/v2/core/resources/checkout.js +8 -0
- package/dist/v2/core/resources/customer.d.ts +20 -19
- package/dist/v2/core/resources/funnel.d.ts +17 -17
- package/dist/v2/core/resources/payments.d.ts +84 -13
- package/dist/v2/core/resources/payments.js +26 -9
- package/dist/v2/core/types.d.ts +50 -12
- package/dist/v2/core/types.js +0 -3
- package/dist/v2/core/utils/checkout.d.ts +2 -2
- package/dist/v2/core/utils/checkout.js +7 -2
- package/dist/v2/core/utils/currency.d.ts +14 -0
- package/dist/v2/core/utils/currency.js +40 -0
- package/dist/v2/core/utils/index.d.ts +1 -0
- package/dist/v2/core/utils/index.js +2 -0
- package/dist/v2/core/utils/order.d.ts +11 -9
- package/dist/v2/core/utils/pluginConfig.d.ts +8 -0
- package/dist/v2/core/utils/pluginConfig.js +28 -0
- package/dist/v2/index.d.ts +3 -1
- package/dist/v2/index.js +1 -1
- package/dist/v2/react/components/FunnelScriptInjector.js +21 -0
- package/dist/v2/react/components/WhopCheckout.d.ts +24 -0
- package/dist/v2/react/components/WhopCheckout.js +231 -0
- package/dist/v2/react/hooks/__examples__/FunnelContextExample.js +1 -1
- package/dist/v2/react/hooks/payment-actions/useAirwallexRadarAction.d.ts +14 -0
- package/dist/v2/react/hooks/payment-actions/useAirwallexRadarAction.js +181 -0
- package/dist/v2/react/hooks/payment-actions/useErrorAction.d.ts +9 -0
- package/dist/v2/react/hooks/payment-actions/useErrorAction.js +21 -0
- package/dist/v2/react/hooks/payment-actions/useFinixRadarAction.d.ts +14 -0
- package/dist/v2/react/hooks/payment-actions/useFinixRadarAction.js +187 -0
- package/dist/v2/react/hooks/payment-actions/useKessPayAction.d.ts +11 -0
- package/dist/v2/react/hooks/payment-actions/useKessPayAction.js +91 -0
- package/dist/v2/react/hooks/payment-actions/useMasterCardAction.d.ts +24 -0
- package/dist/v2/react/hooks/payment-actions/useMasterCardAction.js +221 -0
- package/dist/v2/react/hooks/payment-actions/usePaymentActionHandler.d.ts +15 -0
- package/dist/v2/react/hooks/payment-actions/usePaymentActionHandler.js +142 -0
- package/dist/v2/react/hooks/payment-actions/useProcessorAuthAction.d.ts +3 -0
- package/dist/v2/react/hooks/payment-actions/useProcessorAuthAction.js +13 -0
- package/dist/v2/react/hooks/payment-actions/useRedirectAction.d.ts +10 -0
- package/dist/v2/react/hooks/payment-actions/useRedirectAction.js +35 -0
- package/dist/v2/react/hooks/payment-actions/useStripeRadarAction.d.ts +14 -0
- package/dist/v2/react/hooks/payment-actions/useStripeRadarAction.js +192 -0
- package/dist/v2/react/hooks/payment-actions/useThreedsAuthAction.d.ts +14 -0
- package/dist/v2/react/hooks/payment-actions/useThreedsAuthAction.js +81 -0
- package/dist/v2/react/hooks/payment-actions/useTrustFlowAction.d.ts +11 -0
- package/dist/v2/react/hooks/payment-actions/useTrustFlowAction.js +84 -0
- package/dist/v2/react/hooks/payment-processing/usePaymentInstruments.d.ts +14 -0
- package/dist/v2/react/hooks/payment-processing/usePaymentInstruments.js +36 -0
- package/dist/v2/react/hooks/payment-processing/usePaymentProcessors.d.ts +31 -0
- package/dist/v2/react/hooks/payment-processing/usePaymentProcessors.js +212 -0
- package/dist/v2/react/hooks/payment-redirect/useAirwallex3dsReturn.d.ts +14 -0
- package/dist/v2/react/hooks/payment-redirect/useAirwallex3dsReturn.js +207 -0
- package/dist/v2/react/hooks/payment-redirect/useGenericPaymentReturn.d.ts +12 -0
- package/dist/v2/react/hooks/payment-redirect/useGenericPaymentReturn.js +101 -0
- package/dist/v2/react/hooks/useCheckoutQuery.d.ts +6 -0
- package/dist/v2/react/hooks/useCheckoutQuery.js +45 -0
- package/dist/v2/react/hooks/useGeoLocation.d.ts +2 -1
- package/dist/v2/react/hooks/useGeoLocation.js +4 -2
- package/dist/v2/react/hooks/useISOData.js +1 -1
- package/dist/v2/react/hooks/usePaymentPolling.d.ts +3 -3
- package/dist/v2/react/hooks/usePaymentQuery.d.ts +18 -5
- package/dist/v2/react/hooks/usePaymentQuery.js +63 -1015
- package/dist/v2/react/hooks/usePaymentRetrieve.d.ts +3 -2
- package/dist/v2/react/hooks/usePaymentRetrieve.js +3 -1
- package/dist/v2/react/hooks/usePixelTracking.d.ts +5 -48
- package/dist/v2/react/hooks/usePixelTracking.js +212 -514
- package/dist/v2/react/hooks/useShippingRatesQuery.js +13 -5
- package/dist/v2/react/hooks/useWhopPaymentPolling.d.ts +30 -0
- package/dist/v2/react/hooks/useWhopPaymentPolling.js +61 -0
- package/dist/v2/react/index.d.ts +7 -0
- package/dist/v2/react/index.js +4 -0
- package/dist/v2/react/providers/ExpressPaymentMethodsProvider.d.ts +2 -1
- package/dist/v2/react/providers/ExpressPaymentMethodsProvider.js +3 -1
- package/dist/v2/react/providers/TagadaProvider.js +71 -2
- package/dist/v2/standalone/external-tracker.d.ts +52 -46
- package/dist/v2/standalone/external-tracker.js +205 -98
- package/dist/v2/standalone/index.d.ts +22 -0
- package/dist/v2/standalone/index.js +126 -1
- package/package.json +3 -3
- package/dist/react/utils/__tests__/urlUtils.test.d.ts +0 -1
- package/dist/react/utils/__tests__/urlUtils.test.js +0 -189
- package/dist/v2/core/__tests__/pathRemapping.test.d.ts +0 -11
- package/dist/v2/core/__tests__/pathRemapping.test.js +0 -776
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { CardPaymentMethod, ApplePayToken, GooglePayToken, PaymentOptions, PaymentResponse, PaymentInstrumentResponse } from '../../../core/resources/payments';
|
|
2
|
+
import type { PaymentsResource } from '../../../core/resources/payments';
|
|
3
|
+
import type { UsePaymentOptions } from '../usePaymentQuery';
|
|
4
|
+
interface UsePaymentProcessorsParams {
|
|
5
|
+
paymentsResource: PaymentsResource;
|
|
6
|
+
createCardPaymentInstrument: (cardData: CardPaymentMethod) => Promise<PaymentInstrumentResponse>;
|
|
7
|
+
createApplePayPaymentInstrument: (applePayToken: ApplePayToken) => Promise<PaymentInstrumentResponse>;
|
|
8
|
+
createGooglePayPaymentInstrument: (googlePayToken: GooglePayToken) => Promise<PaymentInstrumentResponse>;
|
|
9
|
+
createSession: any;
|
|
10
|
+
handlePaymentAction: any;
|
|
11
|
+
startPolling: any;
|
|
12
|
+
setIsLoading: (loading: boolean) => void;
|
|
13
|
+
setError: (error: string | null) => void;
|
|
14
|
+
setCurrentPaymentId: (id: string | null) => void;
|
|
15
|
+
hookOptionsRef: React.MutableRefObject<UsePaymentOptions | undefined>;
|
|
16
|
+
storeConfig: any;
|
|
17
|
+
}
|
|
18
|
+
export declare function usePaymentProcessors({ paymentsResource, createCardPaymentInstrument, createApplePayPaymentInstrument, createGooglePayPaymentInstrument, createSession, handlePaymentAction, startPolling, setIsLoading, setError, setCurrentPaymentId, hookOptionsRef, storeConfig, }: UsePaymentProcessorsParams): {
|
|
19
|
+
processCardPayment: (checkoutSessionId: string, cardData: CardPaymentMethod, options?: PaymentOptions) => Promise<PaymentResponse>;
|
|
20
|
+
processApplePayPayment: (checkoutSessionId: string, applePayToken: ApplePayToken, options?: PaymentOptions) => Promise<PaymentResponse>;
|
|
21
|
+
processGooglePayPayment: (checkoutSessionId: string, googlePayToken: GooglePayToken, options?: PaymentOptions) => Promise<PaymentResponse>;
|
|
22
|
+
processPaymentWithInstrument: (checkoutSessionId: string, paymentInstrumentId: string, options?: PaymentOptions) => Promise<PaymentResponse>;
|
|
23
|
+
processApmPayment: (checkoutSessionId: string, options: {
|
|
24
|
+
processorId: string;
|
|
25
|
+
paymentMethod: string;
|
|
26
|
+
initiatedBy?: "customer" | "merchant";
|
|
27
|
+
source?: "upsell" | "checkout" | "offer" | "missing_club" | "forced";
|
|
28
|
+
paymentFlowId?: string;
|
|
29
|
+
} & Pick<PaymentOptions, "onFailure" | "onPaymentFailed" | "onSuccess" | "onPaymentSuccess">) => Promise<PaymentResponse>;
|
|
30
|
+
};
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for payment processing methods
|
|
3
|
+
*/
|
|
4
|
+
import { useCallback } from 'react';
|
|
5
|
+
import { getAssignedPaymentFlowId } from '../../../core/funnelClient';
|
|
6
|
+
export function usePaymentProcessors({ paymentsResource, createCardPaymentInstrument, createApplePayPaymentInstrument, createGooglePayPaymentInstrument, createSession, handlePaymentAction, startPolling, setIsLoading, setError, setCurrentPaymentId, hookOptionsRef, storeConfig, }) {
|
|
7
|
+
// Process payment directly with checkout session
|
|
8
|
+
const processPaymentDirect = useCallback(async (checkoutSessionId, paymentInstrumentId, threedsSessionId, options = {}) => {
|
|
9
|
+
try {
|
|
10
|
+
const paymentFlowId = options.paymentFlowId || getAssignedPaymentFlowId();
|
|
11
|
+
const response = await paymentsResource.processPaymentDirect(checkoutSessionId, paymentInstrumentId, threedsSessionId, {
|
|
12
|
+
initiatedBy: options.initiatedBy,
|
|
13
|
+
source: options.source,
|
|
14
|
+
paymentFlowId,
|
|
15
|
+
processorId: options.processorId,
|
|
16
|
+
paymentMethod: options.paymentMethod,
|
|
17
|
+
});
|
|
18
|
+
setCurrentPaymentId(response.payment?.id);
|
|
19
|
+
if (response.payment.requireAction !== 'none') {
|
|
20
|
+
await handlePaymentAction(response.payment, options);
|
|
21
|
+
}
|
|
22
|
+
else if (response.payment.status === 'succeeded') {
|
|
23
|
+
setIsLoading(false);
|
|
24
|
+
const successResponse = {
|
|
25
|
+
...response,
|
|
26
|
+
order: response.order || response.payment.order,
|
|
27
|
+
};
|
|
28
|
+
if (hookOptionsRef.current?.onPaymentCompleted) {
|
|
29
|
+
await hookOptionsRef.current.onPaymentCompleted(response.payment, {
|
|
30
|
+
isRedirectReturn: false,
|
|
31
|
+
order: successResponse.order,
|
|
32
|
+
checkoutSessionId,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
options.onSuccess?.(successResponse);
|
|
36
|
+
options.onPaymentSuccess?.(successResponse);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
startPolling(response.payment?.id, {
|
|
40
|
+
onRequireAction: (payment) => {
|
|
41
|
+
void handlePaymentAction(payment, options);
|
|
42
|
+
},
|
|
43
|
+
onSuccess: async (payment) => {
|
|
44
|
+
setIsLoading(false);
|
|
45
|
+
const successResponse = {
|
|
46
|
+
paymentId: payment.id,
|
|
47
|
+
payment,
|
|
48
|
+
order: payment.order,
|
|
49
|
+
};
|
|
50
|
+
if (hookOptionsRef.current?.onPaymentCompleted) {
|
|
51
|
+
await hookOptionsRef.current.onPaymentCompleted(payment, {
|
|
52
|
+
isRedirectReturn: false,
|
|
53
|
+
order: successResponse.order,
|
|
54
|
+
checkoutSessionId,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
options.onSuccess?.(successResponse);
|
|
58
|
+
options.onPaymentSuccess?.(successResponse);
|
|
59
|
+
},
|
|
60
|
+
onFailure: async (errorMsg) => {
|
|
61
|
+
setError(errorMsg);
|
|
62
|
+
setIsLoading(false);
|
|
63
|
+
if (hookOptionsRef.current?.onPaymentFailed) {
|
|
64
|
+
await hookOptionsRef.current.onPaymentFailed(errorMsg, {
|
|
65
|
+
isRedirectReturn: false,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
options.onFailure?.(errorMsg);
|
|
69
|
+
options.onPaymentFailed?.({
|
|
70
|
+
code: 'PAYMENT_FAILED',
|
|
71
|
+
message: errorMsg,
|
|
72
|
+
payment: response.payment,
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return response;
|
|
78
|
+
}
|
|
79
|
+
catch (_error) {
|
|
80
|
+
const errorMsg = _error instanceof Error ? _error.message : 'Payment failed';
|
|
81
|
+
setError(errorMsg);
|
|
82
|
+
setIsLoading(false);
|
|
83
|
+
options.onFailure?.(errorMsg);
|
|
84
|
+
options.onPaymentFailed?.({
|
|
85
|
+
code: 'PAYMENT_PROCESSING_ERROR',
|
|
86
|
+
message: errorMsg,
|
|
87
|
+
});
|
|
88
|
+
throw _error;
|
|
89
|
+
}
|
|
90
|
+
}, [paymentsResource, handlePaymentAction, startPolling, setIsLoading, setError, setCurrentPaymentId, hookOptionsRef]);
|
|
91
|
+
// Process APM payment (Alternative Payment Methods)
|
|
92
|
+
const processApmPayment = useCallback(async (checkoutSessionId, options) => {
|
|
93
|
+
setIsLoading(true);
|
|
94
|
+
setError(null);
|
|
95
|
+
try {
|
|
96
|
+
console.log('[processApmPayment] Processing APM payment directly:', options);
|
|
97
|
+
// For APM payments, pass empty paymentInstrumentId and let backend handle it with processorId/paymentMethod
|
|
98
|
+
return await processPaymentDirect(checkoutSessionId, '', undefined, options);
|
|
99
|
+
}
|
|
100
|
+
catch (_error) {
|
|
101
|
+
setIsLoading(false);
|
|
102
|
+
const errorMsg = _error instanceof Error ? _error.message : 'APM payment failed';
|
|
103
|
+
setError(errorMsg);
|
|
104
|
+
options.onFailure?.(errorMsg);
|
|
105
|
+
options.onPaymentFailed?.({
|
|
106
|
+
code: 'APM_PAYMENT_ERROR',
|
|
107
|
+
message: errorMsg,
|
|
108
|
+
});
|
|
109
|
+
throw _error;
|
|
110
|
+
}
|
|
111
|
+
}, [processPaymentDirect, setIsLoading, setError]);
|
|
112
|
+
// Process card payment
|
|
113
|
+
const processCardPayment = useCallback(async (checkoutSessionId, cardData, options = {}) => {
|
|
114
|
+
setIsLoading(true);
|
|
115
|
+
setError(null);
|
|
116
|
+
try {
|
|
117
|
+
// Create payment instrument and handle 3DS for card payments
|
|
118
|
+
const paymentInstrument = await createCardPaymentInstrument(cardData);
|
|
119
|
+
const shouldCreateThreedsSession = storeConfig?.computed?.threedsEnabled;
|
|
120
|
+
let threedsSessionId;
|
|
121
|
+
if (shouldCreateThreedsSession) {
|
|
122
|
+
try {
|
|
123
|
+
const threedsSession = await createSession(paymentInstrument, {
|
|
124
|
+
provider: options.threedsProvider || 'basis_theory',
|
|
125
|
+
});
|
|
126
|
+
threedsSessionId = threedsSession.id;
|
|
127
|
+
}
|
|
128
|
+
catch (_error) {
|
|
129
|
+
// Continue without 3DS session
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return await processPaymentDirect(checkoutSessionId, paymentInstrument.id, threedsSessionId, options);
|
|
133
|
+
}
|
|
134
|
+
catch (_error) {
|
|
135
|
+
setIsLoading(false);
|
|
136
|
+
const errorMsg = _error instanceof Error ? _error.message : 'Payment failed';
|
|
137
|
+
setError(errorMsg);
|
|
138
|
+
options.onFailure?.(errorMsg);
|
|
139
|
+
options.onPaymentFailed?.({
|
|
140
|
+
code: 'CARD_PAYMENT_ERROR',
|
|
141
|
+
message: errorMsg,
|
|
142
|
+
});
|
|
143
|
+
throw _error;
|
|
144
|
+
}
|
|
145
|
+
}, [createCardPaymentInstrument, createSession, processPaymentDirect, storeConfig, setIsLoading, setError]);
|
|
146
|
+
// Process Apple Pay payment
|
|
147
|
+
const processApplePayPayment = useCallback(async (checkoutSessionId, applePayToken, options = {}) => {
|
|
148
|
+
setIsLoading(true);
|
|
149
|
+
setError(null);
|
|
150
|
+
try {
|
|
151
|
+
const paymentInstrument = await createApplePayPaymentInstrument(applePayToken);
|
|
152
|
+
return await processPaymentDirect(checkoutSessionId, paymentInstrument.id, undefined, options);
|
|
153
|
+
}
|
|
154
|
+
catch (_error) {
|
|
155
|
+
setIsLoading(false);
|
|
156
|
+
const errorMsg = _error instanceof Error ? _error.message : 'Apple Pay payment failed';
|
|
157
|
+
setError(errorMsg);
|
|
158
|
+
options.onFailure?.(errorMsg);
|
|
159
|
+
options.onPaymentFailed?.({
|
|
160
|
+
code: 'APPLE_PAY_ERROR',
|
|
161
|
+
message: errorMsg,
|
|
162
|
+
});
|
|
163
|
+
throw _error;
|
|
164
|
+
}
|
|
165
|
+
}, [createApplePayPaymentInstrument, processPaymentDirect, setIsLoading, setError]);
|
|
166
|
+
// Process Google Pay payment
|
|
167
|
+
const processGooglePayPayment = useCallback(async (checkoutSessionId, googlePayToken, options = {}) => {
|
|
168
|
+
setIsLoading(true);
|
|
169
|
+
setError(null);
|
|
170
|
+
try {
|
|
171
|
+
const paymentInstrument = await createGooglePayPaymentInstrument(googlePayToken);
|
|
172
|
+
return await processPaymentDirect(checkoutSessionId, paymentInstrument.id, undefined, options);
|
|
173
|
+
}
|
|
174
|
+
catch (_error) {
|
|
175
|
+
setIsLoading(false);
|
|
176
|
+
const errorMsg = _error instanceof Error ? _error.message : 'Google Pay payment failed';
|
|
177
|
+
setError(errorMsg);
|
|
178
|
+
options.onFailure?.(errorMsg);
|
|
179
|
+
options.onPaymentFailed?.({
|
|
180
|
+
code: 'GOOGLE_PAY_ERROR',
|
|
181
|
+
message: errorMsg,
|
|
182
|
+
});
|
|
183
|
+
throw _error;
|
|
184
|
+
}
|
|
185
|
+
}, [createGooglePayPaymentInstrument, processPaymentDirect, setIsLoading, setError]);
|
|
186
|
+
// Process payment with existing instrument
|
|
187
|
+
const processPaymentWithInstrument = useCallback(async (checkoutSessionId, paymentInstrumentId, options = {}) => {
|
|
188
|
+
setIsLoading(true);
|
|
189
|
+
setError(null);
|
|
190
|
+
try {
|
|
191
|
+
return await processPaymentDirect(checkoutSessionId, paymentInstrumentId, undefined, options);
|
|
192
|
+
}
|
|
193
|
+
catch (_error) {
|
|
194
|
+
setIsLoading(false);
|
|
195
|
+
const errorMsg = _error instanceof Error ? _error.message : 'Payment failed';
|
|
196
|
+
setError(errorMsg);
|
|
197
|
+
options.onFailure?.(errorMsg);
|
|
198
|
+
options.onPaymentFailed?.({
|
|
199
|
+
code: 'PAYMENT_INSTRUMENT_ERROR',
|
|
200
|
+
message: errorMsg,
|
|
201
|
+
});
|
|
202
|
+
throw _error;
|
|
203
|
+
}
|
|
204
|
+
}, [processPaymentDirect, setIsLoading, setError]);
|
|
205
|
+
return {
|
|
206
|
+
processCardPayment,
|
|
207
|
+
processApplePayPayment,
|
|
208
|
+
processGooglePayPayment,
|
|
209
|
+
processPaymentWithInstrument,
|
|
210
|
+
processApmPayment,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PaymentsResource } from '../../../core/resources/payments';
|
|
2
|
+
import type { UsePaymentOptions } from '../usePaymentQuery';
|
|
3
|
+
interface UseAirwallex3dsReturnParams {
|
|
4
|
+
paymentsResource: PaymentsResource;
|
|
5
|
+
startPolling: any;
|
|
6
|
+
handlePaymentAction: any;
|
|
7
|
+
setIsLoading: (loading: boolean) => void;
|
|
8
|
+
setError: (error: string | null) => void;
|
|
9
|
+
setCurrentPaymentId: (id: string | null) => void;
|
|
10
|
+
hookOptionsRef: React.MutableRefObject<UsePaymentOptions | undefined>;
|
|
11
|
+
redirectReturnProcessedRef: React.MutableRefObject<boolean>;
|
|
12
|
+
}
|
|
13
|
+
export declare function useAirwallex3dsReturn({ paymentsResource, startPolling, handlePaymentAction, setIsLoading, setError, setCurrentPaymentId, hookOptionsRef, redirectReturnProcessedRef, }: UseAirwallex3dsReturnParams): void;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for handling Airwallex 3DS redirect returns
|
|
3
|
+
*/
|
|
4
|
+
import { useEffect } from 'react';
|
|
5
|
+
export function useAirwallex3dsReturn({ paymentsResource, startPolling, handlePaymentAction, setIsLoading, setError, setCurrentPaymentId, hookOptionsRef, redirectReturnProcessedRef, }) {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (typeof window === 'undefined')
|
|
8
|
+
return;
|
|
9
|
+
if (redirectReturnProcessedRef.current)
|
|
10
|
+
return;
|
|
11
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
12
|
+
const paymentIdFromUrl = urlParams.get('paymentId');
|
|
13
|
+
const paymentIntentId = urlParams.get('payment_intent_id');
|
|
14
|
+
const succeeded = urlParams.get('succeeded');
|
|
15
|
+
const processorType = urlParams.get('processorType');
|
|
16
|
+
// Check for Airwallex 3DS return
|
|
17
|
+
const hasAirwallexParams = paymentIntentId || succeeded !== null;
|
|
18
|
+
if (!hasAirwallexParams || processorType !== 'airwallex' || !paymentIdFromUrl) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
console.log('โ
[usePayment] Airwallex 3DS return detected!', {
|
|
22
|
+
paymentIntentId,
|
|
23
|
+
succeeded,
|
|
24
|
+
paymentId: paymentIdFromUrl,
|
|
25
|
+
});
|
|
26
|
+
redirectReturnProcessedRef.current = true;
|
|
27
|
+
const handleAirwallex3dsReturn = async () => {
|
|
28
|
+
setIsLoading(true);
|
|
29
|
+
setCurrentPaymentId(paymentIdFromUrl);
|
|
30
|
+
if (succeeded === 'true') {
|
|
31
|
+
try {
|
|
32
|
+
// Update 3DS session status
|
|
33
|
+
await paymentsResource.updateThreedsStatus({
|
|
34
|
+
paymentId: paymentIdFromUrl,
|
|
35
|
+
status: 'succeeded',
|
|
36
|
+
paymentIntentId: paymentIntentId || '',
|
|
37
|
+
});
|
|
38
|
+
console.log('โ
[usePayment] Airwallex 3DS status updated successfully');
|
|
39
|
+
// Clean up URL parameters
|
|
40
|
+
const cleanParams = new URLSearchParams(window.location.search);
|
|
41
|
+
const airwallexParams = ['payment_intent_id', 'succeeded', 'processorType', 'paymentId', 'paymentAction', 'paymentActionStatus', 'error_code', 'error_message', 'mode'];
|
|
42
|
+
airwallexParams.forEach(param => cleanParams.delete(param));
|
|
43
|
+
const newUrl = cleanParams.toString()
|
|
44
|
+
? `${window.location.pathname}?${cleanParams.toString()}`
|
|
45
|
+
: window.location.pathname;
|
|
46
|
+
window.history.replaceState({}, document.title, newUrl);
|
|
47
|
+
// Retrieve payment to trigger server-side check with Airwallex and finalize
|
|
48
|
+
console.log('๐ [usePayment] Retrieving payment to finalize after Airwallex 3DS...');
|
|
49
|
+
const retrieveResult = await paymentsResource.retrievePayment(paymentIdFromUrl);
|
|
50
|
+
console.log('๐ [usePayment] Retrieve result:', retrieveResult);
|
|
51
|
+
const retrieveStatus = retrieveResult?.retrieveResult?.status || retrieveResult?.status;
|
|
52
|
+
if (retrieveResult?.retrieveResult?.success && retrieveStatus === 'succeeded') {
|
|
53
|
+
const payment = await paymentsResource.getPaymentStatus(paymentIdFromUrl);
|
|
54
|
+
console.log('โ
[usePayment] Payment succeeded after Airwallex 3DS!', payment);
|
|
55
|
+
setIsLoading(false);
|
|
56
|
+
if (hookOptionsRef.current?.onPaymentCompleted) {
|
|
57
|
+
try {
|
|
58
|
+
await hookOptionsRef.current.onPaymentCompleted(payment, {
|
|
59
|
+
isRedirectReturn: true,
|
|
60
|
+
order: payment.order,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error('โ [usePayment] Error in onPaymentCompleted callback:', error);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (retrieveStatus === 'declined' || retrieveStatus === 'error') {
|
|
69
|
+
const errorMsg = retrieveResult?.retrieveResult?.message || retrieveResult?.message || 'Payment failed';
|
|
70
|
+
console.error('โ [usePayment] Payment failed after Airwallex 3DS:', errorMsg);
|
|
71
|
+
setError(errorMsg);
|
|
72
|
+
setIsLoading(false);
|
|
73
|
+
if (hookOptionsRef.current?.onPaymentFailed) {
|
|
74
|
+
try {
|
|
75
|
+
await hookOptionsRef.current.onPaymentFailed(errorMsg, {
|
|
76
|
+
isRedirectReturn: true,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.error('โ [usePayment] Error in onPaymentFailed callback:', error);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const payment = await paymentsResource.getPaymentStatus(paymentIdFromUrl);
|
|
86
|
+
console.log('๐ [usePayment] Payment status after retrieve:', payment);
|
|
87
|
+
if (payment.status === 'declined' || payment.status === 'failed') {
|
|
88
|
+
const errorMsg = payment.error?.message || payment.error?.processorMessage || 'Payment declined';
|
|
89
|
+
console.error('โ [usePayment] Payment declined after Airwallex 3DS:', errorMsg);
|
|
90
|
+
setError(errorMsg);
|
|
91
|
+
setIsLoading(false);
|
|
92
|
+
if (hookOptionsRef.current?.onPaymentFailed) {
|
|
93
|
+
try {
|
|
94
|
+
await hookOptionsRef.current.onPaymentFailed(errorMsg, {
|
|
95
|
+
isRedirectReturn: true,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.error('โ [usePayment] Error in onPaymentFailed callback:', error);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else if (payment.requireAction !== 'none' && payment.requireActionData && !payment.requireActionData.processed) {
|
|
104
|
+
console.log('โ ๏ธ [usePayment] Payment requires new action after Airwallex 3DS', payment);
|
|
105
|
+
void handlePaymentAction(payment, {});
|
|
106
|
+
}
|
|
107
|
+
else if (payment.status === 'succeeded' || (payment.status === 'pending' && payment.subStatus === 'authorized')) {
|
|
108
|
+
console.log('โ
[usePayment] Payment succeeded after Airwallex 3DS!', payment);
|
|
109
|
+
setIsLoading(false);
|
|
110
|
+
if (hookOptionsRef.current?.onPaymentCompleted) {
|
|
111
|
+
try {
|
|
112
|
+
await hookOptionsRef.current.onPaymentCompleted(payment, {
|
|
113
|
+
isRedirectReturn: true,
|
|
114
|
+
order: payment.order,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
console.error('โ [usePayment] Error in onPaymentCompleted callback:', error);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
console.log('โณ [usePayment] Payment still pending, starting polling...');
|
|
124
|
+
startPolling(paymentIdFromUrl, {
|
|
125
|
+
onRequireAction: (polledPayment) => {
|
|
126
|
+
console.log('โ ๏ธ [usePayment] Payment requires new action after Airwallex 3DS', polledPayment);
|
|
127
|
+
void handlePaymentAction(polledPayment, {});
|
|
128
|
+
},
|
|
129
|
+
onSuccess: async (polledPayment) => {
|
|
130
|
+
console.log('โ
[usePayment] Payment succeeded after Airwallex 3DS polling!', polledPayment);
|
|
131
|
+
setIsLoading(false);
|
|
132
|
+
if (hookOptionsRef.current?.onPaymentCompleted) {
|
|
133
|
+
try {
|
|
134
|
+
await hookOptionsRef.current.onPaymentCompleted(polledPayment, {
|
|
135
|
+
isRedirectReturn: true,
|
|
136
|
+
order: polledPayment.order,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
console.error('โ [usePayment] Error in onPaymentCompleted callback:', error);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
onFailure: async (errorMsg) => {
|
|
145
|
+
console.error('โ [usePayment] Payment failed after Airwallex 3DS polling:', errorMsg);
|
|
146
|
+
setError(errorMsg);
|
|
147
|
+
setIsLoading(false);
|
|
148
|
+
if (hookOptionsRef.current?.onPaymentFailed) {
|
|
149
|
+
try {
|
|
150
|
+
await hookOptionsRef.current.onPaymentFailed(errorMsg, {
|
|
151
|
+
isRedirectReturn: true,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
console.error('โ [usePayment] Error in onPaymentFailed callback:', error);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
console.error('โ [usePayment] Failed to update Airwallex 3DS status:', error);
|
|
165
|
+
setError('Failed to process 3DS authentication');
|
|
166
|
+
setIsLoading(false);
|
|
167
|
+
if (hookOptionsRef.current?.onPaymentFailed) {
|
|
168
|
+
try {
|
|
169
|
+
await hookOptionsRef.current.onPaymentFailed('Failed to process 3DS authentication', {
|
|
170
|
+
isRedirectReturn: true,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
catch (cbError) {
|
|
174
|
+
console.error('โ [usePayment] Error in onPaymentFailed callback:', cbError);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
// 3DS authentication failed
|
|
181
|
+
console.error('โ [usePayment] Airwallex 3DS authentication failed');
|
|
182
|
+
const errorMsg = urlParams.get('error_message') || 'Authentication failed';
|
|
183
|
+
setError(errorMsg);
|
|
184
|
+
setIsLoading(false);
|
|
185
|
+
// Clean up URL parameters
|
|
186
|
+
const cleanParams = new URLSearchParams(window.location.search);
|
|
187
|
+
const airwallexParams = ['payment_intent_id', 'succeeded', 'processorType', 'paymentId', 'paymentAction', 'paymentActionStatus', 'error_code', 'error_message', 'mode'];
|
|
188
|
+
airwallexParams.forEach(param => cleanParams.delete(param));
|
|
189
|
+
const newUrl = cleanParams.toString()
|
|
190
|
+
? `${window.location.pathname}?${cleanParams.toString()}`
|
|
191
|
+
: window.location.pathname;
|
|
192
|
+
window.history.replaceState({}, document.title, newUrl);
|
|
193
|
+
if (hookOptionsRef.current?.onPaymentFailed) {
|
|
194
|
+
try {
|
|
195
|
+
await hookOptionsRef.current.onPaymentFailed(errorMsg, {
|
|
196
|
+
isRedirectReturn: true,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
console.error('โ [usePayment] Error in onPaymentFailed callback:', error);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
void handleAirwallex3dsReturn();
|
|
206
|
+
}, [paymentsResource, startPolling, handlePaymentAction, setIsLoading, setError, setCurrentPaymentId, hookOptionsRef, redirectReturnProcessedRef]);
|
|
207
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { UsePaymentOptions } from '../usePaymentQuery';
|
|
2
|
+
interface UseGenericPaymentReturnParams {
|
|
3
|
+
startPolling: any;
|
|
4
|
+
handlePaymentAction: any;
|
|
5
|
+
setIsLoading: (loading: boolean) => void;
|
|
6
|
+
setError: (error: string | null) => void;
|
|
7
|
+
setCurrentPaymentId: (id: string | null) => void;
|
|
8
|
+
hookOptionsRef: React.MutableRefObject<UsePaymentOptions | undefined>;
|
|
9
|
+
redirectReturnProcessedRef: React.MutableRefObject<boolean>;
|
|
10
|
+
}
|
|
11
|
+
export declare function useGenericPaymentReturn({ startPolling, handlePaymentAction, setIsLoading, setError, setCurrentPaymentId, hookOptionsRef, redirectReturnProcessedRef, }: UseGenericPaymentReturnParams): void;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for handling generic payment redirect returns
|
|
3
|
+
*/
|
|
4
|
+
import { useEffect } from 'react';
|
|
5
|
+
export function useGenericPaymentReturn({ startPolling, handlePaymentAction, setIsLoading, setError, setCurrentPaymentId, hookOptionsRef, redirectReturnProcessedRef, }) {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (typeof window === 'undefined')
|
|
8
|
+
return;
|
|
9
|
+
if (redirectReturnProcessedRef.current)
|
|
10
|
+
return;
|
|
11
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
12
|
+
const paymentAction = urlParams.get('paymentAction');
|
|
13
|
+
const paymentActionStatus = urlParams.get('paymentActionStatus');
|
|
14
|
+
const paymentIdFromUrl = urlParams.get('paymentId');
|
|
15
|
+
const paymentMode = urlParams.get('mode');
|
|
16
|
+
// Skip if in retrieve mode
|
|
17
|
+
if (paymentMode === 'retrieve') {
|
|
18
|
+
console.log('โญ๏ธ [usePayment] Skipping - retrieve mode detected (handled by usePaymentRetrieve)');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// Check if returning from a payment redirect
|
|
22
|
+
if (paymentAction !== 'requireAction' || paymentActionStatus !== 'completed' || !paymentIdFromUrl) {
|
|
23
|
+
console.log('โญ๏ธ [usePayment] No payment redirect detected - normal page load');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.log('โ
[usePayment] Payment redirect return detected! Starting auto-polling...', {
|
|
27
|
+
paymentId: paymentIdFromUrl,
|
|
28
|
+
});
|
|
29
|
+
redirectReturnProcessedRef.current = true;
|
|
30
|
+
setIsLoading(true);
|
|
31
|
+
setCurrentPaymentId(paymentIdFromUrl);
|
|
32
|
+
// Start polling for the payment status
|
|
33
|
+
startPolling(paymentIdFromUrl, {
|
|
34
|
+
onRequireAction: (payment) => {
|
|
35
|
+
console.log('โ ๏ธ [usePayment] Payment requires new action', payment);
|
|
36
|
+
void handlePaymentAction(payment, {});
|
|
37
|
+
},
|
|
38
|
+
onSuccess: async (payment) => {
|
|
39
|
+
console.log('โ
[usePayment] Payment succeeded after redirect!', {
|
|
40
|
+
paymentId: payment.id,
|
|
41
|
+
status: payment.status,
|
|
42
|
+
hasOrder: !!payment.order,
|
|
43
|
+
});
|
|
44
|
+
setIsLoading(false);
|
|
45
|
+
// Clean up ONLY payment-related query parameters (preserve funnel/checkout params)
|
|
46
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
47
|
+
const paymentParams = ['paymentAction', 'paymentActionStatus', 'paymentId', 'payment_intent', 'payment_intent_client_secret', 'source_type', 'redirect_status'];
|
|
48
|
+
paymentParams.forEach(param => urlParams.delete(param));
|
|
49
|
+
const newUrl = urlParams.toString()
|
|
50
|
+
? `${window.location.pathname}?${urlParams.toString()}`
|
|
51
|
+
: window.location.pathname;
|
|
52
|
+
window.history.replaceState({}, document.title, newUrl);
|
|
53
|
+
console.log('๐งน [usePayment] Payment URL parameters cleaned up (preserved funnel/checkout params)');
|
|
54
|
+
// Call hook-level onPaymentCompleted callback (if provided)
|
|
55
|
+
if (hookOptionsRef.current?.onPaymentCompleted) {
|
|
56
|
+
console.log('๐ [usePayment] Calling onPaymentCompleted callback...', {
|
|
57
|
+
isRedirectReturn: true,
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
await hookOptionsRef.current.onPaymentCompleted(payment, {
|
|
61
|
+
isRedirectReturn: true,
|
|
62
|
+
order: payment.order,
|
|
63
|
+
});
|
|
64
|
+
console.log('โ
[usePayment] onPaymentCompleted callback completed successfully');
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error('โ [usePayment] Error in onPaymentCompleted callback:', error);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
console.warn('โ ๏ธ [usePayment] No onPaymentCompleted callback provided');
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
onFailure: async (errorMsg) => {
|
|
75
|
+
console.error('โ [usePayment] Payment failed after redirect:', errorMsg);
|
|
76
|
+
setError(errorMsg);
|
|
77
|
+
setIsLoading(false);
|
|
78
|
+
// Clean up ONLY payment-related query parameters (preserve funnel/checkout params)
|
|
79
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
80
|
+
const paymentParams = ['paymentAction', 'paymentActionStatus', 'paymentId', 'payment_intent', 'payment_intent_client_secret', 'source_type', 'redirect_status'];
|
|
81
|
+
paymentParams.forEach(param => urlParams.delete(param));
|
|
82
|
+
const newUrl = urlParams.toString()
|
|
83
|
+
? `${window.location.pathname}?${urlParams.toString()}`
|
|
84
|
+
: window.location.pathname;
|
|
85
|
+
window.history.replaceState({}, document.title, newUrl);
|
|
86
|
+
// Call hook-level onPaymentFailed callback (if provided)
|
|
87
|
+
if (hookOptionsRef.current?.onPaymentFailed) {
|
|
88
|
+
console.log('๐ [usePayment] Calling onPaymentFailed callback...');
|
|
89
|
+
try {
|
|
90
|
+
await hookOptionsRef.current.onPaymentFailed(errorMsg, {
|
|
91
|
+
isRedirectReturn: true,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.error('โ [usePayment] Error in onPaymentFailed callback:', error);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
}, [startPolling, handlePaymentAction, setIsLoading, setError, setCurrentPaymentId, hookOptionsRef, redirectReturnProcessedRef]);
|
|
101
|
+
}
|
|
@@ -17,8 +17,14 @@ export interface UseCheckoutQueryResult {
|
|
|
17
17
|
checkoutToken: string;
|
|
18
18
|
}>;
|
|
19
19
|
refresh: () => Promise<void>;
|
|
20
|
+
replaceSessionLineItems: (lineItems: CheckoutLineItem[]) => Promise<any>;
|
|
20
21
|
updateLineItems: (lineItems: CheckoutLineItem[]) => Promise<any>;
|
|
21
22
|
updateLineItemsOptimistic: (lineItems: CheckoutLineItem[]) => void;
|
|
23
|
+
addLineItems: (lineItems: CheckoutLineItem[]) => Promise<any>;
|
|
24
|
+
removeLineItems: (lineItems: {
|
|
25
|
+
variantId: string;
|
|
26
|
+
quantity?: number;
|
|
27
|
+
}[]) => Promise<any>;
|
|
22
28
|
setItemQuantity: (variantId: string, quantity: number, priceId?: string) => Promise<any>;
|
|
23
29
|
updateCustomer: (data: {
|
|
24
30
|
email: string;
|
|
@@ -121,6 +121,20 @@ export function useCheckoutQuery(options = {}) {
|
|
|
121
121
|
},
|
|
122
122
|
});
|
|
123
123
|
// Order bump functionality removed - use useOrderBumpQuery instead
|
|
124
|
+
// Replace session line items mutation (full rewrite)
|
|
125
|
+
const replaceSessionLineItemsMutation = useMutation({
|
|
126
|
+
mutationFn: ({ lineItems }) => {
|
|
127
|
+
if (!checkout?.checkoutSession?.id) {
|
|
128
|
+
throw new Error('No checkout session available');
|
|
129
|
+
}
|
|
130
|
+
return checkoutResource.replaceSessionLineItems(checkout.checkoutSession.id, lineItems);
|
|
131
|
+
},
|
|
132
|
+
onSuccess: () => {
|
|
133
|
+
if (checkoutToken) {
|
|
134
|
+
void queryClient.invalidateQueries({ queryKey: ['checkout', checkoutToken] });
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
});
|
|
124
138
|
// Line items mutation with optimistic updates
|
|
125
139
|
const lineItemsMutation = useMutation({
|
|
126
140
|
mutationFn: ({ lineItems }) => {
|
|
@@ -166,6 +180,34 @@ export function useCheckoutQuery(options = {}) {
|
|
|
166
180
|
}
|
|
167
181
|
},
|
|
168
182
|
});
|
|
183
|
+
// Add line items mutation
|
|
184
|
+
const addLineItemsMutation = useMutation({
|
|
185
|
+
mutationFn: ({ lineItems }) => {
|
|
186
|
+
if (!checkout?.checkoutSession?.id) {
|
|
187
|
+
throw new Error('No checkout session available');
|
|
188
|
+
}
|
|
189
|
+
return checkoutResource.addLineItems(checkout.checkoutSession.id, lineItems);
|
|
190
|
+
},
|
|
191
|
+
onSuccess: () => {
|
|
192
|
+
if (checkoutToken) {
|
|
193
|
+
void queryClient.invalidateQueries({ queryKey: ['checkout', checkoutToken] });
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
// Remove line items mutation
|
|
198
|
+
const removeLineItemsMutation = useMutation({
|
|
199
|
+
mutationFn: ({ lineItems }) => {
|
|
200
|
+
if (!checkout?.checkoutSession?.id) {
|
|
201
|
+
throw new Error('No checkout session available');
|
|
202
|
+
}
|
|
203
|
+
return checkoutResource.removeLineItems(checkout.checkoutSession.id, lineItems);
|
|
204
|
+
},
|
|
205
|
+
onSuccess: () => {
|
|
206
|
+
if (checkoutToken) {
|
|
207
|
+
void queryClient.invalidateQueries({ queryKey: ['checkout', checkoutToken] });
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
});
|
|
169
211
|
// Item quantity mutation
|
|
170
212
|
const quantityMutation = useMutation({
|
|
171
213
|
mutationFn: ({ variantId, quantity, priceId }) => {
|
|
@@ -274,8 +316,11 @@ export function useCheckoutQuery(options = {}) {
|
|
|
274
316
|
},
|
|
275
317
|
refresh,
|
|
276
318
|
// Checkout operations
|
|
319
|
+
replaceSessionLineItems: (lineItems) => replaceSessionLineItemsMutation.mutateAsync({ lineItems }),
|
|
277
320
|
updateLineItems: (lineItems) => lineItemsMutation.mutateAsync({ lineItems }),
|
|
278
321
|
updateLineItemsOptimistic: (lineItems) => lineItemsMutation.mutate({ lineItems }),
|
|
322
|
+
addLineItems: (lineItems) => addLineItemsMutation.mutateAsync({ lineItems }),
|
|
323
|
+
removeLineItems: (lineItems) => removeLineItemsMutation.mutateAsync({ lineItems }),
|
|
279
324
|
setItemQuantity: (variantId, quantity, priceId) => quantityMutation.mutateAsync({ variantId, quantity, priceId }),
|
|
280
325
|
updateCustomer: (data) => customerMutation.mutateAsync(data),
|
|
281
326
|
updateCustomerAndSessionInfo: (data) => customerAndSessionMutation.mutateAsync(data),
|