tonder-web-sdk 1.16.1 → 1.16.6-beta.DEV-1433.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 (105) hide show
  1. package/README.md +134 -40
  2. package/package.json +29 -6
  3. package/types/card.d.ts +17 -17
  4. package/types/checkout.d.ts +85 -87
  5. package/types/common.d.ts +8 -2
  6. package/types/customer.d.ts +10 -10
  7. package/types/index.d.ts +9 -11
  8. package/types/inlineCheckout.d.ts +81 -61
  9. package/types/liteInlineCheckout.d.ts +78 -83
  10. package/types/paymentMethod.d.ts +17 -17
  11. package/types/transaction.d.ts +94 -94
  12. package/v1/bundle.min.js +1 -18
  13. package/.env-example +0 -1
  14. package/cypress/e2e/1-getting-started/todo.cy.js +0 -143
  15. package/cypress/e2e/2-advanced-examples/actions.cy.js +0 -299
  16. package/cypress/e2e/2-advanced-examples/aliasing.cy.js +0 -39
  17. package/cypress/e2e/2-advanced-examples/assertions.cy.js +0 -176
  18. package/cypress/e2e/2-advanced-examples/connectors.cy.js +0 -98
  19. package/cypress/e2e/2-advanced-examples/cookies.cy.js +0 -118
  20. package/cypress/e2e/2-advanced-examples/cypress_api.cy.js +0 -185
  21. package/cypress/e2e/2-advanced-examples/files.cy.js +0 -85
  22. package/cypress/e2e/2-advanced-examples/location.cy.js +0 -32
  23. package/cypress/e2e/2-advanced-examples/misc.cy.js +0 -104
  24. package/cypress/e2e/2-advanced-examples/navigation.cy.js +0 -56
  25. package/cypress/e2e/2-advanced-examples/network_requests.cy.js +0 -163
  26. package/cypress/e2e/2-advanced-examples/querying.cy.js +0 -114
  27. package/cypress/e2e/2-advanced-examples/spies_stubs_clocks.cy.js +0 -201
  28. package/cypress/e2e/2-advanced-examples/storage.cy.js +0 -110
  29. package/cypress/e2e/2-advanced-examples/traversal.cy.js +0 -121
  30. package/cypress/e2e/2-advanced-examples/utilities.cy.js +0 -108
  31. package/cypress/e2e/2-advanced-examples/viewport.cy.js +0 -58
  32. package/cypress/e2e/2-advanced-examples/waiting.cy.js +0 -30
  33. package/cypress/e2e/2-advanced-examples/window.cy.js +0 -22
  34. package/cypress/fixtures/example.json +0 -5
  35. package/cypress/support/commands.js +0 -25
  36. package/cypress/support/e2e.js +0 -20
  37. package/cypress.config.js +0 -9
  38. package/index.js.example +0 -50
  39. package/samples/react/README.md +0 -70
  40. package/samples/react/build/asset-manifest.json +0 -16
  41. package/samples/react/build/favicon.ico +0 -0
  42. package/samples/react/build/index.html +0 -1
  43. package/samples/react/build/logo192.png +0 -0
  44. package/samples/react/build/logo512.png +0 -0
  45. package/samples/react/build/manifest.json +0 -25
  46. package/samples/react/build/robots.txt +0 -3
  47. package/samples/react/build/static/css/main.073c9b0a.css +0 -2
  48. package/samples/react/build/static/css/main.073c9b0a.css.map +0 -1
  49. package/samples/react/build/static/js/787.b83ed06f.chunk.js +0 -2
  50. package/samples/react/build/static/js/787.b83ed06f.chunk.js.map +0 -1
  51. package/samples/react/build/static/js/main.0a848807.js +0 -3
  52. package/samples/react/build/static/js/main.0a848807.js.LICENSE.txt +0 -39
  53. package/samples/react/build/static/js/main.0a848807.js.map +0 -1
  54. package/samples/react/build/static/media/sdk-icons.b491623214b2af4cccdb.png +0 -0
  55. package/samples/react/package-lock.json +0 -28973
  56. package/samples/react/package.json +0 -44
  57. package/samples/react/public/favicon.ico +0 -0
  58. package/samples/react/public/index.html +0 -43
  59. package/samples/react/public/logo192.png +0 -0
  60. package/samples/react/public/logo512.png +0 -0
  61. package/samples/react/public/manifest.json +0 -25
  62. package/samples/react/public/robots.txt +0 -3
  63. package/samples/react/src/App.css +0 -38
  64. package/samples/react/src/App.js +0 -22
  65. package/samples/react/src/App.test.js +0 -8
  66. package/samples/react/src/assets/img/sdk-icons.png +0 -0
  67. package/samples/react/src/components/Cart.js +0 -29
  68. package/samples/react/src/components/ProductCard.js +0 -27
  69. package/samples/react/src/context/CartContext.js +0 -116
  70. package/samples/react/src/index.css +0 -13
  71. package/samples/react/src/index.js +0 -17
  72. package/samples/react/src/logo.svg +0 -1
  73. package/samples/react/src/reportWebVitals.js +0 -13
  74. package/samples/react/src/screens/Checkout.js +0 -82
  75. package/samples/react/src/screens/Store.js +0 -21
  76. package/samples/react/src/setupTests.js +0 -5
  77. package/samples/react/src/storeProducts.js +0 -30
  78. package/src/classes/3dsHandler.js +0 -203
  79. package/src/classes/BaseInlineCheckout.js +0 -324
  80. package/src/classes/LiteInlineCheckout.js +0 -220
  81. package/src/classes/checkout.js +0 -125
  82. package/src/classes/globalLoader.js +0 -29
  83. package/src/classes/inlineCheckout.js +0 -515
  84. package/src/data/apmApi.js +0 -44
  85. package/src/data/businessApi.js +0 -19
  86. package/src/data/cardApi.js +0 -143
  87. package/src/data/checkoutApi.js +0 -92
  88. package/src/data/customerApi.js +0 -37
  89. package/src/data/index.js +0 -17
  90. package/src/data/openPayApi.js +0 -16
  91. package/src/data/skyflowApi.js +0 -18
  92. package/src/helpers/skyflow.js +0 -361
  93. package/src/helpers/styles.js +0 -61
  94. package/src/helpers/template-skeleton.js +0 -59
  95. package/src/helpers/template.js +0 -743
  96. package/src/helpers/utils.js +0 -163
  97. package/src/helpers/validations.js +0 -54
  98. package/src/index-dev.js +0 -307
  99. package/src/index.html +0 -172
  100. package/src/index.js +0 -15
  101. package/src/shared/catalog/paymentMethodsCatalog.js +0 -247
  102. package/src/shared/constants/messages.js +0 -10
  103. package/src/shared/constants/paymentMethodAPM.js +0 -63
  104. package/src/shared/constants/tonderUrl.js +0 -8
  105. package/webpack.config.js +0 -77
@@ -1,203 +0,0 @@
1
- export class ThreeDSHandler {
2
- constructor({
3
- payload = null,
4
- apiKey,
5
- baseUrl,
6
- }) {
7
- this.baseUrl = baseUrl
8
- this.apiKey = apiKey
9
- this.payload = payload
10
- }
11
-
12
- saveVerifyTransactionUrl() {
13
- const url = this.payload?.next_action?.redirect_to_url?.verify_transaction_status_url
14
- if (url) {
15
- this.saveUrlWithExpiration(url)
16
- } else {
17
- const url = this.payload?.next_action?.iframe_resources?.verify_transaction_status_url
18
- if (url) {
19
- this.saveUrlWithExpiration(url)
20
- } else {
21
- console.log('No verify_transaction_status_url found');
22
- }
23
- }
24
- }
25
-
26
- saveUrlWithExpiration(url) {
27
- try {
28
- const now = new Date()
29
- const item = {
30
- url: url,
31
- // Expires after 20 minutes
32
- expires: now.getTime() + 20 * 60 * 1000
33
- }
34
- localStorage.setItem('verify_transaction_status', JSON.stringify(item))
35
- } catch (error) {
36
- console.log('error: ', error)
37
- }
38
- }
39
-
40
- getUrlWithExpiration() {
41
- const item = JSON.parse(localStorage.getItem("verify_transaction_status"))
42
- if (!item) return
43
-
44
- const now = new Date()
45
- if (now.getTime() > item.expires) {
46
- this.removeVerifyTransactionUrl()
47
- return null
48
- } else {
49
- return item.url
50
- }
51
- }
52
-
53
- removeVerifyTransactionUrl() {
54
- localStorage.removeItem("verify_transaction_status")
55
- }
56
-
57
- getVerifyTransactionUrl() {
58
- return localStorage.getItem("verify_transaction_status")
59
- }
60
-
61
- loadIframe() {
62
- const iframe = this.payload?.next_action?.iframe_resources?.iframe
63
- if (iframe) {
64
- return new Promise((resolve, reject) => {
65
- const iframe = this.payload?.next_action?.iframe_resources?.iframe
66
-
67
- if (iframe) {
68
- // TODO: This is not working for Azul
69
- this.saveVerifyTransactionUrl()
70
- const container = document.createElement('div')
71
- container.innerHTML = iframe
72
- document.body.appendChild(container)
73
-
74
- // Create and append the script tag manually
75
- const script = document.createElement('script')
76
- script.textContent = 'document.getElementById("tdsMmethodForm").submit();'
77
- container.appendChild(script)
78
-
79
- // Resolve the promise when the iframe is loaded
80
- const iframeElement = document.getElementById('tdsMmethodTgtFrame')
81
- iframeElement.onload = () => resolve(true)
82
- } else {
83
- console.log('No redirection found');
84
- reject(false)
85
- }
86
- })
87
- }
88
- }
89
-
90
- getRedirectUrl() {
91
- return this.payload?.next_action?.redirect_to_url?.url
92
- }
93
-
94
- redirectToChallenge() {
95
- const url = this.getRedirectUrl()
96
- if (url) {
97
- this.saveVerifyTransactionUrl()
98
- window.location = url;
99
- } else {
100
- console.log('No redirection found');
101
- }
102
- }
103
-
104
- // Returns an object
105
- // https://example.com/?name=John&age=30&city=NewYork
106
- // { name: "John", age: "30", city: "NewYork" }
107
- getURLParameters() {
108
- const parameters = {};
109
- const urlParams = new URLSearchParams(window.location.search);
110
-
111
- for (const [key, value] of urlParams) {
112
- parameters[key] = value;
113
- }
114
-
115
- return parameters;
116
- }
117
-
118
- // TODO: Remove this duplication
119
- handleSuccessTransaction(response) {
120
- this.removeVerifyTransactionUrl();
121
- console.log('Transacción autorizada');
122
- return response;
123
- }
124
-
125
- handleDeclinedTransaction(response) {
126
- this.removeVerifyTransactionUrl();
127
- return response;
128
- }
129
-
130
- async handle3dsChallenge(response_json) {
131
- // Create the form element:
132
- const form = document.createElement('form');
133
- form.name = 'frm';
134
- form.method = 'POST';
135
- form.action = response_json.redirect_post_url;
136
-
137
- // Add hidden fields:
138
- const creqInput = document.createElement('input');
139
- creqInput.type = 'hidden';
140
- creqInput.name = 'creq';
141
- creqInput.value = response_json.creq;
142
- form.appendChild(creqInput);
143
-
144
- if (response_json.term_url) {
145
- const termUrlInput = document.createElement('input');
146
- termUrlInput.type = 'hidden';
147
- termUrlInput.name = 'TermUrl';
148
- termUrlInput.value = response_json.term_url;
149
- form.appendChild(termUrlInput);
150
- }
151
-
152
- // Append the form to the body:
153
- document.body.appendChild(form);
154
- form.submit();
155
- }
156
-
157
- // TODO: This works for Azul
158
- async handleTransactionResponse(response) {
159
- const response_json = await response.json();
160
- // Azul property
161
- if (response_json.status === "Pending" && response_json.redirect_post_url) {
162
- return await this.handle3dsChallenge(response_json);
163
- } else if (["Success", "Authorized"].includes(response_json.status)) {
164
- return this.handleSuccessTransaction(response_json);
165
- } else {
166
- this.handleDeclinedTransaction();
167
- return response_json
168
- }
169
- }
170
-
171
- async verifyTransactionStatus() {
172
- const verifyUrl = this.getUrlWithExpiration();
173
- if (verifyUrl) {
174
- const url = `${this.baseUrl}${verifyUrl}`;
175
- try {
176
- const response = await fetch(url, {
177
- method: "GET",
178
- headers: {
179
- "Content-Type": "application/json",
180
- Authorization: `Token ${this.apiKey}`,
181
- },
182
- // body: JSON.stringify(data),
183
- });
184
- if (response.status !== 200) {
185
- console.error('La verificación de la transacción falló.');
186
- this.removeVerifyTransactionUrl();
187
- return response
188
- }
189
-
190
- return await this.handleTransactionResponse(response);
191
- } catch (error) {
192
- console.error('Error al verificar la transacción:', error);
193
- this.removeVerifyTransactionUrl();
194
- }
195
- } else {
196
- console.log('No verify_transaction_status_url found');
197
- }
198
- }
199
-
200
- setPayload = (payload) => {
201
- this.payload = payload
202
- }
203
- }
@@ -1,324 +0,0 @@
1
- import { ThreeDSHandler } from "./3dsHandler.js";
2
- import {
3
- createOrder,
4
- fetchBusiness,
5
- getOpenpayDeviceSessionID,
6
- registerOrFetchCustomer,
7
- } from "../data";
8
- import { TONDER_URL_BY_MODE } from "../shared/constants/tonderUrl";
9
- import { globalLoader } from "./globalLoader";
10
- import { createPayment, startCheckoutRouter } from "../data/checkoutApi";
11
- import { getBrowserInfo, injectMercadoPagoSecurity } from "../helpers/utils";
12
-
13
- export class BaseInlineCheckout {
14
- baseUrl = "";
15
- cartTotal = "0";
16
- secureToken = "";
17
- constructor({ mode = "stage", apiKey, returnUrl, callBack = () => {} }) {
18
- this.apiKeyTonder = apiKey;
19
- this.returnUrl = returnUrl;
20
- this.callBack = callBack;
21
- this.mode = mode;
22
- this.baseUrl = TONDER_URL_BY_MODE[this.mode] || TONDER_URL_BY_MODE["stage"];
23
- this.abortController = new AbortController();
24
- this.process3ds = new ThreeDSHandler({
25
- apiKey: apiKey,
26
- baseUrl: this.baseUrl,
27
- });
28
- }
29
-
30
- /**
31
- * The configureCheckout function allows you to set initial information, such as the customer's email, which is used to retrieve a list of saved cards.
32
- * @param {import("../../types").IConfigureCheckout} data - Configuration data including customer information and potentially other settings.
33
- * @returns {void}.
34
- * @public
35
- */
36
- configureCheckout(data) {
37
- if ("secureToken" in data) this.#handleSecureToken(data["secureToken"]);
38
- this.#setCheckoutData(data)
39
- }
40
-
41
- /**
42
- * Verifies the 3DS transaction status.
43
- * @returns {Promise<import("../../types").ITransaction | void>} The result of the 3DS verification and checkout resumption.
44
- * @public
45
- */
46
- async verify3dsTransaction() {
47
- globalLoader.show();
48
- const result3ds = await this.process3ds.verifyTransactionStatus();
49
- const resultCheckout = await this.#resumeCheckout(result3ds);
50
- this.process3ds.setPayload(resultCheckout);
51
- const response = await this.#handle3dsRedirect(resultCheckout);
52
- globalLoader.remove();
53
- return response
54
- }
55
-
56
- /**
57
- * Processes a payment.
58
- * @param {import("../../types").IProcessPaymentRequest} data - Payment data including customer, cart, and other relevant information.
59
- * @returns {Promise<import("../../types").IStartCheckoutResponse>} A promise that resolves with the payment response or 3DS redirect or is rejected with an error.
60
- *
61
- * @throws {Error} Throws an error if the checkout process fails. The error object contains
62
- * additional `details` property with the response from the server if available.
63
- * @property {import("../../types").IStartCheckoutErrorResponse} error.details - The response body from the server when an error occurs.
64
- *
65
- * @public
66
- */
67
- payment(data) {
68
- return new Promise(async (resolve, reject) => {
69
- try {
70
- this.#setCheckoutData(data)
71
- const response = await this._checkout(data);
72
- this.process3ds.setPayload(response);
73
- this.callBack(response);
74
- const payload = await this.#handle3dsRedirect(response);
75
- if (payload) {
76
- resolve(response);
77
- }
78
- } catch (error) {
79
- reject(error);
80
- }
81
- });
82
- }
83
-
84
- async _initializeCheckout() {
85
- const { mercado_pago } = await this.#fetchMerchantData();
86
-
87
- if (!!mercado_pago && !!mercado_pago.active) {
88
- injectMercadoPagoSecurity();
89
- }
90
- }
91
-
92
- async _getCustomer(customer, signal) {
93
- return await registerOrFetchCustomer(
94
- this.baseUrl,
95
- this.apiKeyTonder,
96
- customer,
97
- signal,
98
- );
99
- }
100
-
101
- async _checkout() {
102
- throw new Error(
103
- "The #checkout method should be implement in child classes.",
104
- );
105
- }
106
-
107
- _setCartTotal(total) {
108
- throw new Error(
109
- "The #setCartTotal method should be implement in child classes.",
110
- );
111
- }
112
-
113
- async _handleCheckout({ card, payment_method, customer }) {
114
- const { openpay_keys, reference, business } = this.merchantData;
115
- const total = Number(this.cartTotal);
116
- try {
117
- let deviceSessionIdTonder;
118
- if (
119
- !deviceSessionIdTonder &&
120
- openpay_keys.merchant_id &&
121
- openpay_keys.public_key
122
- ) {
123
- deviceSessionIdTonder = await getOpenpayDeviceSessionID(
124
- openpay_keys.merchant_id,
125
- openpay_keys.public_key,
126
- this.abortController.signal,
127
- );
128
- }
129
-
130
- const { id, auth_token } = customer;
131
-
132
- const orderItems = {
133
- business: this.apiKeyTonder,
134
- client: auth_token,
135
- billing_address_id: null,
136
- shipping_address_id: null,
137
- amount: total,
138
- status: "A",
139
- reference: reference,
140
- is_oneclick: true,
141
- items: this.cartItems,
142
- };
143
- const jsonResponseOrder = await createOrder(
144
- this.baseUrl,
145
- this.apiKeyTonder,
146
- orderItems,
147
- );
148
-
149
- // Create payment
150
- const now = new Date();
151
- const dateString = now.toISOString();
152
-
153
- const paymentItems = {
154
- business_pk: business.pk,
155
- client_id: id,
156
- amount: total,
157
- date: dateString,
158
- order_id: jsonResponseOrder.id,
159
- customer_order_reference: this.order_reference ? this.order_reference : reference,
160
- };
161
- const jsonResponsePayment = await createPayment(
162
- this.baseUrl,
163
- this.apiKeyTonder,
164
- paymentItems,
165
- );
166
-
167
- // Checkout router
168
- const routerItems = {
169
- name: this.firstName || "",
170
- last_name: this.lastName || "",
171
- email_client: this.email,
172
- phone_number: this.phone,
173
- return_url: this.returnUrl,
174
- id_product: "no_id",
175
- quantity_product: 1,
176
- id_ship: "0",
177
- instance_id_ship: "0",
178
- amount: total,
179
- title_ship: "shipping",
180
- description: "transaction",
181
- device_session_id: deviceSessionIdTonder ? deviceSessionIdTonder : null,
182
- token_id: "",
183
- order_id: jsonResponseOrder.id,
184
- business_id: business.pk,
185
- payment_id: jsonResponsePayment.pk,
186
- source: "sdk",
187
- metadata: this.metadata,
188
- browser_info: getBrowserInfo(),
189
- currency: this.currency,
190
- ...(!!payment_method ? { payment_method } : { card }),
191
- ...(typeof MP_DEVICE_SESSION_ID !== "undefined"
192
- ? { mp_device_session_id: MP_DEVICE_SESSION_ID }
193
- : {}),
194
- };
195
-
196
- const jsonResponseRouter = await startCheckoutRouter(
197
- this.baseUrl,
198
- this.apiKeyTonder,
199
- routerItems,
200
- );
201
-
202
- if (jsonResponseRouter) {
203
- return jsonResponseRouter;
204
- } else {
205
- return false;
206
- }
207
- } catch (error) {
208
- console.log(error);
209
- throw error;
210
- }
211
- }
212
-
213
- #setCheckoutData(data){
214
- if(!data) return;
215
- this.#handleCustomer(data.customer);
216
- this._setCartTotal(data.cart?.total);
217
- this.#setCartItems(data.cart?.items);
218
- this.#handleMetadata(data);
219
- this.#handleCurrency(data);
220
- this.#handleCard(data);
221
- }
222
-
223
- async #fetchMerchantData() {
224
- this.merchantData = await fetchBusiness(
225
- this.baseUrl,
226
- this.apiKeyTonder,
227
- this.abortController.signal,
228
- );
229
- return this.merchantData;
230
- }
231
-
232
- async #resumeCheckout(response) {
233
- // Stop the routing process if the transaction is either hard declined or successful
234
- if (response?.decline?.error_type === "Hard" || !!response?.checkout?.is_route_finished) {
235
- return response;
236
- }
237
-
238
- if (["Success", "Authorized"].includes(response?.transaction_status)) {
239
- return response;
240
- }
241
-
242
- if (response) {
243
- globalLoader.show();
244
- const routerItems = {
245
- checkout_id: response?.checkout?.id,
246
- };
247
- try {
248
- return await startCheckoutRouter(
249
- this.baseUrl,
250
- this.apiKeyTonder,
251
- routerItems,
252
- );
253
- } catch (error) {
254
- // throw error
255
- } finally {
256
- globalLoader.remove();
257
- }
258
- return response;
259
- }
260
- }
261
-
262
- #handleCustomer(customer) {
263
- if (!customer) return;
264
-
265
- this.firstName = customer?.firstName;
266
- this.lastName = customer?.lastName;
267
- this.country = customer?.country;
268
- this.address = customer?.street;
269
- this.city = customer?.city;
270
- this.state = customer?.state;
271
- this.postCode = customer?.postCode;
272
- this.email = customer?.email;
273
- this.phone = customer?.phone;
274
- this.customer = customer;
275
- }
276
-
277
- #handleSecureToken(secureToken) {
278
- this.secureToken = secureToken;
279
- }
280
-
281
- #handleMetadata(data) {
282
- this.metadata = data?.metadata;
283
- this.order_reference = data?.order_reference;
284
- }
285
-
286
- #handleCurrency(data) {
287
- this.currency = data?.currency;
288
- }
289
-
290
- #handleCard(data) {
291
- this.card = data?.card;
292
- }
293
-
294
- #setCartItems(items) {
295
- this.cartItems = items;
296
- }
297
-
298
- async #handle3dsRedirect(response) {
299
- console.log('Handling 3DS redirect...');
300
- const iframe = response?.next_action?.iframe_resources?.iframe;
301
- const threeDsChallenge = response?.next_action?.three_ds_challenge;
302
-
303
- if (iframe) {
304
- try {
305
- await this.process3ds.loadIframe();
306
- const res = await this.process3ds.verifyTransactionStatus();
307
- return res;
308
- } catch (error) {
309
- console.log("Error loading iframe:", error);
310
- }
311
- } else if (threeDsChallenge) {
312
- await this.process3ds.handle3dsChallenge(threeDsChallenge);
313
- const res = await this.process3ds.verifyTransactionStatus();
314
- return res;
315
- } else {
316
- const redirectUrl = this.process3ds.getRedirectUrl();
317
- if (redirectUrl) {
318
- this.process3ds.redirectToChallenge();
319
- } else {
320
- return response;
321
- }
322
- }
323
- }
324
- }