tonder-web-sdk 1.16.3 → 1.16.6-beta.DEV-1433.2

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