@tonder.io/ionic-lite-sdk 0.0.36-beta.1 → 0.0.38-beta.1

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 (79) hide show
  1. package/README.md +427 -116
  2. package/dist/classes/BaseInlineCheckout.d.ts +47 -0
  3. package/dist/classes/liteCheckout.d.ts +25 -29
  4. package/dist/data/businessApi.d.ts +2 -0
  5. package/dist/data/cardApi.d.ts +4 -0
  6. package/dist/data/checkoutApi.d.ts +5 -0
  7. package/dist/data/customerApi.d.ts +2 -0
  8. package/dist/data/openPayApi.d.ts +1 -0
  9. package/dist/data/paymentMethodApi.d.ts +5 -0
  10. package/dist/data/skyflowApi.d.ts +1 -0
  11. package/dist/helpers/skyflow.d.ts +3 -0
  12. package/dist/helpers/utils.d.ts +8 -4
  13. package/dist/helpers/validations.d.ts +6 -0
  14. package/dist/index.d.ts +3 -1
  15. package/dist/index.js +1 -1
  16. package/dist/shared/catalog/paymentMethodsCatalog.d.ts +1 -0
  17. package/dist/shared/constants/messages.d.ts +11 -0
  18. package/dist/shared/constants/paymentMethodAPM.d.ts +62 -0
  19. package/dist/shared/constants/tonderUrl.d.ts +7 -0
  20. package/dist/types/card.d.ts +30 -0
  21. package/dist/types/checkout.d.ts +109 -0
  22. package/dist/types/commons.d.ts +42 -0
  23. package/dist/types/customer.d.ts +22 -0
  24. package/dist/types/liteInlineCheckout.d.ts +151 -0
  25. package/dist/types/paymentMethod.d.ts +22 -0
  26. package/dist/types/requests.d.ts +12 -3
  27. package/dist/types/transaction.d.ts +101 -0
  28. package/package.json +4 -1
  29. package/src/classes/BaseInlineCheckout.ts +387 -0
  30. package/src/classes/errorResponse.ts +1 -1
  31. package/src/classes/liteCheckout.ts +372 -356
  32. package/src/data/businessApi.ts +18 -0
  33. package/src/data/cardApi.ts +87 -0
  34. package/src/data/checkoutApi.ts +84 -0
  35. package/src/data/customerApi.ts +31 -0
  36. package/src/data/openPayApi.ts +12 -0
  37. package/src/data/paymentMethodApi.ts +37 -0
  38. package/src/data/skyflowApi.ts +20 -0
  39. package/src/helpers/mercadopago.ts +14 -14
  40. package/src/helpers/skyflow.ts +91 -0
  41. package/src/helpers/utils.ts +66 -266
  42. package/src/helpers/validations.ts +55 -0
  43. package/src/index.ts +9 -1
  44. package/src/shared/catalog/paymentMethodsCatalog.ts +248 -0
  45. package/src/shared/constants/messages.ts +11 -0
  46. package/src/shared/constants/paymentMethodAPM.ts +63 -0
  47. package/src/shared/constants/tonderUrl.ts +8 -0
  48. package/src/types/card.ts +35 -0
  49. package/src/types/checkout.ts +124 -0
  50. package/src/types/commons.ts +114 -67
  51. package/src/types/customer.ts +22 -0
  52. package/src/types/liteInlineCheckout.ts +216 -0
  53. package/src/types/paymentMethod.ts +24 -0
  54. package/src/types/requests.ts +12 -3
  55. package/src/types/transaction.ts +101 -0
  56. package/src/types/validations.d.ts +11 -0
  57. package/tests/classes/liteCheckout.test.ts +5 -5
  58. package/tests/methods/createOrder.test.ts +3 -4
  59. package/tests/methods/createPayment.test.ts +2 -3
  60. package/tests/methods/customerRegister.test.ts +3 -4
  61. package/tests/methods/getBusiness.test.ts +4 -5
  62. package/tests/methods/getCustomerCards.test.ts +6 -13
  63. package/tests/methods/registerCustomerCard.test.ts +2 -2
  64. package/tests/methods/startCheckoutRouter.test.ts +2 -2
  65. package/tests/methods/startCheckoutRouterFull.test.ts +2 -2
  66. package/tests/utils/defaultMock.ts +3 -2
  67. package/tests/utils/mockClasses.ts +7 -4
  68. package/types/classes/liteCheckout.d.ts +29 -0
  69. package/types/classes/liteCheckout.js +225 -0
  70. package/types/classes/liteCheckout.js.map +1 -0
  71. package/types/helpers/utils.d.ts +3 -0
  72. package/types/helpers/utils.js +27 -0
  73. package/types/helpers/utils.js.map +1 -0
  74. package/types/index.d.ts +2 -0
  75. package/types/index.js +6 -0
  76. package/types/index.js.map +1 -0
  77. package/tests/methods/getOpenpayDeviceSessionID.test.ts +0 -95
  78. package/tests/methods/getSkyflowToken.test.ts +0 -155
  79. package/tests/methods/getVaultToken.test.ts +0 -107
@@ -1,17 +1,40 @@
1
- import {injectMercadoPagoSecurity} from "../helpers/mercadopago";
1
+ import { fetchBusiness } from "../data/businessApi";
2
2
 
3
3
  declare const MP_DEVICE_SESSION_ID: string | undefined;
4
-
5
- import Skyflow from "skyflow-js";
6
- import CollectContainer from "skyflow-js/types/core/external/collect/collect-container";
7
- import CollectElement from "skyflow-js/types/core/external/collect/collect-element";
8
- import { APM, Business, TonderAPM } from "../types/commons";
9
- import { CreateOrderRequest, CreatePaymentRequest, RegisterCustomerCardRequest, StartCheckoutRequest, TokensRequest, StartCheckoutFullRequest, StartCheckoutIdRequest } from "../types/requests";
10
- import { GetSecureTokenResponse, GetBusinessResponse, CustomerRegisterResponse, CreateOrderResponse, CreatePaymentResponse, StartCheckoutResponse, GetVaultTokenResponse, IErrorResponse, GetCustomerCardsResponse, RegisterCustomerCardResponse } from "../types/responses";
11
4
  import { ErrorResponse } from "./errorResponse";
12
- import { buildErrorResponse, buildErrorResponseFromCatch, getBrowserInfo, getPaymentMethodDetails, getBusinessId } from "../helpers/utils";
13
- import { ThreeDSHandler } from "./3dsHandler";
5
+ import {
6
+ buildErrorResponse,
7
+ buildErrorResponseFromCatch,
8
+ getBrowserInfo,
9
+ getBusinessId,
10
+ formatPublicErrorResponse,
11
+ getCardType,
12
+ } from "../helpers/utils";
14
13
  import { getCustomerAPMs } from "../data/api";
14
+ import { BaseInlineCheckout } from "./BaseInlineCheckout";
15
+ import { MESSAGES } from "../shared/constants/messages";
16
+ import { getSkyflowTokens } from "../helpers/skyflow";
17
+ import { startCheckoutRouter } from "../data/checkoutApi";
18
+ import { getOpenpayDeviceSessionID } from "../data/openPayApi";
19
+ import { getPaymentMethodDetails } from "../shared/catalog/paymentMethodsCatalog";
20
+ import {APM, IInlineLiteCheckoutOptions, TonderAPM} from "../types/commons";
21
+ import {ICustomerCardsResponse, ISaveCardRequest, ISaveCardResponse, ISaveCardSkyflowRequest} from "../types/card";
22
+ import {IPaymentMethod} from "../types/paymentMethod";
23
+ import {
24
+ CreateOrderResponse,
25
+ CreatePaymentResponse,
26
+ CustomerRegisterResponse,
27
+ GetBusinessResponse, IErrorResponse, RegisterCustomerCardResponse, StartCheckoutResponse, GetSecureTokenResponse
28
+ } from "../types/responses";
29
+ import {
30
+ CreateOrderRequest,
31
+ CreatePaymentRequest, RegisterCustomerCardRequest, StartCheckoutFullRequest,
32
+ StartCheckoutIdRequest,
33
+ StartCheckoutRequest,
34
+ TokensRequest
35
+ } from "../types/requests";
36
+ import {ICardFields, IStartCheckoutResponse} from "../types/checkout";
37
+ import {ILiteCheckout} from "../types/liteInlineCheckout";
15
38
 
16
39
  declare global {
17
40
  interface Window {
@@ -19,256 +42,341 @@ declare global {
19
42
  }
20
43
  }
21
44
 
22
- export type LiteCheckoutConstructor = {
23
- signal: AbortSignal;
24
- baseUrlTonder: string;
25
- publicApiKeyTonder: string;
26
- };
27
-
28
- export class LiteCheckout implements LiteCheckoutConstructor {
29
- signal: AbortSignal;
30
- baseUrlTonder: string;
31
- publicApiKeyTonder: string;
32
- process3ds: ThreeDSHandler;
33
- activeAPMs: APM[] = []
34
- merchantData?: Business | ErrorResponse;
35
-
36
- constructor({
37
- signal,
38
- baseUrlTonder,
39
- publicApiKeyTonder,
40
- }: LiteCheckoutConstructor) {
41
- this.baseUrlTonder = baseUrlTonder;
42
- this.signal = signal;
43
- this.publicApiKeyTonder = publicApiKeyTonder;
44
- this.process3ds = new ThreeDSHandler({
45
- apiKey: this.publicApiKeyTonder,
46
- baseUrl: this.baseUrlTonder,
47
- })
48
- this.#init()
45
+ export class LiteCheckout extends BaseInlineCheckout implements ILiteCheckout{
46
+ activeAPMs: APM[] = [];
47
+
48
+ constructor({ apiKey, mode, returnUrl, callBack, apiKeyTonder, baseUrlTonder }: IInlineLiteCheckoutOptions) {
49
+ super({ mode, apiKey, returnUrl, callBack, apiKeyTonder, baseUrlTonder });
49
50
  }
50
51
 
51
- async #init(){
52
- this.getActiveAPMs()
53
- const { mercado_pago } = await this.#fetchMerchantData() as Business
54
- if (!!mercado_pago && mercado_pago.active){
55
- injectMercadoPagoSecurity()
56
- }
52
+ public async injectCheckout() {
53
+ await this._initializeCheckout();
57
54
  }
58
55
 
59
- async getOpenpayDeviceSessionID(
60
- merchant_id: string,
61
- public_key: string,
62
- is_sandbox: boolean
63
- ): Promise<string | ErrorResponse> {
56
+ public async getCustomerCards(): Promise<ICustomerCardsResponse> {
64
57
  try {
65
- let openpay = await window.OpenPay;
66
- openpay.setId(merchant_id);
67
- openpay.setApiKey(public_key);
68
- openpay.setSandboxMode(is_sandbox);
69
- return await openpay.deviceData.setup({
70
- signal: this.signal,
71
- }) as string;
72
- } catch (e) {
73
- throw buildErrorResponseFromCatch(e);
58
+ await this._fetchMerchantData();
59
+ const { auth_token } = await this._getCustomer();
60
+ const response = await this._getCustomerCards(
61
+ auth_token,
62
+ this.merchantData!.business.pk,
63
+ );
64
+
65
+ return {
66
+ ...response,
67
+ cards: response.cards.map((ic) => ({
68
+ ...ic,
69
+ icon: getCardType(ic.fields.card_scheme),
70
+ })),
71
+ };
72
+ } catch (error) {
73
+ throw formatPublicErrorResponse(
74
+ {
75
+ message: MESSAGES.getCardsError,
76
+ },
77
+ error,
78
+ );
74
79
  }
75
80
  }
76
- async #fetchMerchantData() {
81
+
82
+ public async saveCustomerCard(
83
+ secureToken: string,
84
+ card: ISaveCardRequest,
85
+ ): Promise<ISaveCardResponse> {
77
86
  try {
78
- if (!this.merchantData){
79
- this.merchantData = await this.getBusiness();
80
- }
81
- return this.merchantData
82
- }catch(e){
83
- return this.merchantData
87
+ await this._fetchMerchantData();
88
+ const { auth_token } = await this._getCustomer();
89
+ const { vault_id, vault_url, business } = this.merchantData!;
90
+
91
+ const skyflowTokens: ISaveCardSkyflowRequest = await getSkyflowTokens({
92
+ vault_id: vault_id,
93
+ vault_url: vault_url,
94
+ data: card,
95
+ baseUrl: this.baseUrl,
96
+ apiKey: this.apiKeyTonder,
97
+ });
98
+
99
+ return await this._saveCustomerCard(
100
+ secureToken,
101
+ auth_token,
102
+ business?.pk,
103
+ skyflowTokens,
104
+ );
105
+ } catch (error) {
106
+ throw formatPublicErrorResponse(
107
+ {
108
+ message: MESSAGES.saveCardError,
109
+ },
110
+ error,
111
+ );
84
112
  }
85
113
  }
86
114
 
87
- async getBusiness(): Promise<GetBusinessResponse | ErrorResponse> {
115
+ public async removeCustomerCard(skyflowId: string): Promise<string> {
88
116
  try {
89
- const getBusiness = await fetch(
90
- `${this.baseUrlTonder}/api/v1/payments/business/${this.publicApiKeyTonder}`,
117
+ await this._fetchMerchantData();
118
+ const { auth_token } = await this._getCustomer();
119
+ const { business } = this.merchantData!;
120
+
121
+ return await this._removeCustomerCard(
122
+ auth_token,
123
+ business?.pk,
124
+ skyflowId,
125
+ );
126
+ } catch (error) {
127
+ throw formatPublicErrorResponse(
91
128
  {
92
- headers: {
93
- Authorization: `Token ${this.publicApiKeyTonder}`,
94
- },
95
- signal: this.signal,
96
- }
129
+ message: MESSAGES.removeCardError,
130
+ },
131
+ error,
97
132
  );
133
+ }
134
+ }
98
135
 
99
- if (getBusiness.ok) return (await getBusiness.json()) as Business;
136
+ public async getCustomerPaymentMethods(): Promise<IPaymentMethod[]> {
137
+ try {
138
+ const response = await this._fetchCustomerPaymentMethods();
100
139
 
101
- throw await buildErrorResponse(getBusiness);
102
- } catch (e) {
103
- throw buildErrorResponseFromCatch(e);
140
+ const apms_results =
141
+ response && "results" in response && response["results"].length > 0
142
+ ? response["results"]
143
+ : [];
144
+
145
+ return apms_results
146
+ .filter((apmItem) => apmItem.category.toLowerCase() !== "cards")
147
+ .map((apmItem) => {
148
+ const apm = {
149
+ id: apmItem.pk,
150
+ payment_method: apmItem.payment_method,
151
+ priority: apmItem.priority,
152
+ category: apmItem.category,
153
+ ...getPaymentMethodDetails(apmItem.payment_method),
154
+ };
155
+ return apm;
156
+ })
157
+ .sort((a, b) => a.priority - b.priority);
158
+ } catch (error) {
159
+ throw formatPublicErrorResponse(
160
+ {
161
+ message: MESSAGES.getPaymentMethodsError,
162
+ },
163
+ error,
164
+ );
104
165
  }
105
166
  }
106
167
 
107
- async verify3dsTransaction () {
108
- const result3ds = await this.process3ds.verifyTransactionStatus()
109
- const resultCheckout = await this.resumeCheckout(result3ds)
110
- this.process3ds.setPayload(resultCheckout)
111
- return this.handle3dsRedirect(resultCheckout)
168
+ public async getBusiness(): Promise<GetBusinessResponse> {
169
+ try {
170
+ return await fetchBusiness(
171
+ this.baseUrl,
172
+ this.apiKeyTonder,
173
+ this.abortController.signal,
174
+ );
175
+ } catch (e) {
176
+ throw formatPublicErrorResponse(
177
+ {
178
+ message: MESSAGES.getBusinessError,
179
+ },
180
+ e,
181
+ );
182
+ }
112
183
  }
113
184
 
114
- async resumeCheckout(response: any) {
115
- // Stop the routing process if the transaction is either hard declined or successful
116
- if (response?.decline?.error_type === "Hard") {
117
- return response
185
+ // TODO: DEPRECATED
186
+ async getOpenpayDeviceSessionID(
187
+ merchant_id: string,
188
+ public_key: string,
189
+ is_sandbox: boolean,
190
+ ): Promise<string | ErrorResponse> {
191
+ try {
192
+ return await getOpenpayDeviceSessionID(
193
+ merchant_id,
194
+ public_key,
195
+ is_sandbox,
196
+ );
197
+ } catch (e) {
198
+ throw buildErrorResponseFromCatch(e);
118
199
  }
200
+ }
119
201
 
120
- if (["Success", "Authorized"].includes(response?.transaction_status)) {
121
- return response;
122
- }
202
+ // TODO: DEPRECATED
203
+ async getSkyflowTokens({
204
+ vault_id,
205
+ vault_url,
206
+ data,
207
+ }: TokensRequest): Promise<any | ErrorResponse> {
208
+ return await getSkyflowTokens({
209
+ vault_id: vault_id,
210
+ vault_url: vault_url,
211
+ data,
212
+ baseUrl: this.baseUrl,
213
+ apiKey: this.apiKeyTonder,
214
+ });
215
+ }
123
216
 
124
- if (response) {
125
- const routerItems = {
126
- checkout_id: response?.checkout?.id,
127
- };
128
- try {
129
- const routerResponse = await this.handleCheckoutRouter(
130
- routerItems
131
- );
132
- return routerResponse
133
- }catch (error){
134
- // throw error
135
- }
136
- return response
137
- }
217
+ _setCartTotal(total: string) {
218
+ this.cartTotal = total;
138
219
  }
139
220
 
140
- async handle3dsRedirect(response: ErrorResponse | StartCheckoutResponse | false | undefined) {
141
- const iframe = response && 'next_action' in response ? response?.next_action?.iframe_resources?.iframe:null
142
- if (iframe) {
143
- this.process3ds.loadIframe()!.then(() => {
144
- //TODO: Check if this will be necessary on the frontend side
145
- // after some the tests in production, since the 3DS process
146
- // doesn't works properly on the sandbox environment
147
- // setTimeout(() => {
148
- // process3ds.verifyTransactionStatus();
149
- // }, 10000);
150
- this.process3ds.verifyTransactionStatus();
151
- }).catch((error: any) => {
152
- console.log('Error loading iframe:', error)
153
- })
154
- } else {
155
- const redirectUrl = this.process3ds.getRedirectUrl()
156
- if (redirectUrl) {
157
- this.process3ds.redirectToChallenge()
221
+ async _checkout({
222
+ card,
223
+ payment_method,
224
+ isSandbox,
225
+ // TODO: DEPRECATED
226
+ returnUrl: returnUrlData
227
+ }: {
228
+ card?: ICardFields | string;
229
+ payment_method?: string;
230
+ isSandbox?: boolean;
231
+ returnUrl?: string;
232
+ }) {
233
+ await this._fetchMerchantData();
234
+ const customer = await this._getCustomer(this.abortController.signal);
235
+ const { vault_id, vault_url } = this.merchantData!;
236
+ let skyflowTokens;
237
+ if (!payment_method || payment_method !== "" || payment_method === null) {
238
+ if (typeof card === "string") {
239
+ skyflowTokens = {
240
+ skyflow_id: card,
241
+ };
158
242
  } else {
159
- return response;
243
+ skyflowTokens = await getSkyflowTokens({
244
+ vault_id: vault_id,
245
+ vault_url: vault_url,
246
+ data: { ...card, card_number: card!.card_number.replace(/\s+/g, "") },
247
+ baseUrl: this.baseUrl,
248
+ apiKey: this.apiKeyTonder,
249
+ });
160
250
  }
161
251
  }
252
+
253
+ return await this._handleCheckout({
254
+ card: skyflowTokens,
255
+ payment_method,
256
+ customer,
257
+ isSandbox,
258
+ returnUrl: returnUrlData
259
+ });
162
260
  }
163
-
164
- async customerRegister(email: string): Promise<CustomerRegisterResponse | ErrorResponse> {
261
+
262
+ // TODO: DEPRECATED
263
+ async customerRegister(
264
+ email: string,
265
+ ): Promise<CustomerRegisterResponse | ErrorResponse> {
165
266
  try {
166
- const url = `${this.baseUrlTonder}/api/v1/customer/`;
267
+ const url = `${this.baseUrl}/api/v1/customer/`;
167
268
  const data = { email: email };
168
269
  const response = await fetch(url, {
169
270
  method: "POST",
170
271
  headers: {
171
272
  "Content-Type": "application/json",
172
- Authorization: `Token ${this.publicApiKeyTonder}`,
273
+ Authorization: `Token ${this.apiKeyTonder}`,
173
274
  },
174
- signal: this.signal,
275
+ signal: this.abortController.signal,
175
276
  body: JSON.stringify(data),
176
277
  });
177
278
 
178
- if (response.ok) return await response.json() as CustomerRegisterResponse;
279
+ if (response.ok)
280
+ return (await response.json()) as CustomerRegisterResponse;
179
281
  throw await buildErrorResponse(response);
180
282
  } catch (e) {
181
283
  throw buildErrorResponseFromCatch(e);
182
284
  }
183
285
  }
184
286
 
185
- async createOrder(orderItems: CreateOrderRequest): Promise<CreateOrderResponse | ErrorResponse> {
287
+ // TODO: DEPRECATED
288
+ async createOrder(
289
+ orderItems: CreateOrderRequest,
290
+ ): Promise<CreateOrderResponse | ErrorResponse> {
186
291
  try {
187
- const url = `${this.baseUrlTonder}/api/v1/orders/`;
292
+ const url = `${this.baseUrl}/api/v1/orders/`;
188
293
  const data = orderItems;
189
294
  const response = await fetch(url, {
190
295
  method: "POST",
191
296
  headers: {
192
297
  "Content-Type": "application/json",
193
- Authorization: `Token ${this.publicApiKeyTonder}`,
298
+ Authorization: `Token ${this.apiKeyTonder}`,
194
299
  },
195
300
  body: JSON.stringify(data),
196
301
  });
197
- if (response.ok) return await response.json() as CreateOrderResponse;
302
+ if (response.ok) return (await response.json()) as CreateOrderResponse;
198
303
  throw await buildErrorResponse(response);
199
304
  } catch (e) {
200
305
  throw buildErrorResponseFromCatch(e);
201
306
  }
202
307
  }
203
308
 
204
- async createPayment(paymentItems: CreatePaymentRequest): Promise<CreatePaymentResponse | ErrorResponse> {
309
+ // TODO: DEPRECATED
310
+ async createPayment(
311
+ paymentItems: CreatePaymentRequest,
312
+ ): Promise<CreatePaymentResponse | ErrorResponse> {
205
313
  try {
206
- const url = `${this.baseUrlTonder}/api/v1/business/${paymentItems.business_pk}/payments/`;
314
+ const url = `${this.baseUrl}/api/v1/business/${paymentItems.business_pk}/payments/`;
207
315
  const data = paymentItems;
208
316
  const response = await fetch(url, {
209
317
  method: "POST",
210
318
  headers: {
211
319
  "Content-Type": "application/json",
212
- Authorization: `Token ${this.publicApiKeyTonder}`,
320
+ Authorization: `Token ${this.apiKeyTonder}`,
213
321
  },
214
322
  body: JSON.stringify(data),
215
323
  });
216
- if (response.ok) return await response.json() as CreatePaymentResponse;
324
+ if (response.ok) return (await response.json()) as CreatePaymentResponse;
217
325
  throw await buildErrorResponse(response);
218
326
  } catch (e) {
219
327
  throw buildErrorResponseFromCatch(e);
220
328
  }
221
329
  }
222
- async handleCheckoutRouter(routerData: StartCheckoutRequest | StartCheckoutIdRequest){
223
- try {
224
- const url = `${this.baseUrlTonder}/api/v1/checkout-router/`;
225
- const data = routerData;
226
- const response = await fetch(url, {
227
- method: "POST",
228
- headers: {
229
- "Content-Type": "application/json",
230
- Authorization: `Token ${this.publicApiKeyTonder}`,
231
- },
232
- body: JSON.stringify({...data, ...(typeof MP_DEVICE_SESSION_ID !== "undefined" ? {mp_device_session_id: MP_DEVICE_SESSION_ID}:{})}),
233
- });
234
- if (response.ok) return await response.json() as StartCheckoutResponse;
235
- throw await buildErrorResponse(response);
236
- } catch (e) {
237
- throw buildErrorResponseFromCatch(e);
238
- }
330
+
331
+ // TODO: DEPRECATED
332
+ async startCheckoutRouter(
333
+ routerData: StartCheckoutRequest | StartCheckoutIdRequest,
334
+ ): Promise<StartCheckoutResponse | ErrorResponse | undefined> {
335
+ const checkoutResult = await startCheckoutRouter(
336
+ this.baseUrl,
337
+ this.apiKeyTonder,
338
+ routerData,
339
+ );
340
+ const payload = await this.init3DSRedirect(checkoutResult);
341
+ if (payload) return checkoutResult;
239
342
  }
240
343
 
241
- async startCheckoutRouter(routerData: StartCheckoutRequest | StartCheckoutIdRequest): Promise<StartCheckoutResponse | ErrorResponse | undefined> {
242
- const checkoutResult = await this.handleCheckoutRouter(routerData);
243
- const payload = await this.init3DSRedirect(checkoutResult)
244
- if(payload)
245
- return checkoutResult;
344
+ // TODO: DEPRECATED
345
+ async init3DSRedirect(checkoutResult: IStartCheckoutResponse) {
346
+ this.process3ds.setPayload(checkoutResult);
347
+ return await this._handle3dsRedirect(checkoutResult);
246
348
  }
247
349
 
248
- async startCheckoutRouterFull(routerFullData: StartCheckoutFullRequest): Promise<StartCheckoutResponse | ErrorResponse | undefined> {
249
-
350
+ // TODO: DEPRECATED
351
+ async startCheckoutRouterFull(
352
+ routerFullData: StartCheckoutFullRequest,
353
+ ): Promise<StartCheckoutResponse | ErrorResponse | undefined> {
250
354
  try {
251
-
252
- const {
253
- order,
254
- total,
255
- customer,
256
- skyflowTokens,
257
- return_url,
258
- isSandbox,
259
- metadata,
355
+ const {
356
+ order,
357
+ total,
358
+ customer,
359
+ skyflowTokens,
360
+ return_url,
361
+ isSandbox,
362
+ metadata,
260
363
  currency,
261
- payment_method
364
+ payment_method,
262
365
  } = routerFullData;
263
366
 
264
- const merchantResult = await this.getBusiness();
265
-
266
- const customerResult : CustomerRegisterResponse | ErrorResponse = await this.customerRegister(customer.email);
367
+ const merchantResult = await this._fetchMerchantData();
267
368
 
268
- if(customerResult && "auth_token" in customerResult && merchantResult && "reference" in merchantResult) {
369
+ const customerResult: CustomerRegisterResponse | ErrorResponse =
370
+ await this.customerRegister(customer.email);
269
371
 
372
+ if (
373
+ customerResult &&
374
+ "auth_token" in customerResult &&
375
+ merchantResult &&
376
+ "reference" in merchantResult
377
+ ) {
270
378
  const orderData: CreateOrderRequest = {
271
- business: this.publicApiKeyTonder,
379
+ business: this.apiKeyTonder,
272
380
  client: customerResult.auth_token,
273
381
  billing_address_id: null,
274
382
  shipping_address_id: null,
@@ -284,29 +392,30 @@ export class LiteCheckout implements LiteCheckoutConstructor {
284
392
 
285
393
  const dateString = now.toISOString();
286
394
 
287
- if("id" in orderResult && "id" in customerResult && "business" in merchantResult) {
288
-
395
+ if (
396
+ "id" in orderResult &&
397
+ "id" in customerResult &&
398
+ "business" in merchantResult
399
+ ) {
289
400
  const paymentItems: CreatePaymentRequest = {
290
401
  business_pk: merchantResult.business.pk,
291
402
  amount: total,
292
403
  date: dateString,
293
404
  order_id: orderResult.id,
294
- client_id: customerResult.id
405
+ client_id: customerResult.id,
295
406
  };
296
407
 
297
- const paymentResult = await this.createPayment(
298
- paymentItems
299
- );
408
+ const paymentResult = await this.createPayment(paymentItems);
300
409
 
301
410
  let deviceSessionIdTonder: any;
302
411
 
303
- const { openpay_keys, business } = merchantResult
412
+ const { openpay_keys, business } = merchantResult;
304
413
 
305
414
  if (openpay_keys.merchant_id && openpay_keys.public_key) {
306
- deviceSessionIdTonder = await this.getOpenpayDeviceSessionID(
415
+ deviceSessionIdTonder = await getOpenpayDeviceSessionID(
307
416
  openpay_keys.merchant_id,
308
417
  openpay_keys.public_key,
309
- isSandbox
418
+ isSandbox,
310
419
  );
311
420
  }
312
421
 
@@ -323,192 +432,101 @@ export class LiteCheckout implements LiteCheckoutConstructor {
323
432
  amount: total,
324
433
  title_ship: "shipping",
325
434
  description: "transaction",
326
- device_session_id: deviceSessionIdTonder ? deviceSessionIdTonder : null,
435
+ device_session_id: deviceSessionIdTonder
436
+ ? deviceSessionIdTonder
437
+ : null,
327
438
  token_id: "",
328
- order_id: ("id" in orderResult) && orderResult.id,
439
+ order_id: "id" in orderResult && orderResult.id,
329
440
  business_id: business.pk,
330
- payment_id: ("pk" in paymentResult) && paymentResult.pk,
331
- source: 'sdk',
441
+ payment_id: "pk" in paymentResult && paymentResult.pk,
442
+ source: "sdk",
332
443
  metadata: metadata,
333
444
  browser_info: getBrowserInfo(),
334
445
  currency: currency,
335
- ...( !!payment_method
336
- ? {payment_method}
337
- : {card: skyflowTokens}
338
- ),
339
- ...(typeof MP_DEVICE_SESSION_ID !== "undefined" ? {mp_device_session_id: MP_DEVICE_SESSION_ID}:{})
446
+ ...(!!payment_method
447
+ ? { payment_method }
448
+ : { card: skyflowTokens }),
449
+ ...(typeof MP_DEVICE_SESSION_ID !== "undefined"
450
+ ? { mp_device_session_id: MP_DEVICE_SESSION_ID }
451
+ : {}),
340
452
  };
341
453
 
342
- const checkoutResult = await this.handleCheckoutRouter(routerItems);
343
- const payload = await this.init3DSRedirect(checkoutResult)
344
- if(payload)
345
- return checkoutResult;
454
+ const checkoutResult = await startCheckoutRouter(
455
+ this.baseUrl,
456
+ this.apiKeyTonder,
457
+ routerItems,
458
+ );
459
+ const payload = await this.init3DSRedirect(checkoutResult);
460
+ if (payload) return checkoutResult;
346
461
  } else {
347
-
348
462
  throw new ErrorResponse({
349
463
  code: "500",
350
464
  body: orderResult as any,
351
465
  name: "Keys error",
352
- message: "Order response errors"
353
- } as IErrorResponse)
354
-
466
+ message: "Order response errors",
467
+ } as IErrorResponse);
355
468
  }
356
-
357
469
  } else {
358
-
359
470
  throw new ErrorResponse({
360
471
  code: "500",
361
472
  body: merchantResult as any,
362
473
  name: "Keys error",
363
- message: "Merchant or customer reposne errors"
364
- } as IErrorResponse)
365
-
474
+ message: "Merchant or customer reposne errors",
475
+ } as IErrorResponse);
366
476
  }
367
477
  } catch (e) {
368
-
369
478
  throw buildErrorResponseFromCatch(e);
370
-
371
- }
372
- }
373
-
374
- async init3DSRedirect(checkoutResult: ErrorResponse | StartCheckoutResponse){
375
- this.process3ds.setPayload(checkoutResult)
376
- return await this.handle3dsRedirect(checkoutResult)
377
- }
378
-
379
- async getSkyflowTokens({
380
- vault_id,
381
- vault_url,
382
- data,
383
- }: TokensRequest): Promise<any | ErrorResponse> {
384
- const skyflow = Skyflow.init({
385
- vaultID: vault_id,
386
- vaultURL: vault_url,
387
- getBearerToken: async () => await this.getVaultToken(),
388
- options: {
389
- logLevel: Skyflow.LogLevel.ERROR,
390
- env: Skyflow.Env.DEV,
391
- },
392
- });
393
-
394
- const collectContainer: CollectContainer = skyflow.container(
395
- Skyflow.ContainerType.COLLECT
396
- ) as CollectContainer;
397
-
398
- const fieldPromises = await this.getFieldsPromise(data, collectContainer);
399
-
400
- const result = await Promise.all(fieldPromises);
401
-
402
- const mountFail = result.some((item: boolean) => !item);
403
-
404
- if (mountFail) {
405
- throw buildErrorResponseFromCatch(Error("Ocurrió un error al montar los campos de la tarjeta"));
406
- } else {
407
- try {
408
- const collectResponseSkyflowTonder = await collectContainer.collect() as any;
409
- if (collectResponseSkyflowTonder) return collectResponseSkyflowTonder["records"][0]["fields"];
410
- throw buildErrorResponseFromCatch(Error("Por favor, verifica todos los campos de tu tarjeta"))
411
- } catch (error) {
412
- throw buildErrorResponseFromCatch(error);
413
- }
414
479
  }
415
480
  }
416
481
 
417
- async getVaultToken(): Promise<string> {
482
+ // TODO: DEPRECATED
483
+ async registerCustomerCard(
484
+ secureToken: string,
485
+ customerToken: string,
486
+ data: RegisterCustomerCardRequest,
487
+ ): Promise<RegisterCustomerCardResponse | ErrorResponse> {
418
488
  try {
419
- const response = await fetch(`${this.baseUrlTonder}/api/v1/vault-token/`, {
420
- method: "GET",
421
- headers: {
422
- Authorization: `Token ${this.publicApiKeyTonder}`,
423
- },
424
- signal: this.signal,
425
- });
426
- if (response.ok) return (await response.json() as GetVaultTokenResponse)?.token;
427
- throw new Error(`HTTPCODE: ${response.status}`)
428
- } catch (e) {
429
- throw new Error(`Failed to retrieve bearer token; ${typeof e == "string" ? e : (e as Error).message}`)
430
- }
431
- }
432
-
433
- async getFieldsPromise(data: any, collectContainer: CollectContainer): Promise<Promise<boolean>[]> {
434
- const fields = await this.getFields(data, collectContainer);
435
- if (!fields) return [];
436
-
437
- return fields.map((field: { element: CollectElement, key: string }) => {
438
- return new Promise((resolve) => {
439
- const div = document.createElement("div");
440
- div.hidden = true;
441
- div.id = `id-${field.key}`;
442
- document.querySelector(`body`)?.appendChild(div);
443
- setTimeout(() => {
444
- field.element.mount(`#id-${field.key}`);
445
- setInterval(() => {
446
- if (field.element.isMounted()) {
447
- const value = data[field.key];
448
- field.element.update({ value: value });
449
- return resolve(field.element.isMounted());
450
- }
451
- }, 120);
452
- }, 120);
453
- });
454
- })
455
- }
456
-
457
- async registerCustomerCard(secureToken: string, customerToken: string, data: RegisterCustomerCardRequest): Promise<RegisterCustomerCardResponse | ErrorResponse> {
458
- try {
459
- await this.#fetchMerchantData()
460
-
461
- const response = await fetch(`${this.baseUrlTonder}/api/v1/business/${getBusinessId(this.merchantData)}/cards/`, {
462
- method: 'POST',
463
- headers: {
464
- 'Authorization': `Bearer ${secureToken}`,
465
- 'User-token': customerToken,
466
- 'Content-Type': 'application/json'
467
- },
468
- signal: this.signal,
469
- body: JSON.stringify({...data})
470
- });
471
-
472
- if (response.ok) return await response.json() as RegisterCustomerCardResponse;
473
- throw await buildErrorResponse(response);
474
- } catch (error) {
475
- throw buildErrorResponseFromCatch(error);
476
- }
477
- }
478
-
479
- async getCustomerCards(customerToken: string, bearerToken: string): Promise<GetCustomerCardsResponse | ErrorResponse> {
480
- try {
481
- await this.#fetchMerchantData()
489
+ await this._fetchMerchantData();
482
490
 
483
- const response = await fetch(`${this.baseUrlTonder}/api/v1/business/${getBusinessId(this.merchantData)}/cards`, {
484
- method: 'GET',
485
- headers: {
486
- 'Authorization': `Bearer ${bearerToken}`,
487
- 'User-Token': customerToken,
488
- 'Content-Type': 'application/json',
489
- 'Accept': 'application/json'
491
+ const response = await fetch(
492
+ `${this.baseUrl}/api/v1/business/${getBusinessId(this.merchantData)}/cards/`,
493
+ {
494
+ method: "POST",
495
+ headers: {
496
+ Authorization: `Bearer ${secureToken}`,
497
+ "User-token": customerToken,
498
+ "Content-Type": "application/json",
499
+ },
500
+ body: JSON.stringify({ ...data }),
490
501
  },
491
- signal: this.signal,
492
- });
502
+ );
493
503
 
494
- if (response.ok) return await response.json() as GetCustomerCardsResponse;
504
+ if (response.ok)
505
+ return (await response.json()) as RegisterCustomerCardResponse;
495
506
  throw await buildErrorResponse(response);
496
507
  } catch (error) {
497
508
  throw buildErrorResponseFromCatch(error);
498
509
  }
499
510
  }
500
511
 
501
- async deleteCustomerCard(customerToken: string, skyflowId: string = ""): Promise<Boolean | ErrorResponse> {
512
+ // TODO: DEPRECATED
513
+ async deleteCustomerCard(
514
+ customerToken: string,
515
+ skyflowId: string = "",
516
+ ): Promise<Boolean | ErrorResponse> {
502
517
  try {
503
- await this.#fetchMerchantData()
504
- const response = await fetch(`${this.baseUrlTonder}/api/v1/business/${getBusinessId(this.merchantData)}/cards/${skyflowId}`, {
505
- method: 'DELETE',
506
- headers: {
507
- 'Authorization': `Token ${customerToken}`,
508
- 'Content-Type': 'application/json'
518
+ await this._fetchMerchantData();
519
+ const response = await fetch(
520
+ `${this.baseUrl}/api/v1/business/${getBusinessId(this.merchantData)}/cards/${skyflowId}`,
521
+ {
522
+ method: "DELETE",
523
+ headers: {
524
+ Authorization: `Token ${customerToken}`,
525
+ "Content-Type": "application/json",
526
+ },
527
+ signal: this.abortController.signal,
509
528
  },
510
- signal: this.signal,
511
- });
529
+ );
512
530
 
513
531
  if (response.ok) return true;
514
532
  throw await buildErrorResponse(response);
@@ -517,38 +535,36 @@ export class LiteCheckout implements LiteCheckoutConstructor {
517
535
  }
518
536
  }
519
537
 
520
- private async getFields(data: any, collectContainer: CollectContainer): Promise<{ element: CollectElement, key: string }[]> {
521
- return await Promise.all(
522
- Object.keys(data).map(async (key) => {
523
- const cardHolderNameElement = await collectContainer.create({
524
- table: "cards",
525
- column: key,
526
- type: Skyflow.ElementType.INPUT_FIELD,
527
- });
528
- return { element: cardHolderNameElement, key: key };
529
- })
530
- )
531
- }
532
-
538
+ // TODO: DEPRECATED
533
539
  async getActiveAPMs(): Promise<APM[]> {
534
540
  try {
535
- const apms_response = await getCustomerAPMs(this.baseUrlTonder, this.publicApiKeyTonder);
536
- const apms_results = apms_response && apms_response['results'] && apms_response['results'].length > 0 ? apms_response['results'] : []
541
+ const apms_response = await getCustomerAPMs(
542
+ this.baseUrl,
543
+ this.apiKeyTonder,
544
+ );
545
+ const apms_results =
546
+ apms_response &&
547
+ apms_response["results"] &&
548
+ apms_response["results"].length > 0
549
+ ? apms_response["results"]
550
+ : [];
537
551
  this.activeAPMs = apms_results
538
- .filter((apmItem: TonderAPM) =>
539
- apmItem.category.toLowerCase() !== 'cards')
552
+ .filter(
553
+ (apmItem: TonderAPM) => apmItem.category.toLowerCase() !== "cards",
554
+ )
540
555
  .map((apmItem: TonderAPM) => {
541
556
  const apm: APM = {
542
557
  id: apmItem.pk,
543
558
  payment_method: apmItem.payment_method,
544
559
  priority: apmItem.priority,
545
560
  category: apmItem.category,
546
- ...getPaymentMethodDetails(apmItem.payment_method,)
547
- }
561
+ ...getPaymentMethodDetails(apmItem.payment_method),
562
+ };
548
563
  return apm;
549
- }).sort((a: APM, b: APM) => a.priority - b.priority);
564
+ })
565
+ .sort((a: APM, b: APM) => a.priority - b.priority);
550
566
 
551
- return this.activeAPMs
567
+ return this.activeAPMs;
552
568
  } catch (e) {
553
569
  console.error("Error getting APMS", e);
554
570
  return [];
@@ -557,13 +573,13 @@ export class LiteCheckout implements LiteCheckoutConstructor {
557
573
 
558
574
  async getSecureToken(token: string): Promise<GetSecureTokenResponse | ErrorResponse> {
559
575
  try {
560
- const response = await fetch(`${this.baseUrlTonder}/api/secure-token/`, {
576
+ const response = await fetch(`${this.baseUrl}/api/secure-token/`, {
561
577
  method: 'POST',
562
578
  headers: {
563
579
  'Authorization': `Token ${token}`,
564
580
  'Content-Type': 'application/json'
565
581
  },
566
- signal: this.signal,
582
+ signal: this.abortController.signal
567
583
  });
568
584
 
569
585
  if (response.ok) return await response.json() as GetSecureTokenResponse;