@tonder.io/ionic-lite-sdk 0.0.36-beta.1 → 0.0.37-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 +385 -0
  30. package/src/classes/errorResponse.ts +1 -1
  31. package/src/classes/liteCheckout.ts +369 -356
  32. package/src/data/businessApi.ts +18 -0
  33. package/src/data/cardApi.ts +85 -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,339 @@ 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
+ card: ISaveCardRequest,
84
+ ): Promise<ISaveCardResponse> {
77
85
  try {
78
- if (!this.merchantData){
79
- this.merchantData = await this.getBusiness();
80
- }
81
- return this.merchantData
82
- }catch(e){
83
- return this.merchantData
86
+ await this._fetchMerchantData();
87
+ const { auth_token } = await this._getCustomer();
88
+ const { vault_id, vault_url, business } = this.merchantData!;
89
+
90
+ const skyflowTokens: ISaveCardSkyflowRequest = await getSkyflowTokens({
91
+ vault_id: vault_id,
92
+ vault_url: vault_url,
93
+ data: card,
94
+ baseUrl: this.baseUrl,
95
+ apiKey: this.apiKeyTonder,
96
+ });
97
+
98
+ return await this._saveCustomerCard(
99
+ auth_token,
100
+ business?.pk,
101
+ skyflowTokens,
102
+ );
103
+ } catch (error) {
104
+ throw formatPublicErrorResponse(
105
+ {
106
+ message: MESSAGES.saveCardError,
107
+ },
108
+ error,
109
+ );
84
110
  }
85
111
  }
86
112
 
87
- async getBusiness(): Promise<GetBusinessResponse | ErrorResponse> {
113
+ public async removeCustomerCard(skyflowId: string): Promise<string> {
88
114
  try {
89
- const getBusiness = await fetch(
90
- `${this.baseUrlTonder}/api/v1/payments/business/${this.publicApiKeyTonder}`,
115
+ await this._fetchMerchantData();
116
+ const { auth_token } = await this._getCustomer();
117
+ const { business } = this.merchantData!;
118
+
119
+ return await this._removeCustomerCard(
120
+ auth_token,
121
+ business?.pk,
122
+ skyflowId,
123
+ );
124
+ } catch (error) {
125
+ throw formatPublicErrorResponse(
91
126
  {
92
- headers: {
93
- Authorization: `Token ${this.publicApiKeyTonder}`,
94
- },
95
- signal: this.signal,
96
- }
127
+ message: MESSAGES.removeCardError,
128
+ },
129
+ error,
97
130
  );
131
+ }
132
+ }
98
133
 
99
- if (getBusiness.ok) return (await getBusiness.json()) as Business;
134
+ public async getCustomerPaymentMethods(): Promise<IPaymentMethod[]> {
135
+ try {
136
+ const response = await this._fetchCustomerPaymentMethods();
100
137
 
101
- throw await buildErrorResponse(getBusiness);
102
- } catch (e) {
103
- throw buildErrorResponseFromCatch(e);
138
+ const apms_results =
139
+ response && "results" in response && response["results"].length > 0
140
+ ? response["results"]
141
+ : [];
142
+
143
+ return apms_results
144
+ .filter((apmItem) => apmItem.category.toLowerCase() !== "cards")
145
+ .map((apmItem) => {
146
+ const apm = {
147
+ id: apmItem.pk,
148
+ payment_method: apmItem.payment_method,
149
+ priority: apmItem.priority,
150
+ category: apmItem.category,
151
+ ...getPaymentMethodDetails(apmItem.payment_method),
152
+ };
153
+ return apm;
154
+ })
155
+ .sort((a, b) => a.priority - b.priority);
156
+ } catch (error) {
157
+ throw formatPublicErrorResponse(
158
+ {
159
+ message: MESSAGES.getPaymentMethodsError,
160
+ },
161
+ error,
162
+ );
104
163
  }
105
164
  }
106
165
 
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)
166
+ public async getBusiness(): Promise<GetBusinessResponse> {
167
+ try {
168
+ return await fetchBusiness(
169
+ this.baseUrl,
170
+ this.apiKeyTonder,
171
+ this.abortController.signal,
172
+ );
173
+ } catch (e) {
174
+ throw formatPublicErrorResponse(
175
+ {
176
+ message: MESSAGES.getBusinessError,
177
+ },
178
+ e,
179
+ );
180
+ }
112
181
  }
113
182
 
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
183
+ // TODO: DEPRECATED
184
+ async getOpenpayDeviceSessionID(
185
+ merchant_id: string,
186
+ public_key: string,
187
+ is_sandbox: boolean,
188
+ ): Promise<string | ErrorResponse> {
189
+ try {
190
+ return await getOpenpayDeviceSessionID(
191
+ merchant_id,
192
+ public_key,
193
+ is_sandbox,
194
+ );
195
+ } catch (e) {
196
+ throw buildErrorResponseFromCatch(e);
118
197
  }
198
+ }
119
199
 
120
- if (["Success", "Authorized"].includes(response?.transaction_status)) {
121
- return response;
122
- }
200
+ // TODO: DEPRECATED
201
+ async getSkyflowTokens({
202
+ vault_id,
203
+ vault_url,
204
+ data,
205
+ }: TokensRequest): Promise<any | ErrorResponse> {
206
+ return await getSkyflowTokens({
207
+ vault_id: vault_id,
208
+ vault_url: vault_url,
209
+ data,
210
+ baseUrl: this.baseUrl,
211
+ apiKey: this.apiKeyTonder,
212
+ });
213
+ }
123
214
 
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
- }
215
+ _setCartTotal(total: string) {
216
+ this.cartTotal = total;
138
217
  }
139
218
 
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()
219
+ async _checkout({
220
+ card,
221
+ payment_method,
222
+ isSandbox,
223
+ // TODO: DEPRECATED
224
+ returnUrl: returnUrlData
225
+ }: {
226
+ card?: ICardFields | string;
227
+ payment_method?: string;
228
+ isSandbox?: boolean;
229
+ returnUrl?: string;
230
+ }) {
231
+ await this._fetchMerchantData();
232
+ const customer = await this._getCustomer(this.abortController.signal);
233
+ const { vault_id, vault_url } = this.merchantData!;
234
+ let skyflowTokens;
235
+ if (!payment_method || payment_method !== "" || payment_method === null) {
236
+ if (typeof card === "string") {
237
+ skyflowTokens = {
238
+ skyflow_id: card,
239
+ };
158
240
  } else {
159
- return response;
241
+ skyflowTokens = await getSkyflowTokens({
242
+ vault_id: vault_id,
243
+ vault_url: vault_url,
244
+ data: { ...card, card_number: card!.card_number.replace(/\s+/g, "") },
245
+ baseUrl: this.baseUrl,
246
+ apiKey: this.apiKeyTonder,
247
+ });
160
248
  }
161
249
  }
250
+
251
+ return await this._handleCheckout({
252
+ card: skyflowTokens,
253
+ payment_method,
254
+ customer,
255
+ isSandbox,
256
+ returnUrl: returnUrlData
257
+ });
162
258
  }
163
-
164
- async customerRegister(email: string): Promise<CustomerRegisterResponse | ErrorResponse> {
259
+
260
+ // TODO: DEPRECATED
261
+ async customerRegister(
262
+ email: string,
263
+ ): Promise<CustomerRegisterResponse | ErrorResponse> {
165
264
  try {
166
- const url = `${this.baseUrlTonder}/api/v1/customer/`;
265
+ const url = `${this.baseUrl}/api/v1/customer/`;
167
266
  const data = { email: email };
168
267
  const response = await fetch(url, {
169
268
  method: "POST",
170
269
  headers: {
171
270
  "Content-Type": "application/json",
172
- Authorization: `Token ${this.publicApiKeyTonder}`,
271
+ Authorization: `Token ${this.apiKeyTonder}`,
173
272
  },
174
- signal: this.signal,
273
+ signal: this.abortController.signal,
175
274
  body: JSON.stringify(data),
176
275
  });
177
276
 
178
- if (response.ok) return await response.json() as CustomerRegisterResponse;
277
+ if (response.ok)
278
+ return (await response.json()) as CustomerRegisterResponse;
179
279
  throw await buildErrorResponse(response);
180
280
  } catch (e) {
181
281
  throw buildErrorResponseFromCatch(e);
182
282
  }
183
283
  }
184
284
 
185
- async createOrder(orderItems: CreateOrderRequest): Promise<CreateOrderResponse | ErrorResponse> {
285
+ // TODO: DEPRECATED
286
+ async createOrder(
287
+ orderItems: CreateOrderRequest,
288
+ ): Promise<CreateOrderResponse | ErrorResponse> {
186
289
  try {
187
- const url = `${this.baseUrlTonder}/api/v1/orders/`;
290
+ const url = `${this.baseUrl}/api/v1/orders/`;
188
291
  const data = orderItems;
189
292
  const response = await fetch(url, {
190
293
  method: "POST",
191
294
  headers: {
192
295
  "Content-Type": "application/json",
193
- Authorization: `Token ${this.publicApiKeyTonder}`,
296
+ Authorization: `Token ${this.apiKeyTonder}`,
194
297
  },
195
298
  body: JSON.stringify(data),
196
299
  });
197
- if (response.ok) return await response.json() as CreateOrderResponse;
300
+ if (response.ok) return (await response.json()) as CreateOrderResponse;
198
301
  throw await buildErrorResponse(response);
199
302
  } catch (e) {
200
303
  throw buildErrorResponseFromCatch(e);
201
304
  }
202
305
  }
203
306
 
204
- async createPayment(paymentItems: CreatePaymentRequest): Promise<CreatePaymentResponse | ErrorResponse> {
307
+ // TODO: DEPRECATED
308
+ async createPayment(
309
+ paymentItems: CreatePaymentRequest,
310
+ ): Promise<CreatePaymentResponse | ErrorResponse> {
205
311
  try {
206
- const url = `${this.baseUrlTonder}/api/v1/business/${paymentItems.business_pk}/payments/`;
312
+ const url = `${this.baseUrl}/api/v1/business/${paymentItems.business_pk}/payments/`;
207
313
  const data = paymentItems;
208
314
  const response = await fetch(url, {
209
315
  method: "POST",
210
316
  headers: {
211
317
  "Content-Type": "application/json",
212
- Authorization: `Token ${this.publicApiKeyTonder}`,
318
+ Authorization: `Token ${this.apiKeyTonder}`,
213
319
  },
214
320
  body: JSON.stringify(data),
215
321
  });
216
- if (response.ok) return await response.json() as CreatePaymentResponse;
322
+ if (response.ok) return (await response.json()) as CreatePaymentResponse;
217
323
  throw await buildErrorResponse(response);
218
324
  } catch (e) {
219
325
  throw buildErrorResponseFromCatch(e);
220
326
  }
221
327
  }
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
- }
328
+
329
+ // TODO: DEPRECATED
330
+ async startCheckoutRouter(
331
+ routerData: StartCheckoutRequest | StartCheckoutIdRequest,
332
+ ): Promise<StartCheckoutResponse | ErrorResponse | undefined> {
333
+ const checkoutResult = await startCheckoutRouter(
334
+ this.baseUrl,
335
+ this.apiKeyTonder,
336
+ routerData,
337
+ );
338
+ const payload = await this.init3DSRedirect(checkoutResult);
339
+ if (payload) return checkoutResult;
239
340
  }
240
341
 
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;
342
+ // TODO: DEPRECATED
343
+ async init3DSRedirect(checkoutResult: IStartCheckoutResponse) {
344
+ this.process3ds.setPayload(checkoutResult);
345
+ return await this._handle3dsRedirect(checkoutResult);
246
346
  }
247
347
 
248
- async startCheckoutRouterFull(routerFullData: StartCheckoutFullRequest): Promise<StartCheckoutResponse | ErrorResponse | undefined> {
249
-
348
+ // TODO: DEPRECATED
349
+ async startCheckoutRouterFull(
350
+ routerFullData: StartCheckoutFullRequest,
351
+ ): Promise<StartCheckoutResponse | ErrorResponse | undefined> {
250
352
  try {
251
-
252
- const {
253
- order,
254
- total,
255
- customer,
256
- skyflowTokens,
257
- return_url,
258
- isSandbox,
259
- metadata,
353
+ const {
354
+ order,
355
+ total,
356
+ customer,
357
+ skyflowTokens,
358
+ return_url,
359
+ isSandbox,
360
+ metadata,
260
361
  currency,
261
- payment_method
362
+ payment_method,
262
363
  } = routerFullData;
263
364
 
264
- const merchantResult = await this.getBusiness();
265
-
266
- const customerResult : CustomerRegisterResponse | ErrorResponse = await this.customerRegister(customer.email);
365
+ const merchantResult = await this._fetchMerchantData();
267
366
 
268
- if(customerResult && "auth_token" in customerResult && merchantResult && "reference" in merchantResult) {
367
+ const customerResult: CustomerRegisterResponse | ErrorResponse =
368
+ await this.customerRegister(customer.email);
269
369
 
370
+ if (
371
+ customerResult &&
372
+ "auth_token" in customerResult &&
373
+ merchantResult &&
374
+ "reference" in merchantResult
375
+ ) {
270
376
  const orderData: CreateOrderRequest = {
271
- business: this.publicApiKeyTonder,
377
+ business: this.apiKeyTonder,
272
378
  client: customerResult.auth_token,
273
379
  billing_address_id: null,
274
380
  shipping_address_id: null,
@@ -284,29 +390,30 @@ export class LiteCheckout implements LiteCheckoutConstructor {
284
390
 
285
391
  const dateString = now.toISOString();
286
392
 
287
- if("id" in orderResult && "id" in customerResult && "business" in merchantResult) {
288
-
393
+ if (
394
+ "id" in orderResult &&
395
+ "id" in customerResult &&
396
+ "business" in merchantResult
397
+ ) {
289
398
  const paymentItems: CreatePaymentRequest = {
290
399
  business_pk: merchantResult.business.pk,
291
400
  amount: total,
292
401
  date: dateString,
293
402
  order_id: orderResult.id,
294
- client_id: customerResult.id
403
+ client_id: customerResult.id,
295
404
  };
296
405
 
297
- const paymentResult = await this.createPayment(
298
- paymentItems
299
- );
406
+ const paymentResult = await this.createPayment(paymentItems);
300
407
 
301
408
  let deviceSessionIdTonder: any;
302
409
 
303
- const { openpay_keys, business } = merchantResult
410
+ const { openpay_keys, business } = merchantResult;
304
411
 
305
412
  if (openpay_keys.merchant_id && openpay_keys.public_key) {
306
- deviceSessionIdTonder = await this.getOpenpayDeviceSessionID(
413
+ deviceSessionIdTonder = await getOpenpayDeviceSessionID(
307
414
  openpay_keys.merchant_id,
308
415
  openpay_keys.public_key,
309
- isSandbox
416
+ isSandbox,
310
417
  );
311
418
  }
312
419
 
@@ -323,192 +430,100 @@ export class LiteCheckout implements LiteCheckoutConstructor {
323
430
  amount: total,
324
431
  title_ship: "shipping",
325
432
  description: "transaction",
326
- device_session_id: deviceSessionIdTonder ? deviceSessionIdTonder : null,
433
+ device_session_id: deviceSessionIdTonder
434
+ ? deviceSessionIdTonder
435
+ : null,
327
436
  token_id: "",
328
- order_id: ("id" in orderResult) && orderResult.id,
437
+ order_id: "id" in orderResult && orderResult.id,
329
438
  business_id: business.pk,
330
- payment_id: ("pk" in paymentResult) && paymentResult.pk,
331
- source: 'sdk',
439
+ payment_id: "pk" in paymentResult && paymentResult.pk,
440
+ source: "sdk",
332
441
  metadata: metadata,
333
442
  browser_info: getBrowserInfo(),
334
443
  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}:{})
444
+ ...(!!payment_method
445
+ ? { payment_method }
446
+ : { card: skyflowTokens }),
447
+ ...(typeof MP_DEVICE_SESSION_ID !== "undefined"
448
+ ? { mp_device_session_id: MP_DEVICE_SESSION_ID }
449
+ : {}),
340
450
  };
341
451
 
342
- const checkoutResult = await this.handleCheckoutRouter(routerItems);
343
- const payload = await this.init3DSRedirect(checkoutResult)
344
- if(payload)
345
- return checkoutResult;
452
+ const checkoutResult = await startCheckoutRouter(
453
+ this.baseUrl,
454
+ this.apiKeyTonder,
455
+ routerItems,
456
+ );
457
+ const payload = await this.init3DSRedirect(checkoutResult);
458
+ if (payload) return checkoutResult;
346
459
  } else {
347
-
348
460
  throw new ErrorResponse({
349
461
  code: "500",
350
462
  body: orderResult as any,
351
463
  name: "Keys error",
352
- message: "Order response errors"
353
- } as IErrorResponse)
354
-
464
+ message: "Order response errors",
465
+ } as IErrorResponse);
355
466
  }
356
-
357
467
  } else {
358
-
359
468
  throw new ErrorResponse({
360
469
  code: "500",
361
470
  body: merchantResult as any,
362
471
  name: "Keys error",
363
- message: "Merchant or customer reposne errors"
364
- } as IErrorResponse)
365
-
472
+ message: "Merchant or customer reposne errors",
473
+ } as IErrorResponse);
366
474
  }
367
475
  } catch (e) {
368
-
369
476
  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
477
  }
415
478
  }
416
479
 
417
- async getVaultToken(): Promise<string> {
480
+ // TODO: DEPRECATED
481
+ async registerCustomerCard(
482
+ secureToken: string,
483
+ customerToken: string,
484
+ data: RegisterCustomerCardRequest,
485
+ ): Promise<RegisterCustomerCardResponse | ErrorResponse> {
418
486
  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()
487
+ await this._fetchMerchantData();
482
488
 
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'
489
+ const response = await fetch(
490
+ `${this.baseUrl}/api/v1/business/${getBusinessId(this.merchantData)}/cards/`,
491
+ {
492
+ method: "POST",
493
+ headers: {
494
+ Authorization: `Token ${customerToken}`,
495
+ "Content-Type": "application/json",
496
+ },
497
+ body: JSON.stringify({ ...data }),
490
498
  },
491
- signal: this.signal,
492
- });
499
+ );
493
500
 
494
- if (response.ok) return await response.json() as GetCustomerCardsResponse;
501
+ if (response.ok)
502
+ return (await response.json()) as RegisterCustomerCardResponse;
495
503
  throw await buildErrorResponse(response);
496
504
  } catch (error) {
497
505
  throw buildErrorResponseFromCatch(error);
498
506
  }
499
507
  }
500
508
 
501
- async deleteCustomerCard(customerToken: string, skyflowId: string = ""): Promise<Boolean | ErrorResponse> {
509
+ // TODO: DEPRECATED
510
+ async deleteCustomerCard(
511
+ customerToken: string,
512
+ skyflowId: string = "",
513
+ ): Promise<Boolean | ErrorResponse> {
502
514
  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'
515
+ await this._fetchMerchantData();
516
+ const response = await fetch(
517
+ `${this.baseUrl}/api/v1/business/${getBusinessId(this.merchantData)}/cards/${skyflowId}`,
518
+ {
519
+ method: "DELETE",
520
+ headers: {
521
+ Authorization: `Token ${customerToken}`,
522
+ "Content-Type": "application/json",
523
+ },
524
+ signal: this.abortController.signal,
509
525
  },
510
- signal: this.signal,
511
- });
526
+ );
512
527
 
513
528
  if (response.ok) return true;
514
529
  throw await buildErrorResponse(response);
@@ -517,38 +532,36 @@ export class LiteCheckout implements LiteCheckoutConstructor {
517
532
  }
518
533
  }
519
534
 
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
-
535
+ // TODO: DEPRECATED
533
536
  async getActiveAPMs(): Promise<APM[]> {
534
537
  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'] : []
538
+ const apms_response = await getCustomerAPMs(
539
+ this.baseUrl,
540
+ this.apiKeyTonder,
541
+ );
542
+ const apms_results =
543
+ apms_response &&
544
+ apms_response["results"] &&
545
+ apms_response["results"].length > 0
546
+ ? apms_response["results"]
547
+ : [];
537
548
  this.activeAPMs = apms_results
538
- .filter((apmItem: TonderAPM) =>
539
- apmItem.category.toLowerCase() !== 'cards')
549
+ .filter(
550
+ (apmItem: TonderAPM) => apmItem.category.toLowerCase() !== "cards",
551
+ )
540
552
  .map((apmItem: TonderAPM) => {
541
553
  const apm: APM = {
542
554
  id: apmItem.pk,
543
555
  payment_method: apmItem.payment_method,
544
556
  priority: apmItem.priority,
545
557
  category: apmItem.category,
546
- ...getPaymentMethodDetails(apmItem.payment_method,)
547
- }
558
+ ...getPaymentMethodDetails(apmItem.payment_method),
559
+ };
548
560
  return apm;
549
- }).sort((a: APM, b: APM) => a.priority - b.priority);
561
+ })
562
+ .sort((a: APM, b: APM) => a.priority - b.priority);
550
563
 
551
- return this.activeAPMs
564
+ return this.activeAPMs;
552
565
  } catch (e) {
553
566
  console.error("Error getting APMS", e);
554
567
  return [];
@@ -557,13 +570,13 @@ export class LiteCheckout implements LiteCheckoutConstructor {
557
570
 
558
571
  async getSecureToken(token: string): Promise<GetSecureTokenResponse | ErrorResponse> {
559
572
  try {
560
- const response = await fetch(`${this.baseUrlTonder}/api/secure-token/`, {
573
+ const response = await fetch(`${this.baseUrl}/api/secure-token/`, {
561
574
  method: 'POST',
562
575
  headers: {
563
576
  'Authorization': `Token ${token}`,
564
577
  'Content-Type': 'application/json'
565
578
  },
566
- signal: this.signal,
579
+ signal: this.abortController.signal
567
580
  });
568
581
 
569
582
  if (response.ok) return await response.json() as GetSecureTokenResponse;