@tagadapay/plugin-sdk 3.1.12 → 3.1.24

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 (144) hide show
  1. package/build-cdn.js +397 -11
  2. package/dist/data/iso3166.d.ts +23 -33
  3. package/dist/data/iso3166.js +134 -198
  4. package/dist/data/languages.d.ts +5 -64
  5. package/dist/data/languages.js +23 -143
  6. package/dist/external-tracker.js +623 -3426
  7. package/dist/external-tracker.min.js +2 -25
  8. package/dist/external-tracker.min.js.map +4 -4
  9. package/dist/react/config/payment.d.ts +14 -4
  10. package/dist/react/config/payment.js +47 -9
  11. package/dist/react/hooks/useCheckout.d.ts +3 -0
  12. package/dist/react/hooks/useCheckout.js +4 -1
  13. package/dist/react/hooks/useISOData.js +1 -1
  14. package/dist/react/hooks/usePaymentPolling.d.ts +3 -3
  15. package/dist/react/hooks/usePluginConfig.js +9 -10
  16. package/dist/react/providers/TagadaProvider.js +1 -1
  17. package/dist/tagada-react-sdk-minimal.min.js +36 -0
  18. package/dist/tagada-react-sdk-minimal.min.js.map +7 -0
  19. package/dist/tagada-react-sdk.js +37821 -0
  20. package/dist/tagada-react-sdk.min.js +78 -0
  21. package/dist/tagada-react-sdk.min.js.map +7 -0
  22. package/dist/tagada-sdk.js +16044 -0
  23. package/dist/tagada-sdk.min.js +32 -0
  24. package/dist/tagada-sdk.min.js.map +7 -0
  25. package/dist/v2/cdn-react-minimal.d.ts +23 -0
  26. package/dist/v2/cdn-react-minimal.js +26 -0
  27. package/dist/v2/core/client.d.ts +4 -2
  28. package/dist/v2/core/client.js +5 -4
  29. package/dist/v2/core/config/environment.js +2 -1
  30. package/dist/v2/core/errors.d.ts +75 -0
  31. package/dist/v2/core/errors.js +104 -0
  32. package/dist/v2/core/funnelClient.d.ts +100 -10
  33. package/dist/v2/core/funnelClient.js +121 -27
  34. package/dist/v2/core/isoData.d.ts +4 -4
  35. package/dist/v2/core/isoData.js +7 -7
  36. package/dist/v2/core/pixelMapping.d.ts +49 -0
  37. package/dist/v2/core/pixelMapping.js +363 -0
  38. package/dist/v2/core/resources/apiClient.d.ts +2 -0
  39. package/dist/v2/core/resources/apiClient.js +52 -9
  40. package/dist/v2/core/resources/checkout.d.ts +99 -30
  41. package/dist/v2/core/resources/checkout.js +14 -0
  42. package/dist/v2/core/resources/customer.d.ts +20 -19
  43. package/dist/v2/core/resources/expressPaymentMethods.d.ts +1 -0
  44. package/dist/v2/core/resources/funnel.d.ts +17 -17
  45. package/dist/v2/core/resources/payments.d.ts +89 -13
  46. package/dist/v2/core/resources/payments.js +27 -9
  47. package/dist/v2/core/resources/postPurchases.d.ts +17 -0
  48. package/dist/v2/core/resources/postPurchases.js +20 -0
  49. package/dist/v2/core/types.d.ts +50 -12
  50. package/dist/v2/core/types.js +0 -3
  51. package/dist/v2/core/utils/checkout.d.ts +2 -2
  52. package/dist/v2/core/utils/checkout.js +7 -2
  53. package/dist/v2/core/utils/currency.d.ts +14 -0
  54. package/dist/v2/core/utils/currency.js +40 -0
  55. package/dist/v2/core/utils/deviceInfo.d.ts +0 -10
  56. package/dist/v2/core/utils/deviceInfo.js +152 -76
  57. package/dist/v2/core/utils/index.d.ts +1 -0
  58. package/dist/v2/core/utils/index.js +2 -0
  59. package/dist/v2/core/utils/order.d.ts +13 -9
  60. package/dist/v2/core/utils/pluginConfig.d.ts +8 -0
  61. package/dist/v2/core/utils/pluginConfig.js +36 -12
  62. package/dist/v2/index.d.ts +6 -3
  63. package/dist/v2/index.js +4 -2
  64. package/dist/v2/react/components/FunnelScriptInjector.js +166 -77
  65. package/dist/v2/react/components/StripeExpressButton.d.ts +13 -0
  66. package/dist/v2/react/components/StripeExpressButton.js +171 -0
  67. package/dist/v2/react/components/WhopCheckout.d.ts +24 -0
  68. package/dist/v2/react/components/WhopCheckout.js +237 -0
  69. package/dist/v2/react/hooks/__examples__/FunnelContextExample.js +1 -1
  70. package/dist/v2/react/hooks/payment-actions/useAirwallexRadarAction.d.ts +14 -0
  71. package/dist/v2/react/hooks/payment-actions/useAirwallexRadarAction.js +181 -0
  72. package/dist/v2/react/hooks/payment-actions/useErrorAction.d.ts +9 -0
  73. package/dist/v2/react/hooks/payment-actions/useErrorAction.js +21 -0
  74. package/dist/v2/react/hooks/payment-actions/useFinixRadarAction.d.ts +14 -0
  75. package/dist/v2/react/hooks/payment-actions/useFinixRadarAction.js +187 -0
  76. package/dist/v2/react/hooks/payment-actions/useKessPayAction.d.ts +11 -0
  77. package/dist/v2/react/hooks/payment-actions/useKessPayAction.js +91 -0
  78. package/dist/v2/react/hooks/payment-actions/useMasterCardAction.d.ts +24 -0
  79. package/dist/v2/react/hooks/payment-actions/useMasterCardAction.js +221 -0
  80. package/dist/v2/react/hooks/payment-actions/usePaymentActionHandler.d.ts +15 -0
  81. package/dist/v2/react/hooks/payment-actions/usePaymentActionHandler.js +142 -0
  82. package/dist/v2/react/hooks/payment-actions/useProcessorAuthAction.d.ts +3 -0
  83. package/dist/v2/react/hooks/payment-actions/useProcessorAuthAction.js +31 -0
  84. package/dist/v2/react/hooks/payment-actions/useRedirectAction.d.ts +10 -0
  85. package/dist/v2/react/hooks/payment-actions/useRedirectAction.js +35 -0
  86. package/dist/v2/react/hooks/payment-actions/useStripeRadarAction.d.ts +14 -0
  87. package/dist/v2/react/hooks/payment-actions/useStripeRadarAction.js +192 -0
  88. package/dist/v2/react/hooks/payment-actions/useThreedsAuthAction.d.ts +14 -0
  89. package/dist/v2/react/hooks/payment-actions/useThreedsAuthAction.js +81 -0
  90. package/dist/v2/react/hooks/payment-actions/useTrustFlowAction.d.ts +11 -0
  91. package/dist/v2/react/hooks/payment-actions/useTrustFlowAction.js +84 -0
  92. package/dist/v2/react/hooks/payment-processing/usePaymentInstruments.d.ts +14 -0
  93. package/dist/v2/react/hooks/payment-processing/usePaymentInstruments.js +36 -0
  94. package/dist/v2/react/hooks/payment-processing/usePaymentProcessors.d.ts +31 -0
  95. package/dist/v2/react/hooks/payment-processing/usePaymentProcessors.js +212 -0
  96. package/dist/v2/react/hooks/payment-redirect/useAirwallex3dsReturn.d.ts +14 -0
  97. package/dist/v2/react/hooks/payment-redirect/useAirwallex3dsReturn.js +207 -0
  98. package/dist/v2/react/hooks/payment-redirect/useGenericPaymentReturn.d.ts +12 -0
  99. package/dist/v2/react/hooks/payment-redirect/useGenericPaymentReturn.js +101 -0
  100. package/dist/v2/react/hooks/useApplePayCheckout.js +8 -8
  101. package/dist/v2/react/hooks/useCheckoutQuery.d.ts +16 -0
  102. package/dist/v2/react/hooks/useCheckoutQuery.js +63 -10
  103. package/dist/v2/react/hooks/useFunnel.d.ts +15 -4
  104. package/dist/v2/react/hooks/useFunnel.js +8 -4
  105. package/dist/v2/react/hooks/useGeoLocation.d.ts +2 -1
  106. package/dist/v2/react/hooks/useGeoLocation.js +4 -2
  107. package/dist/v2/react/hooks/useGoogleAutocomplete.d.ts +2 -0
  108. package/dist/v2/react/hooks/useGoogleAutocomplete.js +29 -15
  109. package/dist/v2/react/hooks/useISOData.d.ts +2 -5
  110. package/dist/v2/react/hooks/useISOData.js +26 -27
  111. package/dist/v2/react/hooks/usePaymentPolling.d.ts +3 -3
  112. package/dist/v2/react/hooks/usePaymentQuery.d.ts +18 -5
  113. package/dist/v2/react/hooks/usePaymentQuery.js +63 -1015
  114. package/dist/v2/react/hooks/usePaymentRetrieve.d.ts +3 -2
  115. package/dist/v2/react/hooks/usePaymentRetrieve.js +3 -1
  116. package/dist/v2/react/hooks/usePixelTracking.d.ts +5 -48
  117. package/dist/v2/react/hooks/usePixelTracking.js +283 -504
  118. package/dist/v2/react/hooks/usePostPurchasesQuery.js +34 -2
  119. package/dist/v2/react/hooks/useRemappableParams.d.ts +2 -6
  120. package/dist/v2/react/hooks/useRemappableParams.js +23 -23
  121. package/dist/v2/react/hooks/useSetPaymentMethod.d.ts +16 -0
  122. package/dist/v2/react/hooks/useSetPaymentMethod.js +33 -0
  123. package/dist/v2/react/hooks/useShippingRatesQuery.js +13 -5
  124. package/dist/v2/react/hooks/useStepConfig.d.ts +23 -6
  125. package/dist/v2/react/hooks/useStepConfig.js +14 -7
  126. package/dist/v2/react/hooks/useTranslation.js +23 -8
  127. package/dist/v2/react/hooks/useWhopPaymentPolling.d.ts +30 -0
  128. package/dist/v2/react/hooks/useWhopPaymentPolling.js +61 -0
  129. package/dist/v2/react/index.d.ts +15 -1
  130. package/dist/v2/react/index.js +7 -0
  131. package/dist/v2/react/providers/ExpressPaymentMethodsProvider.d.ts +3 -1
  132. package/dist/v2/react/providers/ExpressPaymentMethodsProvider.js +12 -2
  133. package/dist/v2/react/providers/TagadaProvider.js +74 -5
  134. package/dist/v2/standalone/external-tracker.d.ts +52 -46
  135. package/dist/v2/standalone/external-tracker.js +205 -98
  136. package/dist/v2/standalone/index.d.ts +40 -0
  137. package/dist/v2/standalone/index.js +148 -1
  138. package/dist/v2/standalone/payment-service.d.ts +134 -0
  139. package/dist/v2/standalone/payment-service.js +928 -0
  140. package/package.json +6 -4
  141. package/dist/react/utils/__tests__/urlUtils.test.d.ts +0 -1
  142. package/dist/react/utils/__tests__/urlUtils.test.js +0 -189
  143. package/dist/v2/core/__tests__/pathRemapping.test.d.ts +0 -11
  144. package/dist/v2/core/__tests__/pathRemapping.test.js +0 -776
@@ -0,0 +1,928 @@
1
+ /**
2
+ * PaymentService (Standalone / Vanilla JS)
3
+ *
4
+ * Complete standalone equivalent of the React SDK's payment system:
5
+ * - usePaymentQuery (orchestration)
6
+ * - usePaymentPolling (status polling)
7
+ * - usePaymentActionHandler (action routing)
8
+ * - usePaymentProcessors (card, APM, Apple Pay, Google Pay, saved instruments)
9
+ * - usePaymentInstruments (instrument creation)
10
+ * - useThreeds (3DS session + challenge)
11
+ * - useGenericPaymentReturn (generic redirect return)
12
+ * - useAirwallex3dsReturn (Airwallex-specific redirect return)
13
+ * - All action handlers: redirect, threeds_auth, processor_auth, error,
14
+ * kesspay_auth, trustflow_auth, finix_radar, stripe_radar, airwallex radar,
15
+ * mastercard_auth
16
+ *
17
+ * No React. No hooks. No DOM framework dependency.
18
+ */
19
+ import { PaymentsResource, } from '../core/resources/payments';
20
+ import { ThreedsResource } from '../core/resources/threeds';
21
+ import { StoreConfigResource } from '../core/resources/storeConfig';
22
+ import { getAssignedPaymentFlowId } from '../core/funnelClient';
23
+ import { getBasisTheoryApiKey } from '../../react/config/payment';
24
+ // =============================================================================
25
+ // PAYMENT SERVICE
26
+ // =============================================================================
27
+ export class PaymentService {
28
+ constructor(config) {
29
+ this.callbacks = {};
30
+ // BasisTheory (lazy initialized)
31
+ this.basisTheory = null;
32
+ this.btInitPromise = null;
33
+ // BasisTheory 3DS (lazy initialized)
34
+ this.bt3dsClass = null;
35
+ this.bt3dsInitPromise = null;
36
+ // Store config (cached)
37
+ this.storeConfig = null;
38
+ this.storeConfigPromise = null;
39
+ // Polling state
40
+ this.pollTimer = null;
41
+ this.pollAttempts = 0;
42
+ this.isPollingActive = false;
43
+ // Redirect return guard
44
+ this.redirectReturnProcessed = false;
45
+ this.paymentsResource = new PaymentsResource(config.apiClient);
46
+ this.threedsResource = new ThreedsResource(config.apiClient);
47
+ this.storeConfigResource = new StoreConfigResource(config.apiClient);
48
+ this.storeId = config.storeId;
49
+ }
50
+ /** Expose paymentsResource for advanced consumers */
51
+ get payments() {
52
+ return this.paymentsResource;
53
+ }
54
+ // ==========================================================================
55
+ // LIFECYCLE
56
+ // ==========================================================================
57
+ setCallbacks(callbacks) {
58
+ this.callbacks = callbacks;
59
+ }
60
+ /** Pre-warm BasisTheory + store config (non-blocking). */
61
+ warmup() {
62
+ void this.initBasisTheory();
63
+ void this.initBt3ds();
64
+ if (this.storeId)
65
+ void this.fetchStoreConfig();
66
+ }
67
+ destroy() {
68
+ this.stopPolling();
69
+ this.basisTheory = null;
70
+ this.btInitPromise = null;
71
+ this.bt3dsClass = null;
72
+ this.bt3dsInitPromise = null;
73
+ this.storeConfig = null;
74
+ this.storeConfigPromise = null;
75
+ }
76
+ // ==========================================================================
77
+ // BASIS THEORY
78
+ // ==========================================================================
79
+ initBasisTheory() {
80
+ if (this.basisTheory)
81
+ return Promise.resolve(this.basisTheory);
82
+ if (this.btInitPromise)
83
+ return this.btInitPromise;
84
+ this.btInitPromise = (async () => {
85
+ try {
86
+ const apiKey = getBasisTheoryApiKey();
87
+ const { BasisTheory } = await import('@basis-theory/basis-theory-js');
88
+ const bt = await new BasisTheory().init(apiKey, { elements: false });
89
+ this.basisTheory = bt;
90
+ console.log('[PaymentService] BasisTheory initialized');
91
+ return this.basisTheory;
92
+ }
93
+ catch (error) {
94
+ console.error('[PaymentService] BasisTheory init failed:', error);
95
+ return null;
96
+ }
97
+ })();
98
+ return this.btInitPromise;
99
+ }
100
+ getBtApiKey() {
101
+ return getBasisTheoryApiKey();
102
+ }
103
+ /** Lazy-load @basis-theory/web-threeds (BasisTheory3ds class) */
104
+ initBt3ds() {
105
+ if (this.bt3dsClass)
106
+ return Promise.resolve(this.bt3dsClass);
107
+ if (this.bt3dsInitPromise)
108
+ return this.bt3dsInitPromise;
109
+ this.bt3dsInitPromise = (async () => {
110
+ try {
111
+ const { BasisTheory3ds } = await import('@basis-theory/web-threeds');
112
+ this.bt3dsClass = BasisTheory3ds;
113
+ console.log('[PaymentService] BasisTheory 3DS loaded');
114
+ return this.bt3dsClass;
115
+ }
116
+ catch (error) {
117
+ console.error('[PaymentService] BasisTheory 3DS load failed:', error);
118
+ return null;
119
+ }
120
+ })();
121
+ return this.bt3dsInitPromise;
122
+ }
123
+ // ==========================================================================
124
+ // STORE CONFIG
125
+ // ==========================================================================
126
+ fetchStoreConfig() {
127
+ if (this.storeConfig)
128
+ return Promise.resolve(this.storeConfig);
129
+ if (this.storeConfigPromise)
130
+ return this.storeConfigPromise;
131
+ if (!this.storeId)
132
+ return Promise.resolve(null);
133
+ this.storeConfigPromise = (async () => {
134
+ try {
135
+ this.storeConfig = await this.storeConfigResource.getStoreConfig(this.storeId);
136
+ return this.storeConfig;
137
+ }
138
+ catch {
139
+ return null;
140
+ }
141
+ })();
142
+ return this.storeConfigPromise;
143
+ }
144
+ // ==========================================================================
145
+ // POLLING
146
+ // ==========================================================================
147
+ stopPolling() {
148
+ if (this.pollTimer) {
149
+ clearInterval(this.pollTimer);
150
+ this.pollTimer = null;
151
+ }
152
+ this.isPollingActive = false;
153
+ this.pollAttempts = 0;
154
+ }
155
+ startPolling(paymentId, callbacks, maxAttempts = 20, interval = 1500) {
156
+ this.stopPolling();
157
+ this.isPollingActive = true;
158
+ this.pollAttempts = 0;
159
+ console.log('[PaymentService] Starting payment polling:', paymentId);
160
+ const check = async () => {
161
+ if (!this.isPollingActive)
162
+ return;
163
+ this.pollAttempts++;
164
+ try {
165
+ const payment = await this.paymentsResource.getPaymentStatus(paymentId);
166
+ console.log(`[PaymentService] Poll #${this.pollAttempts}: ${payment.status} / ${payment.subStatus}`);
167
+ if (!this.isPollingActive)
168
+ return;
169
+ if (payment.status === 'succeeded' ||
170
+ (payment.status === 'pending' && payment.subStatus === 'authorized')) {
171
+ this.stopPolling();
172
+ callbacks.onSuccess(payment);
173
+ return;
174
+ }
175
+ if (payment.requireAction !== 'none' && payment.requireActionData && !payment.requireActionData.processed) {
176
+ this.stopPolling();
177
+ callbacks.onRequireAction?.(payment);
178
+ return;
179
+ }
180
+ if (payment.status !== 'succeeded' && payment.status !== 'pending') {
181
+ this.stopPolling();
182
+ callbacks.onFailure(payment.status || 'Payment failed');
183
+ return;
184
+ }
185
+ if (this.pollAttempts >= maxAttempts) {
186
+ this.stopPolling();
187
+ callbacks.onFailure('Payment verification timeout');
188
+ }
189
+ }
190
+ catch {
191
+ if (this.pollAttempts >= 3) {
192
+ this.stopPolling();
193
+ callbacks.onFailure('Payment verification failed due to network errors');
194
+ }
195
+ }
196
+ };
197
+ void check();
198
+ this.pollTimer = setInterval(() => void check(), interval);
199
+ }
200
+ // ==========================================================================
201
+ // COMMON: processPaymentDirect + result handling
202
+ // ==========================================================================
203
+ /**
204
+ * Internal: call processPaymentDirect and handle requireAction / polling.
205
+ * Shared by processCardPayment, processApplePayPayment, etc.
206
+ */
207
+ async processAndHandle(checkoutSessionId, paymentInstrumentId, threedsSessionId, extra) {
208
+ const paymentFlowId = getAssignedPaymentFlowId();
209
+ const response = await this.paymentsResource.processPaymentDirect(checkoutSessionId, paymentInstrumentId, threedsSessionId, {
210
+ initiatedBy: extra?.initiatedBy || 'customer',
211
+ source: extra?.source || 'checkout',
212
+ paymentFlowId,
213
+ processorId: extra?.processorId,
214
+ paymentMethod: extra?.paymentMethod,
215
+ });
216
+ console.log('[PaymentService] Payment response:', {
217
+ paymentId: response.payment?.id,
218
+ status: response.payment?.status,
219
+ requireAction: response.payment?.requireAction,
220
+ });
221
+ this.callbacks.onCurrentPaymentId?.(response.payment?.id || null);
222
+ if (response.payment.requireAction !== 'none') {
223
+ await this.handlePaymentAction(response.payment);
224
+ return { success: true, payment: response.payment, order: response.order, redirecting: true };
225
+ }
226
+ if (response.payment.status === 'succeeded') {
227
+ this.callbacks.onProcessing?.(false);
228
+ return { success: true, payment: response.payment, order: response.order };
229
+ }
230
+ return new Promise((resolve) => {
231
+ this.startPolling(response.payment.id, {
232
+ onSuccess: (payment) => {
233
+ this.callbacks.onProcessing?.(false);
234
+ resolve({ success: true, payment, order: response.order });
235
+ },
236
+ onFailure: (error) => {
237
+ this.callbacks.onError?.(error);
238
+ this.callbacks.onProcessing?.(false);
239
+ resolve({ success: false, error });
240
+ },
241
+ onRequireAction: (payment) => {
242
+ void this.handlePaymentAction(payment);
243
+ },
244
+ });
245
+ });
246
+ }
247
+ /**
248
+ * After radar / completePaymentAfterAction, handle the resumed payment.
249
+ */
250
+ async handleResumedPayment(resumedPayment) {
251
+ if (resumedPayment.status === 'declined' || resumedPayment.status === 'failed') {
252
+ const errorMsg = resumedPayment.error?.message
253
+ || resumedPayment.error?.processorMessage
254
+ || 'Payment declined';
255
+ this.callbacks.onError?.(errorMsg);
256
+ this.callbacks.onProcessing?.(false);
257
+ this.callbacks.onFailure?.(errorMsg);
258
+ return;
259
+ }
260
+ if (resumedPayment.status === 'succeeded') {
261
+ this.callbacks.onProcessing?.(false);
262
+ this.callbacks.onSuccess?.(resumedPayment);
263
+ return;
264
+ }
265
+ if (resumedPayment.requireAction !== 'none' && resumedPayment.requireActionData) {
266
+ await this.handlePaymentAction(resumedPayment);
267
+ return;
268
+ }
269
+ // Start polling for final status
270
+ this.startPolling(resumedPayment.id, {
271
+ onSuccess: (p) => {
272
+ this.callbacks.onProcessing?.(false);
273
+ this.callbacks.onSuccess?.(p);
274
+ },
275
+ onFailure: (e) => {
276
+ this.callbacks.onError?.(e);
277
+ this.callbacks.onProcessing?.(false);
278
+ },
279
+ onRequireAction: (p) => { void this.handlePaymentAction(p); },
280
+ });
281
+ }
282
+ // ==========================================================================
283
+ // PAYMENT ACTION HANDLER (mirrors usePaymentActionHandler)
284
+ // ==========================================================================
285
+ async handlePaymentAction(payment) {
286
+ if (payment.requireAction === 'none')
287
+ return;
288
+ if (payment.requireActionData?.processed)
289
+ return;
290
+ const actionData = payment.requireActionData;
291
+ if (!actionData)
292
+ return;
293
+ try {
294
+ await this.paymentsResource.markPaymentActionProcessed(payment.id);
295
+ }
296
+ catch { /* best-effort */ }
297
+ switch (actionData.type) {
298
+ case 'redirect':
299
+ case 'redirect_to_payment':
300
+ case 'processor_auth': {
301
+ const redirectUrl = actionData.metadata?.redirect?.redirectUrl || actionData.redirectUrl || actionData.url;
302
+ if (redirectUrl) {
303
+ console.log('[PaymentService] Redirecting:', redirectUrl);
304
+ window.location.href = redirectUrl;
305
+ }
306
+ else if (payment.status === 'succeeded') {
307
+ this.callbacks.onProcessing?.(false);
308
+ this.callbacks.onSuccess?.(payment);
309
+ }
310
+ break;
311
+ }
312
+ case 'threeds_auth': {
313
+ const session = actionData.metadata?.threedsSession;
314
+ if (session?.acsChallengeUrl) {
315
+ console.log('[PaymentService] 3DS challenge redirect:', session.acsChallengeUrl);
316
+ window.location.href = session.acsChallengeUrl;
317
+ }
318
+ break;
319
+ }
320
+ case 'error': {
321
+ const msg = actionData.message || 'Payment action failed';
322
+ this.callbacks.onError?.(msg);
323
+ this.callbacks.onProcessing?.(false);
324
+ break;
325
+ }
326
+ case 'kesspay_auth':
327
+ this.handleKessPayAuth(actionData);
328
+ break;
329
+ case 'trustflow_auth':
330
+ this.handleTrustFlowAuth(actionData);
331
+ break;
332
+ case 'finix_radar':
333
+ await this.handleFinixRadar(payment, actionData);
334
+ break;
335
+ case 'stripe_radar':
336
+ await this.handleStripeRadar(payment, actionData);
337
+ break;
338
+ case 'radar':
339
+ if (actionData.metadata?.provider === 'airwallex') {
340
+ await this.handleAirwallexRadar(payment, actionData);
341
+ }
342
+ break;
343
+ case 'mastercard_auth':
344
+ await this.handleMasterCardAuth(payment, actionData);
345
+ break;
346
+ default: {
347
+ console.log('[PaymentService] Unhandled action, starting polling:', actionData.type);
348
+ this.startPolling(payment.id, {
349
+ onSuccess: (p) => { this.callbacks.onProcessing?.(false); this.callbacks.onSuccess?.(p); },
350
+ onFailure: (e) => { this.callbacks.onError?.(e); this.callbacks.onProcessing?.(false); },
351
+ onRequireAction: (p) => { void this.handlePaymentAction(p); },
352
+ });
353
+ break;
354
+ }
355
+ }
356
+ }
357
+ // --------------------------------------------------------------------------
358
+ // KessPay Auth
359
+ // --------------------------------------------------------------------------
360
+ handleKessPayAuth(actionData) {
361
+ const threeDSData = actionData?.metadata?.threeds;
362
+ if (!threeDSData?.challengeHtml) {
363
+ this.callbacks.onError?.('Missing KessPay 3DS challenge HTML');
364
+ this.callbacks.onProcessing?.(false);
365
+ return;
366
+ }
367
+ try {
368
+ this.callbacks.onProcessing?.(false);
369
+ const tempDoc = document.implementation.createHTMLDocument('KessPay 3DS');
370
+ tempDoc.body.innerHTML = threeDSData.challengeHtml;
371
+ const form = tempDoc.querySelector('form');
372
+ if (form) {
373
+ const redirectForm = document.createElement('form');
374
+ redirectForm.method = form.method || 'POST';
375
+ redirectForm.action = form.action || '';
376
+ redirectForm.style.display = 'none';
377
+ form.querySelectorAll('input').forEach(input => {
378
+ const newInput = document.createElement('input');
379
+ newInput.type = input.type;
380
+ newInput.name = input.name;
381
+ newInput.value = input.value;
382
+ redirectForm.appendChild(newInput);
383
+ });
384
+ document.body.appendChild(redirectForm);
385
+ redirectForm.submit();
386
+ }
387
+ else {
388
+ document.open();
389
+ document.write(threeDSData.challengeHtml);
390
+ document.close();
391
+ }
392
+ }
393
+ catch (error) {
394
+ this.callbacks.onError?.(error instanceof Error ? error.message : 'KessPay 3DS failed');
395
+ this.callbacks.onProcessing?.(false);
396
+ }
397
+ }
398
+ // --------------------------------------------------------------------------
399
+ // TrustFlow Auth
400
+ // --------------------------------------------------------------------------
401
+ handleTrustFlowAuth(actionData) {
402
+ const authData = actionData?.metadata?.trustflow;
403
+ if (!authData?.appId || !authData?.txnId || !authData?.hash) {
404
+ this.callbacks.onError?.('Missing Trust Flow 3DS data');
405
+ this.callbacks.onProcessing?.(false);
406
+ return;
407
+ }
408
+ try {
409
+ this.callbacks.onProcessing?.(false);
410
+ const form = document.createElement('form');
411
+ form.method = 'POST';
412
+ form.action = authData.captureUrl;
413
+ form.style.display = 'none';
414
+ for (const [name, value] of [['APP_ID', authData.appId], ['TXN_ID', authData.txnId], ['HASH', authData.hash]]) {
415
+ const input = document.createElement('input');
416
+ input.type = 'hidden';
417
+ input.name = name;
418
+ input.value = value;
419
+ form.appendChild(input);
420
+ }
421
+ document.body.appendChild(form);
422
+ form.submit();
423
+ }
424
+ catch (error) {
425
+ this.callbacks.onError?.(error instanceof Error ? error.message : 'Trust Flow 3DS failed');
426
+ this.callbacks.onProcessing?.(false);
427
+ }
428
+ }
429
+ // --------------------------------------------------------------------------
430
+ // Finix Radar
431
+ // --------------------------------------------------------------------------
432
+ async handleFinixRadar(payment, actionData) {
433
+ const radarConfig = actionData.metadata?.radar;
434
+ if (!radarConfig) {
435
+ this.callbacks.onError?.('Finix radar config missing');
436
+ this.callbacks.onProcessing?.(false);
437
+ return;
438
+ }
439
+ try {
440
+ await this.loadScript('https://js.finix.com/v/1/finix.js', () => typeof window.Finix?.Auth === 'function');
441
+ const sessionKey = await new Promise((resolve, reject) => {
442
+ const timeout = setTimeout(() => reject(new Error('Timeout waiting for Finix Auth')), 10000);
443
+ const FinixAuth = window.Finix.Auth(radarConfig.environment, radarConfig.merchantId, () => {
444
+ clearTimeout(timeout);
445
+ const key = FinixAuth.getSessionKey();
446
+ key ? resolve(key) : reject(new Error('No Finix session key'));
447
+ });
448
+ const immediateKey = FinixAuth.getSessionKey();
449
+ if (immediateKey) {
450
+ clearTimeout(timeout);
451
+ resolve(immediateKey);
452
+ }
453
+ });
454
+ await this.paymentsResource.saveRadarSession({
455
+ orderId: radarConfig.orderId,
456
+ finixRadarSessionId: sessionKey,
457
+ finixRadarSessionData: {
458
+ sessionKey,
459
+ merchantId: radarConfig.merchantId,
460
+ environment: radarConfig.environment,
461
+ createdAt: new Date().toISOString(),
462
+ },
463
+ });
464
+ const resumed = await this.paymentsResource.completePaymentAfterAction(payment.id);
465
+ await this.handleResumedPayment(resumed);
466
+ }
467
+ catch (error) {
468
+ this.callbacks.onError?.(error instanceof Error ? error.message : 'Finix radar failed');
469
+ this.callbacks.onProcessing?.(false);
470
+ }
471
+ }
472
+ // --------------------------------------------------------------------------
473
+ // Stripe Radar
474
+ // --------------------------------------------------------------------------
475
+ async handleStripeRadar(payment, actionData) {
476
+ const radarConfig = actionData.metadata?.radar;
477
+ if (!radarConfig?.publishableKey) {
478
+ this.callbacks.onError?.('Stripe radar config missing');
479
+ this.callbacks.onProcessing?.(false);
480
+ return;
481
+ }
482
+ try {
483
+ await this.loadScript('https://js.stripe.com/v3/', () => typeof window.Stripe === 'function');
484
+ const stripe = window.Stripe(radarConfig.publishableKey);
485
+ const result = await stripe.createRadarSession();
486
+ if (result.error)
487
+ throw new Error(result.error.message || 'Failed to create Radar session');
488
+ if (!result.radarSession)
489
+ throw new Error('No radar session returned from Stripe');
490
+ await this.paymentsResource.saveRadarSession({
491
+ orderId: radarConfig.orderId,
492
+ stripeRadarSessionId: result.radarSession.id,
493
+ stripeRadarSessionData: result.radarSession,
494
+ });
495
+ const resumed = await this.paymentsResource.completePaymentAfterAction(payment.id);
496
+ await this.handleResumedPayment(resumed);
497
+ }
498
+ catch (error) {
499
+ this.callbacks.onError?.(error instanceof Error ? error.message : 'Stripe radar failed');
500
+ this.callbacks.onProcessing?.(false);
501
+ }
502
+ }
503
+ // --------------------------------------------------------------------------
504
+ // Airwallex Radar
505
+ // --------------------------------------------------------------------------
506
+ async handleAirwallexRadar(payment, actionData) {
507
+ const isTest = actionData.metadata?.isTest || false;
508
+ const orderId = payment.order?.id;
509
+ const checkoutSessionId = payment.order?.checkoutSessionId;
510
+ if (!orderId || !checkoutSessionId) {
511
+ this.callbacks.onError?.('Missing order info for Airwallex radar');
512
+ this.callbacks.onProcessing?.(false);
513
+ return;
514
+ }
515
+ try {
516
+ const sessionId = crypto.randomUUID();
517
+ const existingScript = document.getElementById('airwallex-fraud-api');
518
+ if (!existingScript) {
519
+ const baseUrl = isTest ? 'https://static-demo.airwallex.com' : 'https://static.airwallex.com';
520
+ const script = document.createElement('script');
521
+ script.type = 'text/javascript';
522
+ script.async = true;
523
+ script.id = 'airwallex-fraud-api';
524
+ script.setAttribute('data-order-session-id', sessionId);
525
+ script.src = `${baseUrl}/webapp/fraud/device-fingerprint/index.js`;
526
+ await new Promise((resolve, reject) => {
527
+ script.onload = () => resolve();
528
+ script.onerror = () => reject(new Error('Failed to load Airwallex fraud script'));
529
+ document.body.appendChild(script);
530
+ });
531
+ }
532
+ else {
533
+ existingScript.setAttribute('data-order-session-id', sessionId);
534
+ }
535
+ await this.paymentsResource.saveRadarSession({
536
+ checkoutSessionId,
537
+ orderId,
538
+ airwallexRadarSessionId: sessionId,
539
+ });
540
+ const resumed = await this.paymentsResource.completePaymentAfterAction(payment.id);
541
+ await this.handleResumedPayment(resumed);
542
+ }
543
+ catch (error) {
544
+ this.callbacks.onError?.(error instanceof Error ? error.message : 'Airwallex radar failed');
545
+ this.callbacks.onProcessing?.(false);
546
+ }
547
+ }
548
+ // --------------------------------------------------------------------------
549
+ // MasterCard Auth (3DS inline challenge)
550
+ // --------------------------------------------------------------------------
551
+ async handleMasterCardAuth(payment, actionData) {
552
+ const threeDSData = actionData?.metadata?.threeds;
553
+ if (!threeDSData?.sessionId || !threeDSData?.merchantId) {
554
+ this.callbacks.onError?.('Missing MasterCard 3DS data');
555
+ this.callbacks.onProcessing?.(false);
556
+ return;
557
+ }
558
+ try {
559
+ this.callbacks.onProcessing?.(false);
560
+ await this.loadScript(threeDSData.scriptUrl, () => !!window.ThreeDS);
561
+ const containerId = 'mastercard-3ds-container';
562
+ let container = document.getElementById(containerId);
563
+ if (!container) {
564
+ container = document.createElement('div');
565
+ container.id = containerId;
566
+ container.style.cssText = 'position:absolute;top:-9999px;left:-9999px;width:1px;height:1px;overflow:hidden';
567
+ document.body.appendChild(container);
568
+ }
569
+ await new Promise((resolve, reject) => {
570
+ window.ThreeDS.configure({
571
+ merchantId: threeDSData.merchantId,
572
+ sessionId: threeDSData.sessionId,
573
+ containerId,
574
+ callback: () => {
575
+ window.ThreeDS.isConfigured() ? resolve() : reject(new Error('ThreeDS configuration failed'));
576
+ },
577
+ configuration: { userLanguage: 'en-US', wsVersion: threeDSData.version ? parseInt(threeDSData.version, 10) : 72 },
578
+ });
579
+ });
580
+ const authResult = await new Promise((resolve) => {
581
+ window.ThreeDS.authenticatePayer(threeDSData.orderId, threeDSData.transactionId, resolve);
582
+ });
583
+ const challengeHtml = authResult?.htmlRedirectCode || authResult?.restApiResponse?.authentication?.redirect?.html;
584
+ if (challengeHtml) {
585
+ // For standalone, redirect via form submission (no modal support without React)
586
+ const tempDoc = document.implementation.createHTMLDocument('MasterCard 3DS');
587
+ tempDoc.body.innerHTML = challengeHtml;
588
+ const form = tempDoc.querySelector('form');
589
+ if (form) {
590
+ const redirectForm = document.createElement('form');
591
+ redirectForm.method = form.method || 'POST';
592
+ redirectForm.action = form.action || '';
593
+ redirectForm.style.display = 'none';
594
+ form.querySelectorAll('input').forEach(input => {
595
+ const newInput = document.createElement('input');
596
+ newInput.type = input.type;
597
+ newInput.name = input.name;
598
+ newInput.value = input.value;
599
+ redirectForm.appendChild(newInput);
600
+ });
601
+ document.body.appendChild(redirectForm);
602
+ redirectForm.submit();
603
+ }
604
+ else {
605
+ document.open();
606
+ document.write(challengeHtml);
607
+ document.close();
608
+ }
609
+ }
610
+ else {
611
+ // Frictionless — complete immediately
612
+ if (threeDSData.paymentId) {
613
+ const resumed = await this.paymentsResource.completePaymentAfterAction(threeDSData.paymentId);
614
+ await this.handleResumedPayment(resumed);
615
+ }
616
+ }
617
+ const cleanup = document.getElementById(containerId);
618
+ if (cleanup)
619
+ cleanup.remove();
620
+ }
621
+ catch (error) {
622
+ this.callbacks.onError?.(error instanceof Error ? error.message : 'MasterCard 3DS failed');
623
+ this.callbacks.onProcessing?.(false);
624
+ }
625
+ }
626
+ // --------------------------------------------------------------------------
627
+ // Script loader utility
628
+ // --------------------------------------------------------------------------
629
+ async loadScript(src, isReady) {
630
+ if (typeof window === 'undefined')
631
+ return;
632
+ if (isReady())
633
+ return;
634
+ const existing = document.querySelector(`script[src="${src}"]`);
635
+ if (existing) {
636
+ await this.waitFor(isReady, 10000);
637
+ return;
638
+ }
639
+ const script = document.createElement('script');
640
+ script.src = src;
641
+ script.async = true;
642
+ await new Promise((resolve, reject) => {
643
+ script.onload = () => resolve();
644
+ script.onerror = () => reject(new Error(`Failed to load script: ${src}`));
645
+ document.head.appendChild(script);
646
+ });
647
+ }
648
+ waitFor(predicate, timeout) {
649
+ return new Promise((resolve, reject) => {
650
+ if (predicate()) {
651
+ resolve();
652
+ return;
653
+ }
654
+ const t = setTimeout(() => reject(new Error('Timeout')), timeout);
655
+ const check = () => {
656
+ if (predicate()) {
657
+ clearTimeout(t);
658
+ resolve();
659
+ }
660
+ else
661
+ setTimeout(check, 100);
662
+ };
663
+ check();
664
+ });
665
+ }
666
+ // ==========================================================================
667
+ // REDIRECT RETURN DETECTION
668
+ // ==========================================================================
669
+ /**
670
+ * Detect ALL redirect return types and resume.
671
+ * Handles both generic returns and Airwallex-specific 3DS returns.
672
+ * Call once during initialization. Returns true if a return was detected.
673
+ */
674
+ detectRedirectReturn() {
675
+ if (typeof window === 'undefined')
676
+ return false;
677
+ if (this.redirectReturnProcessed)
678
+ return false;
679
+ // Try Airwallex 3DS return first
680
+ if (this.detectAirwallex3dsReturn())
681
+ return true;
682
+ // Then generic return
683
+ return this.detectGenericRedirectReturn();
684
+ }
685
+ detectGenericRedirectReturn() {
686
+ const url = new URLSearchParams(window.location.search);
687
+ const paymentAction = url.get('paymentAction');
688
+ const paymentActionStatus = url.get('paymentActionStatus');
689
+ const paymentId = url.get('paymentId');
690
+ const mode = url.get('mode');
691
+ if (mode === 'retrieve')
692
+ return false;
693
+ if (paymentAction !== 'requireAction' || paymentActionStatus !== 'completed' || !paymentId)
694
+ return false;
695
+ console.log('[PaymentService] Generic redirect return detected:', paymentId);
696
+ this.redirectReturnProcessed = true;
697
+ this.callbacks.onProcessing?.(true);
698
+ this.callbacks.onCurrentPaymentId?.(paymentId);
699
+ this.callbacks.onRedirectReturn?.(paymentId);
700
+ this.startPolling(paymentId, {
701
+ onSuccess: (payment) => {
702
+ this.callbacks.onProcessing?.(false);
703
+ this.cleanPaymentUrlParams();
704
+ this.callbacks.onSuccess?.(payment);
705
+ },
706
+ onFailure: (error) => {
707
+ this.callbacks.onError?.(error);
708
+ this.callbacks.onProcessing?.(false);
709
+ this.cleanPaymentUrlParams();
710
+ },
711
+ onRequireAction: (payment) => { void this.handlePaymentAction(payment); },
712
+ });
713
+ return true;
714
+ }
715
+ detectAirwallex3dsReturn() {
716
+ const url = new URLSearchParams(window.location.search);
717
+ const paymentIdFromUrl = url.get('paymentId');
718
+ const paymentIntentId = url.get('payment_intent_id');
719
+ const succeeded = url.get('succeeded');
720
+ const processorType = url.get('processorType');
721
+ const hasAirwallexParams = paymentIntentId || succeeded !== null;
722
+ if (!hasAirwallexParams || processorType !== 'airwallex' || !paymentIdFromUrl)
723
+ return false;
724
+ console.log('[PaymentService] Airwallex 3DS return detected:', paymentIdFromUrl);
725
+ this.redirectReturnProcessed = true;
726
+ this.callbacks.onProcessing?.(true);
727
+ this.callbacks.onCurrentPaymentId?.(paymentIdFromUrl);
728
+ void this.handleAirwallex3dsRedirectReturn(paymentIdFromUrl, paymentIntentId, succeeded);
729
+ return true;
730
+ }
731
+ async handleAirwallex3dsRedirectReturn(paymentId, paymentIntentId, succeeded) {
732
+ const cleanParams = () => {
733
+ const url = new URLSearchParams(window.location.search);
734
+ ['payment_intent_id', 'succeeded', 'processorType', 'paymentId', 'paymentAction', 'paymentActionStatus', 'error_code', 'error_message', 'mode'].forEach(p => url.delete(p));
735
+ const newUrl = url.toString() ? `${window.location.pathname}?${url.toString()}` : window.location.pathname;
736
+ window.history.replaceState({}, document.title, newUrl);
737
+ };
738
+ if (succeeded === 'true') {
739
+ try {
740
+ await this.paymentsResource.updateThreedsStatus({
741
+ paymentId,
742
+ status: 'succeeded',
743
+ paymentIntentId: paymentIntentId || '',
744
+ });
745
+ cleanParams();
746
+ const retrieveResult = await this.paymentsResource.retrievePayment(paymentId);
747
+ const retrieveStatus = retrieveResult?.retrieveResult?.status || retrieveResult?.status;
748
+ if (retrieveResult?.retrieveResult?.success && retrieveStatus === 'succeeded') {
749
+ const payment = await this.paymentsResource.getPaymentStatus(paymentId);
750
+ this.callbacks.onProcessing?.(false);
751
+ this.callbacks.onSuccess?.(payment);
752
+ }
753
+ else if (retrieveStatus === 'declined' || retrieveStatus === 'error') {
754
+ const msg = retrieveResult?.retrieveResult?.message || retrieveResult?.message || 'Payment failed';
755
+ this.callbacks.onError?.(msg);
756
+ this.callbacks.onProcessing?.(false);
757
+ }
758
+ else {
759
+ const payment = await this.paymentsResource.getPaymentStatus(paymentId);
760
+ if (payment.status === 'declined' || payment.status === 'failed') {
761
+ const msg = payment.error?.message || payment.error?.processorMessage || 'Payment declined';
762
+ this.callbacks.onError?.(msg);
763
+ this.callbacks.onProcessing?.(false);
764
+ }
765
+ else if (payment.status === 'succeeded' || (payment.status === 'pending' && payment.subStatus === 'authorized')) {
766
+ this.callbacks.onProcessing?.(false);
767
+ this.callbacks.onSuccess?.(payment);
768
+ }
769
+ else if (payment.requireAction !== 'none' && payment.requireActionData && !payment.requireActionData.processed) {
770
+ void this.handlePaymentAction(payment);
771
+ }
772
+ else {
773
+ this.startPolling(paymentId, {
774
+ onSuccess: (p) => { this.callbacks.onProcessing?.(false); this.callbacks.onSuccess?.(p); },
775
+ onFailure: (e) => { this.callbacks.onError?.(e); this.callbacks.onProcessing?.(false); },
776
+ onRequireAction: (p) => { void this.handlePaymentAction(p); },
777
+ });
778
+ }
779
+ }
780
+ }
781
+ catch (error) {
782
+ this.callbacks.onError?.(error instanceof Error ? error.message : 'Failed to process Airwallex 3DS');
783
+ this.callbacks.onProcessing?.(false);
784
+ }
785
+ }
786
+ else {
787
+ const errorMsg = new URLSearchParams(window.location.search).get('error_message') || 'Authentication failed';
788
+ this.callbacks.onError?.(errorMsg);
789
+ this.callbacks.onProcessing?.(false);
790
+ cleanParams();
791
+ }
792
+ }
793
+ cleanPaymentUrlParams() {
794
+ if (typeof window === 'undefined')
795
+ return;
796
+ const url = new URLSearchParams(window.location.search);
797
+ ['paymentAction', 'paymentActionStatus', 'paymentId', 'payment_intent', 'payment_intent_client_secret', 'source_type', 'redirect_status'].forEach(p => url.delete(p));
798
+ const newUrl = url.toString() ? `${window.location.pathname}?${url.toString()}` : window.location.pathname;
799
+ window.history.replaceState({}, document.title, newUrl);
800
+ }
801
+ // ==========================================================================
802
+ // PAYMENT INSTRUMENT MANAGEMENT
803
+ // ==========================================================================
804
+ async createCardPaymentInstrument(cardData) {
805
+ const bt = await this.initBasisTheory();
806
+ return this.paymentsResource.createCardPaymentInstrument(bt ?? undefined, cardData);
807
+ }
808
+ async createApplePayPaymentInstrument(token) {
809
+ const bt = await this.initBasisTheory();
810
+ return this.paymentsResource.createApplePayPaymentInstrument(bt ?? undefined, token);
811
+ }
812
+ async createGooglePayPaymentInstrument(token) {
813
+ const bt = await this.initBasisTheory();
814
+ return this.paymentsResource.createGooglePayPaymentInstrument(bt ?? undefined, token);
815
+ }
816
+ async getCardPaymentInstruments() {
817
+ return this.paymentsResource.getCardPaymentInstruments();
818
+ }
819
+ // ==========================================================================
820
+ // 3DS SESSION + CHALLENGE (mirrors useThreeds)
821
+ // ==========================================================================
822
+ async createThreedsSession(paymentInstrument) {
823
+ const BasisTheory3ds = await this.initBt3ds();
824
+ if (!BasisTheory3ds)
825
+ throw new Error('BasisTheory 3DS not loaded');
826
+ const bt3ds = BasisTheory3ds(this.getBtApiKey());
827
+ const session = await bt3ds.createSession({ tokenId: paymentInstrument.token });
828
+ return this.threedsResource.createSession({
829
+ provider: 'basis_theory',
830
+ sessionData: session,
831
+ paymentInstrumentId: paymentInstrument.id,
832
+ });
833
+ }
834
+ // ==========================================================================
835
+ // PAYMENT PROCESSING (all methods)
836
+ // ==========================================================================
837
+ async processCardPayment(checkoutSessionId, cardData) {
838
+ this.callbacks.onProcessing?.(true);
839
+ this.callbacks.onError?.(null);
840
+ try {
841
+ const instrument = await this.createCardPaymentInstrument({
842
+ cardNumber: cardData.cardNumber,
843
+ expiryDate: cardData.expiryDate,
844
+ cvc: cardData.cvc,
845
+ });
846
+ if (!instrument?.id)
847
+ throw new Error('Failed to create payment instrument');
848
+ // Auto-detect 3DS from store config
849
+ let threedsSessionId;
850
+ const config = await this.fetchStoreConfig();
851
+ if (config?.computed?.threedsEnabled) {
852
+ try {
853
+ const session = await this.createThreedsSession(instrument);
854
+ threedsSessionId = session.id;
855
+ }
856
+ catch {
857
+ // Continue without 3DS
858
+ }
859
+ }
860
+ return await this.processAndHandle(checkoutSessionId, instrument.id, threedsSessionId);
861
+ }
862
+ catch (error) {
863
+ const msg = error instanceof Error ? error.message : String(error);
864
+ this.callbacks.onError?.(msg);
865
+ this.callbacks.onProcessing?.(false);
866
+ return { success: false, error: msg };
867
+ }
868
+ }
869
+ async processApplePayPayment(checkoutSessionId, applePayToken) {
870
+ this.callbacks.onProcessing?.(true);
871
+ this.callbacks.onError?.(null);
872
+ try {
873
+ const instrument = await this.createApplePayPaymentInstrument(applePayToken);
874
+ return await this.processAndHandle(checkoutSessionId, instrument.id);
875
+ }
876
+ catch (error) {
877
+ const msg = error instanceof Error ? error.message : String(error);
878
+ this.callbacks.onError?.(msg);
879
+ this.callbacks.onProcessing?.(false);
880
+ return { success: false, error: msg };
881
+ }
882
+ }
883
+ async processGooglePayPayment(checkoutSessionId, googlePayToken) {
884
+ this.callbacks.onProcessing?.(true);
885
+ this.callbacks.onError?.(null);
886
+ try {
887
+ const instrument = await this.createGooglePayPaymentInstrument(googlePayToken);
888
+ return await this.processAndHandle(checkoutSessionId, instrument.id);
889
+ }
890
+ catch (error) {
891
+ const msg = error instanceof Error ? error.message : String(error);
892
+ this.callbacks.onError?.(msg);
893
+ this.callbacks.onProcessing?.(false);
894
+ return { success: false, error: msg };
895
+ }
896
+ }
897
+ async processPaymentWithInstrument(checkoutSessionId, paymentInstrumentId) {
898
+ this.callbacks.onProcessing?.(true);
899
+ this.callbacks.onError?.(null);
900
+ try {
901
+ return await this.processAndHandle(checkoutSessionId, paymentInstrumentId);
902
+ }
903
+ catch (error) {
904
+ const msg = error instanceof Error ? error.message : String(error);
905
+ this.callbacks.onError?.(msg);
906
+ this.callbacks.onProcessing?.(false);
907
+ return { success: false, error: msg };
908
+ }
909
+ }
910
+ async processApmPayment(checkoutSessionId, apmData) {
911
+ this.callbacks.onProcessing?.(true);
912
+ this.callbacks.onError?.(null);
913
+ try {
914
+ return await this.processAndHandle(checkoutSessionId, '', undefined, {
915
+ processorId: apmData.processorId,
916
+ paymentMethod: apmData.paymentMethod,
917
+ initiatedBy: apmData.initiatedBy,
918
+ source: apmData.source,
919
+ });
920
+ }
921
+ catch (error) {
922
+ const msg = error instanceof Error ? error.message : String(error);
923
+ this.callbacks.onError?.(msg);
924
+ this.callbacks.onProcessing?.(false);
925
+ return { success: false, error: msg };
926
+ }
927
+ }
928
+ }