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.
- package/README.md +134 -40
- package/package.json +29 -6
- package/types/card.d.ts +17 -17
- package/types/checkout.d.ts +85 -87
- package/types/common.d.ts +8 -2
- package/types/customer.d.ts +10 -10
- package/types/index.d.ts +9 -11
- package/types/inlineCheckout.d.ts +81 -61
- package/types/liteInlineCheckout.d.ts +78 -83
- package/types/paymentMethod.d.ts +17 -17
- package/types/transaction.d.ts +94 -94
- package/v1/bundle.min.js +1 -18
- package/.env-example +0 -1
- package/cypress/e2e/1-getting-started/todo.cy.js +0 -143
- package/cypress/e2e/2-advanced-examples/actions.cy.js +0 -299
- package/cypress/e2e/2-advanced-examples/aliasing.cy.js +0 -39
- package/cypress/e2e/2-advanced-examples/assertions.cy.js +0 -176
- package/cypress/e2e/2-advanced-examples/connectors.cy.js +0 -98
- package/cypress/e2e/2-advanced-examples/cookies.cy.js +0 -118
- package/cypress/e2e/2-advanced-examples/cypress_api.cy.js +0 -185
- package/cypress/e2e/2-advanced-examples/files.cy.js +0 -85
- package/cypress/e2e/2-advanced-examples/location.cy.js +0 -32
- package/cypress/e2e/2-advanced-examples/misc.cy.js +0 -104
- package/cypress/e2e/2-advanced-examples/navigation.cy.js +0 -56
- package/cypress/e2e/2-advanced-examples/network_requests.cy.js +0 -163
- package/cypress/e2e/2-advanced-examples/querying.cy.js +0 -114
- package/cypress/e2e/2-advanced-examples/spies_stubs_clocks.cy.js +0 -201
- package/cypress/e2e/2-advanced-examples/storage.cy.js +0 -110
- package/cypress/e2e/2-advanced-examples/traversal.cy.js +0 -121
- package/cypress/e2e/2-advanced-examples/utilities.cy.js +0 -108
- package/cypress/e2e/2-advanced-examples/viewport.cy.js +0 -58
- package/cypress/e2e/2-advanced-examples/waiting.cy.js +0 -30
- package/cypress/e2e/2-advanced-examples/window.cy.js +0 -22
- package/cypress/fixtures/example.json +0 -5
- package/cypress/support/commands.js +0 -25
- package/cypress/support/e2e.js +0 -20
- package/cypress.config.js +0 -9
- package/index.js.example +0 -50
- package/samples/react/README.md +0 -70
- package/samples/react/build/asset-manifest.json +0 -16
- package/samples/react/build/favicon.ico +0 -0
- package/samples/react/build/index.html +0 -1
- package/samples/react/build/logo192.png +0 -0
- package/samples/react/build/logo512.png +0 -0
- package/samples/react/build/manifest.json +0 -25
- package/samples/react/build/robots.txt +0 -3
- package/samples/react/build/static/css/main.073c9b0a.css +0 -2
- package/samples/react/build/static/css/main.073c9b0a.css.map +0 -1
- package/samples/react/build/static/js/787.b83ed06f.chunk.js +0 -2
- package/samples/react/build/static/js/787.b83ed06f.chunk.js.map +0 -1
- package/samples/react/build/static/js/main.0a848807.js +0 -3
- package/samples/react/build/static/js/main.0a848807.js.LICENSE.txt +0 -39
- package/samples/react/build/static/js/main.0a848807.js.map +0 -1
- package/samples/react/build/static/media/sdk-icons.b491623214b2af4cccdb.png +0 -0
- package/samples/react/package-lock.json +0 -28973
- package/samples/react/package.json +0 -44
- package/samples/react/public/favicon.ico +0 -0
- package/samples/react/public/index.html +0 -43
- package/samples/react/public/logo192.png +0 -0
- package/samples/react/public/logo512.png +0 -0
- package/samples/react/public/manifest.json +0 -25
- package/samples/react/public/robots.txt +0 -3
- package/samples/react/src/App.css +0 -38
- package/samples/react/src/App.js +0 -22
- package/samples/react/src/App.test.js +0 -8
- package/samples/react/src/assets/img/sdk-icons.png +0 -0
- package/samples/react/src/components/Cart.js +0 -29
- package/samples/react/src/components/ProductCard.js +0 -27
- package/samples/react/src/context/CartContext.js +0 -116
- package/samples/react/src/index.css +0 -13
- package/samples/react/src/index.js +0 -17
- package/samples/react/src/logo.svg +0 -1
- package/samples/react/src/reportWebVitals.js +0 -13
- package/samples/react/src/screens/Checkout.js +0 -82
- package/samples/react/src/screens/Store.js +0 -21
- package/samples/react/src/setupTests.js +0 -5
- package/samples/react/src/storeProducts.js +0 -30
- package/src/classes/3dsHandler.js +0 -203
- package/src/classes/BaseInlineCheckout.js +0 -324
- package/src/classes/LiteInlineCheckout.js +0 -220
- package/src/classes/checkout.js +0 -125
- package/src/classes/globalLoader.js +0 -29
- package/src/classes/inlineCheckout.js +0 -515
- package/src/data/apmApi.js +0 -44
- package/src/data/businessApi.js +0 -19
- package/src/data/cardApi.js +0 -143
- package/src/data/checkoutApi.js +0 -92
- package/src/data/customerApi.js +0 -37
- package/src/data/index.js +0 -17
- package/src/data/openPayApi.js +0 -16
- package/src/data/skyflowApi.js +0 -18
- package/src/helpers/skyflow.js +0 -361
- package/src/helpers/styles.js +0 -61
- package/src/helpers/template-skeleton.js +0 -59
- package/src/helpers/template.js +0 -743
- package/src/helpers/utils.js +0 -163
- package/src/helpers/validations.js +0 -54
- package/src/index-dev.js +0 -307
- package/src/index.html +0 -172
- package/src/index.js +0 -15
- package/src/shared/catalog/paymentMethodsCatalog.js +0 -247
- package/src/shared/constants/messages.js +0 -10
- package/src/shared/constants/paymentMethodAPM.js +0 -63
- package/src/shared/constants/tonderUrl.js +0 -8
- package/webpack.config.js +0 -77
|
@@ -1,515 +0,0 @@
|
|
|
1
|
-
import { apmItemsTemplate, cardItemsTemplate, cardTemplate } from '../helpers/template.js'
|
|
2
|
-
import {
|
|
3
|
-
clearSpace,
|
|
4
|
-
injectMercadoPagoSecurity,
|
|
5
|
-
mapCards,
|
|
6
|
-
showError,
|
|
7
|
-
showMessage
|
|
8
|
-
} from '../helpers/utils';
|
|
9
|
-
import { initSkyflow, initUpdateSkyflow } from '../helpers/skyflow'
|
|
10
|
-
import { globalLoader } from './globalLoader.js';
|
|
11
|
-
import { BaseInlineCheckout } from "./BaseInlineCheckout";
|
|
12
|
-
import {
|
|
13
|
-
fetchCustomerCards,
|
|
14
|
-
removeCustomerCard,
|
|
15
|
-
saveCustomerCard,
|
|
16
|
-
fetchCustomerAPMs
|
|
17
|
-
} from "../data";
|
|
18
|
-
import { MESSAGES } from "../shared/constants/messages";
|
|
19
|
-
import Accordion from "accordion-js";
|
|
20
|
-
|
|
21
|
-
export class InlineCheckout extends BaseInlineCheckout {
|
|
22
|
-
static injected = false;
|
|
23
|
-
static cardsInjected = false
|
|
24
|
-
static apmsInjected = false
|
|
25
|
-
static apmsData = [];
|
|
26
|
-
accordionC = null;
|
|
27
|
-
|
|
28
|
-
deletingCards = [];
|
|
29
|
-
customer = {}
|
|
30
|
-
items = []
|
|
31
|
-
collectContainer = null
|
|
32
|
-
updateCollectContainer = null
|
|
33
|
-
merchantData = {}
|
|
34
|
-
cartTotal = null
|
|
35
|
-
metadata = {}
|
|
36
|
-
card = {}
|
|
37
|
-
collectorIds = {
|
|
38
|
-
cardsListContainer: "cardsListContainer",
|
|
39
|
-
holderName: "collectCardholderName",
|
|
40
|
-
cardNumber: "collectCardNumber",
|
|
41
|
-
expirationMonth: "collectExpirationMonth",
|
|
42
|
-
expirationYear: "collectExpirationYear",
|
|
43
|
-
cvv: "collectCvv",
|
|
44
|
-
tonderPayButton: "tonderPayButton",
|
|
45
|
-
msgError: "msgError",
|
|
46
|
-
msgNotification: "msgNotification",
|
|
47
|
-
apmsListContainer: "apmsListContainer"
|
|
48
|
-
}
|
|
49
|
-
customization = {
|
|
50
|
-
saveCards: {
|
|
51
|
-
showSaveCardOption: false,
|
|
52
|
-
showSaved: false,
|
|
53
|
-
autoSave: false
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
constructor({
|
|
57
|
-
mode = "stage",
|
|
58
|
-
apiKey,
|
|
59
|
-
returnUrl,
|
|
60
|
-
renderPaymentButton = false,
|
|
61
|
-
callBack = () => { },
|
|
62
|
-
styles,
|
|
63
|
-
customization,
|
|
64
|
-
}) {
|
|
65
|
-
super({ mode, apiKey, returnUrl, callBack });
|
|
66
|
-
this.renderPaymentButton = renderPaymentButton;
|
|
67
|
-
this.customStyles = styles
|
|
68
|
-
this.abortRefreshCardsController = new AbortController();
|
|
69
|
-
// TODO: Wait until SaveCards is ready (server token).
|
|
70
|
-
this.customization = {
|
|
71
|
-
...this.customization,
|
|
72
|
-
...(customization || {}),
|
|
73
|
-
saveCards: {
|
|
74
|
-
...this.customization.saveCards,
|
|
75
|
-
...(customization?.saveCards || {}),
|
|
76
|
-
},
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
#mountPayButton(cardId="") {
|
|
81
|
-
if (!this.renderPaymentButton) return;
|
|
82
|
-
|
|
83
|
-
const btnID = `#tonderPayButton${cardId}`;
|
|
84
|
-
const payButton = document.querySelector(btnID);
|
|
85
|
-
const containerID = `#acContainer${cardId}`;
|
|
86
|
-
const container = document.querySelector(containerID);
|
|
87
|
-
|
|
88
|
-
if (!payButton) {
|
|
89
|
-
console.error("Pay button not found");
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (cardId !== "") {
|
|
94
|
-
const sdkPayButton = document.querySelector(`#tonderPayButton`);
|
|
95
|
-
if(sdkPayButton){
|
|
96
|
-
sdkPayButton.style.display = "none";
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
payButton.style.display = "block";
|
|
101
|
-
payButton.textContent = `Pagar $${this.cartTotal}`;
|
|
102
|
-
document.querySelectorAll(".ac-card-panel-container").forEach((cont) => {
|
|
103
|
-
cont.classList.remove("show");
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
if (container) {
|
|
107
|
-
container.classList.add("show");
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
payButton.onclick = async (event) => {
|
|
111
|
-
event.preventDefault();
|
|
112
|
-
await this.#handlePaymentClick(payButton);
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async #handlePaymentClick(payButton) {
|
|
117
|
-
const prevButtonContent = payButton.innerHTML;
|
|
118
|
-
payButton.innerHTML = `<div class="lds-dual-ring"></div>`;
|
|
119
|
-
try {
|
|
120
|
-
const response = await this.payment();
|
|
121
|
-
this.callBack(response);
|
|
122
|
-
} catch (error) {
|
|
123
|
-
console.error("Payment error:", error);
|
|
124
|
-
} finally {
|
|
125
|
-
payButton.innerHTML = prevButtonContent;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
_setCartTotal(total) {
|
|
130
|
-
this.cartTotal = total
|
|
131
|
-
this.#updatePayButton()
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
#updatePayButton() {
|
|
135
|
-
const payButton = document.querySelector("#tonderPayButton");
|
|
136
|
-
if (!payButton) return
|
|
137
|
-
payButton.textContent = `Pagar $${this.cartTotal}`;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
setCallback(cb) {
|
|
141
|
-
this.cb = cb
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Injects the checkout into the DOM and initializes it.
|
|
146
|
-
* Checks for an existing container and sets up an observer if needed.
|
|
147
|
-
* @returns {void}
|
|
148
|
-
* @public
|
|
149
|
-
*/
|
|
150
|
-
async injectCheckout() {
|
|
151
|
-
if (InlineCheckout.injected) return
|
|
152
|
-
const containerTonderCheckout = document.querySelector("#tonder-checkout");
|
|
153
|
-
if (containerTonderCheckout) {
|
|
154
|
-
await this.#mount(containerTonderCheckout)
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
const observer = new MutationObserver(async (mutations, obs) => {
|
|
158
|
-
const containerTonderCheckout = document.querySelector("#tonder-checkout");
|
|
159
|
-
if (containerTonderCheckout) {
|
|
160
|
-
await this.#mount(containerTonderCheckout)
|
|
161
|
-
obs.disconnect();
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
observer.observe(document.body, {
|
|
165
|
-
childList: true,
|
|
166
|
-
subtree: true,
|
|
167
|
-
attributeFilter: ['id']
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
async #mount(containerTonderCheckout) {
|
|
172
|
-
containerTonderCheckout.innerHTML = cardTemplate({ renderPaymentButton: this.renderPaymentButton, customStyles: this.customStyles, customization: this.customization });
|
|
173
|
-
globalLoader.show()
|
|
174
|
-
await this.#mountTonder();
|
|
175
|
-
InlineCheckout.injected = true;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
async #mountAPMs() {
|
|
179
|
-
try {
|
|
180
|
-
const apms = await fetchCustomerAPMs(this.baseUrl, this.apiKeyTonder);
|
|
181
|
-
if (apms && apms['results'] && apms['results'].length > 0) {
|
|
182
|
-
this.apmsData = apms['results']
|
|
183
|
-
this.#loadAPMList(apms['results'])
|
|
184
|
-
}
|
|
185
|
-
} catch (e) {
|
|
186
|
-
console.warn("Error getting APMS")
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
async #mountTonder(getCards = true) {
|
|
191
|
-
this.#mountPayButton()
|
|
192
|
-
await this._initializeCheckout()
|
|
193
|
-
try {
|
|
194
|
-
const {
|
|
195
|
-
vault_id,
|
|
196
|
-
vault_url
|
|
197
|
-
} = this.merchantData;
|
|
198
|
-
if (this.email && getCards) {
|
|
199
|
-
const customerResponse = await this._getCustomer({ email: this.email });
|
|
200
|
-
if ("auth_token" in customerResponse) {
|
|
201
|
-
const { auth_token } = customerResponse
|
|
202
|
-
await this.#loadCardsList(auth_token)
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
await this.#mountAPMs();
|
|
207
|
-
|
|
208
|
-
this.collectContainer = await initSkyflow(
|
|
209
|
-
vault_id,
|
|
210
|
-
vault_url,
|
|
211
|
-
this.baseUrl,
|
|
212
|
-
this.apiKeyTonder,
|
|
213
|
-
this.abortController.signal,
|
|
214
|
-
this.customStyles,
|
|
215
|
-
this.collectorIds
|
|
216
|
-
);
|
|
217
|
-
setTimeout(() => {
|
|
218
|
-
globalLoader.remove()
|
|
219
|
-
}, 800)
|
|
220
|
-
} catch (e) {
|
|
221
|
-
if (e && e.name !== 'AbortError') {
|
|
222
|
-
globalLoader.remove()
|
|
223
|
-
showError("No se pudieron cargar los datos del comercio.")
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Removes the checkout from the DOM and cleans up associated resources.
|
|
230
|
-
*
|
|
231
|
-
* This method performs the following actions:
|
|
232
|
-
* 1. Resets the injection status flags for the checkout, cards, and APMs.
|
|
233
|
-
* 2. Aborts any ongoing requests using the AbortController.
|
|
234
|
-
* 3. Creates a new AbortController for future use.
|
|
235
|
-
* 4. Clears any existing injection intervals.
|
|
236
|
-
*
|
|
237
|
-
* Note: This method should be called when you want to completely remove
|
|
238
|
-
* the checkout from the page and reset its state.
|
|
239
|
-
*
|
|
240
|
-
* @returns {void}
|
|
241
|
-
* @public
|
|
242
|
-
*/
|
|
243
|
-
removeCheckout() {
|
|
244
|
-
InlineCheckout.injected = false
|
|
245
|
-
InlineCheckout.cardsInjected = false
|
|
246
|
-
InlineCheckout.apmsInjected = false
|
|
247
|
-
// Cancel all requests
|
|
248
|
-
this.abortController.abort();
|
|
249
|
-
this.abortController = new AbortController();
|
|
250
|
-
|
|
251
|
-
clearInterval(this.injectInterval);
|
|
252
|
-
console.log("InlineCheckout removed from DOM and cleaned up.");
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
async #getCardTokens(cardSelected) {
|
|
256
|
-
if (this.card?.skyflow_id) return this.card
|
|
257
|
-
try {
|
|
258
|
-
const collectResponse = cardSelected && cardSelected !== "new" ? await this.updateCollectContainer.container.collect():await this.collectContainer.container.collect();
|
|
259
|
-
const cardTokens = await collectResponse["records"][0]["fields"];
|
|
260
|
-
return cardTokens;
|
|
261
|
-
} catch (error) {
|
|
262
|
-
showError("Por favor, verifica todos los campos de tu tarjeta")
|
|
263
|
-
throw error;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
async _checkout() {
|
|
268
|
-
try {
|
|
269
|
-
document.querySelector("#tonderPayButton").disabled = true;
|
|
270
|
-
} catch (error) {
|
|
271
|
-
}
|
|
272
|
-
const { business } = this.merchantData
|
|
273
|
-
let cardTokens;
|
|
274
|
-
|
|
275
|
-
if (this.radioChecked === "new" || this.radioChecked === undefined) {
|
|
276
|
-
cardTokens = await this.#getCardTokens(this.radioChecked);
|
|
277
|
-
} else {
|
|
278
|
-
await this.#getCardTokens(this.radioChecked);
|
|
279
|
-
cardTokens = {
|
|
280
|
-
skyflow_id: this.radioChecked
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
try {
|
|
284
|
-
const customerData = await this._getCustomer(
|
|
285
|
-
this.customer,
|
|
286
|
-
this.abortController.signal
|
|
287
|
-
)
|
|
288
|
-
const { auth_token } = customerData;
|
|
289
|
-
if (auth_token && this.email) {
|
|
290
|
-
await this.#handleSaveCard(auth_token, business.pk, cardTokens)
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
const selected_apm = this.apmsData ? this.apmsData.find((iapm) => iapm.pk === this.radioChecked) : {};
|
|
294
|
-
|
|
295
|
-
const jsonResponseRouter = await this._handleCheckout({
|
|
296
|
-
...(selected_apm && Object.keys(selected_apm).length > 0
|
|
297
|
-
? { payment_method: selected_apm.payment_method }
|
|
298
|
-
: { card: cardTokens }),
|
|
299
|
-
customer: customerData
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
if (jsonResponseRouter) {
|
|
303
|
-
try {
|
|
304
|
-
document.querySelector("#tonderPayButton").disabled = false;
|
|
305
|
-
} catch { }
|
|
306
|
-
return jsonResponseRouter;
|
|
307
|
-
} else {
|
|
308
|
-
showError("No se ha podido procesar el pago")
|
|
309
|
-
return false;
|
|
310
|
-
}
|
|
311
|
-
} catch (error) {
|
|
312
|
-
console.log(error);
|
|
313
|
-
showError("Ha ocurrido un error")
|
|
314
|
-
throw error;
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
async #handleSaveCard(auth_token, businessId, cardTokens) {
|
|
319
|
-
const saveCard = document.getElementById("save-checkout-card");
|
|
320
|
-
if ((saveCard && "checked" in saveCard && saveCard.checked) || !!this.customization.saveCards?.autoSave) {
|
|
321
|
-
try {
|
|
322
|
-
await saveCustomerCard(
|
|
323
|
-
this.baseUrl,
|
|
324
|
-
auth_token,
|
|
325
|
-
this.secureToken,
|
|
326
|
-
businessId,
|
|
327
|
-
{ skyflow_id: cardTokens.skyflow_id, }
|
|
328
|
-
);
|
|
329
|
-
showMessage(MESSAGES.cardSaved, this.collectorIds.msgNotification);
|
|
330
|
-
} catch (error) {
|
|
331
|
-
if (error?.message) {
|
|
332
|
-
showError(error.message)
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
await this.#loadCardsList(auth_token)
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
async #loadCardsList(token) {
|
|
340
|
-
if(this.cardsInjected || !this.customization.saveCards?.showSaved) return;
|
|
341
|
-
this.cardsInjected = false
|
|
342
|
-
const cardsResponse = await fetchCustomerCards(
|
|
343
|
-
this.baseUrl,
|
|
344
|
-
token,
|
|
345
|
-
this.secureToken,
|
|
346
|
-
this.merchantData.business.pk,
|
|
347
|
-
);
|
|
348
|
-
let cards = []
|
|
349
|
-
if("cards" in cardsResponse) {
|
|
350
|
-
cards = cardsResponse.cards.map(mapCards)
|
|
351
|
-
const injectInterval = setInterval(() => {
|
|
352
|
-
const queryElement = document.querySelector(`#${this.collectorIds.cardsListContainer}`);
|
|
353
|
-
if (queryElement && InlineCheckout.injected) {
|
|
354
|
-
queryElement.innerHTML = cardItemsTemplate(cards, {renderPaymentButton: this.renderPaymentButton})
|
|
355
|
-
clearInterval(injectInterval)
|
|
356
|
-
this.#generateCardsAccordion()
|
|
357
|
-
this.#mountRadioButtons(token)
|
|
358
|
-
this.cardsInjected = true
|
|
359
|
-
}
|
|
360
|
-
}, 500);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
#generateCardsAccordion(){
|
|
365
|
-
this.accordionC = new Accordion(".accordion-container", {
|
|
366
|
-
triggerClass: "card-item-label",
|
|
367
|
-
duration: 300,
|
|
368
|
-
collapse: true,
|
|
369
|
-
showMultiple: false,
|
|
370
|
-
onOpen: async (currentElement) => {
|
|
371
|
-
await this.#handleOpenCardAccordion(currentElement)
|
|
372
|
-
}
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
async #handleOpenCardAccordion(currentElement){
|
|
377
|
-
const { vault_id, vault_url } = this.merchantData;
|
|
378
|
-
const container_radio_id = currentElement.id.replace("card_container-", "");
|
|
379
|
-
|
|
380
|
-
if (this.updateCollectContainer && "unmount" in this.updateCollectContainer?.elements?.cvvElement) {
|
|
381
|
-
await this.updateCollectContainer.elements.cvvElement.unmount()
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
document.querySelectorAll(".cvvContainer").forEach((container) => {
|
|
385
|
-
container.classList.remove("show");
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
const radio_card = document.getElementById(container_radio_id);
|
|
389
|
-
radio_card.checked = true;
|
|
390
|
-
|
|
391
|
-
try{
|
|
392
|
-
this.updateCollectContainer = await initUpdateSkyflow(
|
|
393
|
-
container_radio_id,
|
|
394
|
-
vault_id,
|
|
395
|
-
vault_url,
|
|
396
|
-
this.baseUrl,
|
|
397
|
-
this.apiKeyTonder,
|
|
398
|
-
this.abortController.signal,
|
|
399
|
-
this.customStyles
|
|
400
|
-
);
|
|
401
|
-
setTimeout(() => {
|
|
402
|
-
document.querySelector(`#cvvContainer${container_radio_id}`).classList.add("show");
|
|
403
|
-
}, 5)
|
|
404
|
-
this.#mountPayButton(container_radio_id)
|
|
405
|
-
}catch (e){
|
|
406
|
-
console.error("Ha ocurrido un error", e);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
this.#handleRadioButtonClick(radio_card)
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
#loadAPMList(apms) {
|
|
413
|
-
if (this.apmsInjected) return;
|
|
414
|
-
const injectInterval = setInterval(() => {
|
|
415
|
-
const queryElement = document.querySelector(`#${this.collectorIds.apmsListContainer}`);
|
|
416
|
-
if (queryElement && InlineCheckout.injected) {
|
|
417
|
-
const filteredAndSortedApms = apms
|
|
418
|
-
.filter((apm) =>
|
|
419
|
-
clearSpace(apm.category.toLowerCase()) !== 'cards' && apm.status.toLowerCase() === 'active')
|
|
420
|
-
.sort((a, b) => a.priority - b.priority);
|
|
421
|
-
|
|
422
|
-
queryElement.innerHTML = apmItemsTemplate(filteredAndSortedApms);
|
|
423
|
-
clearInterval(injectInterval);
|
|
424
|
-
this.#mountRadioButtons();
|
|
425
|
-
this.apmsInjected = true;
|
|
426
|
-
}
|
|
427
|
-
}, 500);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
#mountRadioButtons(token = '') {
|
|
431
|
-
const radioButtons = document.getElementsByName(`card_selected`);
|
|
432
|
-
for (const radio of radioButtons) {
|
|
433
|
-
radio.style.display = "block";
|
|
434
|
-
radio.onclick = async (event) => {
|
|
435
|
-
const position = Array.from(radioButtons).indexOf(radio);
|
|
436
|
-
await this.#handleRadioButtonClick(radio, position);
|
|
437
|
-
};
|
|
438
|
-
}
|
|
439
|
-
const cardsButtons = document.getElementsByClassName("card-delete-button");
|
|
440
|
-
for (const cardButton of cardsButtons) {
|
|
441
|
-
cardButton.addEventListener("click", (event) => {
|
|
442
|
-
event.preventDefault();
|
|
443
|
-
event.stopImmediatePropagation();
|
|
444
|
-
this.#handleDeleteCardButtonClick(token, cardButton)
|
|
445
|
-
}, false);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
async #handleRadioButtonClick(radio, position = null) {
|
|
450
|
-
if (radio.id === this.radioChecked || (radio.id === "new" && this.radioChecked === undefined)) return;
|
|
451
|
-
const containerForm = document.querySelector(".container-form");
|
|
452
|
-
if (containerForm) {
|
|
453
|
-
containerForm.style.display = radio.id === "new" ? "block" : "none";
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
if (radio.id === "new") {
|
|
457
|
-
this.accordionC.closeAll()
|
|
458
|
-
if (this.radioChecked !== radio.id) {
|
|
459
|
-
globalLoader.show()
|
|
460
|
-
this.#mountTonder(false);
|
|
461
|
-
InlineCheckout.injected = true;
|
|
462
|
-
}
|
|
463
|
-
} else {
|
|
464
|
-
if (position !== null) {
|
|
465
|
-
this.accordionC.closeAll()
|
|
466
|
-
this.accordionC.open(position)
|
|
467
|
-
}
|
|
468
|
-
this.#unmountForm();
|
|
469
|
-
}
|
|
470
|
-
this.radioChecked = radio.id;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
async #handleDeleteCardButtonClick(customerToken, button) {
|
|
474
|
-
const id = button.attributes.getNamedItem("id")
|
|
475
|
-
const skyflow_id = id?.value?.split("_")?.[2]
|
|
476
|
-
if (skyflow_id) {
|
|
477
|
-
const cardClicked = document.querySelector(`#card_container-${skyflow_id}`);
|
|
478
|
-
if (cardClicked) {
|
|
479
|
-
cardClicked.style.display = "none"
|
|
480
|
-
}
|
|
481
|
-
try {
|
|
482
|
-
this.deletingCards.push(skyflow_id);
|
|
483
|
-
if (this.abortRefreshCardsController) {
|
|
484
|
-
this.abortRefreshCardsController.abort();
|
|
485
|
-
this.abortRefreshCardsController = new AbortController();
|
|
486
|
-
}
|
|
487
|
-
const businessId = this.merchantData.business.pk
|
|
488
|
-
await removeCustomerCard(
|
|
489
|
-
this.baseUrl,
|
|
490
|
-
customerToken,
|
|
491
|
-
this.secureToken,
|
|
492
|
-
skyflow_id,
|
|
493
|
-
businessId
|
|
494
|
-
)
|
|
495
|
-
} catch (error) { } finally {
|
|
496
|
-
this.deletingCards = this.deletingCards.filter(id => id !== skyflow_id);
|
|
497
|
-
this.#refreshCardOnDelete(customerToken)
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
async #refreshCardOnDelete(customerToken) {
|
|
502
|
-
if (this.deletingCards.length > 0) return;
|
|
503
|
-
await this.#loadCardsList(customerToken)
|
|
504
|
-
}
|
|
505
|
-
#unmountForm() {
|
|
506
|
-
InlineCheckout.injected = false
|
|
507
|
-
if (this.collectContainer) {
|
|
508
|
-
if ("unmount" in this.collectContainer.elements.cardHolderNameElement) this.collectContainer.elements.cardHolderNameElement.unmount()
|
|
509
|
-
if ("unmount" in this.collectContainer.elements.cardNumberElement) this.collectContainer.elements.cardNumberElement.unmount()
|
|
510
|
-
if ("unmount" in this.collectContainer.elements.expiryYearElement) this.collectContainer.elements.expiryYearElement.unmount()
|
|
511
|
-
if ("unmount" in this.collectContainer.elements.expiryMonthElement) this.collectContainer.elements.expiryMonthElement.unmount()
|
|
512
|
-
if ("unmount" in this.collectContainer.elements.cvvElement) this.collectContainer.elements.cvvElement.unmount()
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
}
|
package/src/data/apmApi.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildErrorResponse,
|
|
3
|
-
buildErrorResponseFromCatch,
|
|
4
|
-
} from "../helpers/utils";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Fetches Alternative Payment Methods (APMs) of a customer.
|
|
8
|
-
* @param {string} baseUrl - The base URL of the API.
|
|
9
|
-
* @param {string} apiKey - The API key for authentication.
|
|
10
|
-
* @param params - The query params to filter APMs
|
|
11
|
-
* @param {AbortSignal} signal - The abort signal to cancel the request.
|
|
12
|
-
* @returns {Promise<import("../../types").IPaymentMethodResponse>} The available APMs.
|
|
13
|
-
*/
|
|
14
|
-
export async function fetchCustomerAPMs(
|
|
15
|
-
baseUrl,
|
|
16
|
-
apiKey,
|
|
17
|
-
params = {
|
|
18
|
-
status: "active",
|
|
19
|
-
pagesize: "10000",
|
|
20
|
-
},
|
|
21
|
-
signal = null,
|
|
22
|
-
) {
|
|
23
|
-
try {
|
|
24
|
-
const queryString = new URLSearchParams(params).toString();
|
|
25
|
-
|
|
26
|
-
const response = await fetch(
|
|
27
|
-
`${baseUrl}/api/v1/payment_methods?${queryString}`,
|
|
28
|
-
{
|
|
29
|
-
method: "GET",
|
|
30
|
-
headers: {
|
|
31
|
-
Authorization: `Token ${apiKey}`,
|
|
32
|
-
"Content-Type": "application/json",
|
|
33
|
-
},
|
|
34
|
-
signal,
|
|
35
|
-
},
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
if (response.ok) return await response.json();
|
|
39
|
-
const res_json = await response.json();
|
|
40
|
-
throw await buildErrorResponse(response, res_json);
|
|
41
|
-
} catch (error) {
|
|
42
|
-
throw buildErrorResponseFromCatch(error);
|
|
43
|
-
}
|
|
44
|
-
}
|
package/src/data/businessApi.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fetches business information.
|
|
3
|
-
* @param {string} baseUrl - The base URL of the Tonder API.
|
|
4
|
-
* @param {string} apiKey - The API key for authentication.
|
|
5
|
-
* @param {AbortSignal} signal - The abort signal to cancel the request.
|
|
6
|
-
* @returns {Promise<Object>} The business information.
|
|
7
|
-
*/
|
|
8
|
-
export async function fetchBusiness(baseUrl, apiKey, signal) {
|
|
9
|
-
const getBusiness = await fetch(
|
|
10
|
-
`${baseUrl}/api/v1/payments/business/${apiKey}`,
|
|
11
|
-
{
|
|
12
|
-
headers: {
|
|
13
|
-
Authorization: `Token ${apiKey}`,
|
|
14
|
-
},
|
|
15
|
-
signal: signal,
|
|
16
|
-
},
|
|
17
|
-
);
|
|
18
|
-
return await getBusiness.json();
|
|
19
|
-
}
|