tonder-web-sdk 1.7.0 → 1.8.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/package.json +1 -1
- package/src/classes/inlineCheckout.js +143 -8
- package/src/data/api.js +63 -0
- package/src/helpers/skyflow.js +81 -8
- package/src/helpers/template.js +350 -7
- package/src/helpers/utils.js +71 -0
- package/src/index-dev.js +5 -5
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cardTemplate } from '../helpers/template.js'
|
|
1
|
+
import { cardItemsTemplate, cardTemplate } from '../helpers/template.js'
|
|
2
2
|
import { cardTemplateSkeleton } from '../helpers/template-skeleton.js'
|
|
3
3
|
import {
|
|
4
4
|
getBusiness,
|
|
@@ -6,11 +6,16 @@ import {
|
|
|
6
6
|
createOrder,
|
|
7
7
|
createPayment,
|
|
8
8
|
startCheckoutRouter,
|
|
9
|
-
getOpenpayDeviceSessionID
|
|
9
|
+
getOpenpayDeviceSessionID,
|
|
10
|
+
getCustomerCards,
|
|
11
|
+
registerCard,
|
|
12
|
+
deleteCustomerCard
|
|
10
13
|
} from '../data/api';
|
|
11
14
|
import {
|
|
12
15
|
showError,
|
|
13
16
|
getBrowserInfo,
|
|
17
|
+
mapCards,
|
|
18
|
+
showMessage,
|
|
14
19
|
} from '../helpers/utils';
|
|
15
20
|
import { initSkyflow } from '../helpers/skyflow'
|
|
16
21
|
import { ThreeDSHandler } from './3dsHandler.js';
|
|
@@ -18,6 +23,7 @@ import { ThreeDSHandler } from './3dsHandler.js';
|
|
|
18
23
|
|
|
19
24
|
export class InlineCheckout {
|
|
20
25
|
static injected = false;
|
|
26
|
+
static cardsInjected = false
|
|
21
27
|
customer = {}
|
|
22
28
|
items = []
|
|
23
29
|
baseUrl = null
|
|
@@ -26,6 +32,18 @@ export class InlineCheckout {
|
|
|
26
32
|
cartTotal = null
|
|
27
33
|
metadata = {}
|
|
28
34
|
card = {}
|
|
35
|
+
collectorIds = {
|
|
36
|
+
cardsListContainer: "cardsListContainer",
|
|
37
|
+
holderName: "collectCardholderName",
|
|
38
|
+
cardNumber: "collectCardNumber",
|
|
39
|
+
expirationMonth: "collectExpirationMonth",
|
|
40
|
+
expirationYear: "collectExpirationYear",
|
|
41
|
+
cvv: "collectCvv",
|
|
42
|
+
tonderPayButton: "tonderPayButton",
|
|
43
|
+
msgError: "msgError",
|
|
44
|
+
msgNotification: "msgNotification"
|
|
45
|
+
|
|
46
|
+
}
|
|
29
47
|
|
|
30
48
|
constructor({
|
|
31
49
|
mode = "stage",
|
|
@@ -34,7 +52,7 @@ export class InlineCheckout {
|
|
|
34
52
|
successUrl,
|
|
35
53
|
renderPaymentButton = false,
|
|
36
54
|
callBack = () => { },
|
|
37
|
-
styles
|
|
55
|
+
styles
|
|
38
56
|
}) {
|
|
39
57
|
this.apiKeyTonder = apiKey;
|
|
40
58
|
this.returnUrl = returnUrl;
|
|
@@ -172,6 +190,9 @@ export class InlineCheckout {
|
|
|
172
190
|
this.cartItems = items
|
|
173
191
|
}
|
|
174
192
|
|
|
193
|
+
setCustomerEmail (email) {
|
|
194
|
+
this.email = email
|
|
195
|
+
}
|
|
175
196
|
setCartTotal(total) {
|
|
176
197
|
console.log('total: ', total)
|
|
177
198
|
this.cartTotal = total
|
|
@@ -215,13 +236,14 @@ export class InlineCheckout {
|
|
|
215
236
|
let checkoutContainer = document.querySelector("#global-loader");
|
|
216
237
|
if (checkoutContainer) {
|
|
217
238
|
checkoutContainer.innerHTML = cardTemplateSkeleton;
|
|
239
|
+
checkoutContainer.style.display = 'block';
|
|
218
240
|
}
|
|
219
241
|
}
|
|
220
242
|
|
|
221
243
|
#removeGlobalLoader() {
|
|
222
244
|
const loader = document.querySelector('#global-loader');
|
|
223
245
|
if (loader) {
|
|
224
|
-
loader.
|
|
246
|
+
loader.style.display = 'none';
|
|
225
247
|
}
|
|
226
248
|
}
|
|
227
249
|
|
|
@@ -245,13 +267,25 @@ export class InlineCheckout {
|
|
|
245
267
|
return await customerRegister(this.baseUrl, this.apiKeyTonder, customer, signal);
|
|
246
268
|
}
|
|
247
269
|
|
|
248
|
-
async #mountTonder() {
|
|
270
|
+
async #mountTonder(getCards = true) {
|
|
249
271
|
this.#mountPayButton()
|
|
250
272
|
try{
|
|
251
273
|
const {
|
|
252
274
|
vault_id,
|
|
253
275
|
vault_url,
|
|
254
276
|
} = await this.#fetchMerchantData();
|
|
277
|
+
if(this.email && getCards){
|
|
278
|
+
const customerResponse = await this.getCustomer({email: this.email});
|
|
279
|
+
if("auth_token" in customerResponse) {
|
|
280
|
+
const { auth_token } = customerResponse
|
|
281
|
+
const cards = await getCustomerCards(this.baseUrl, auth_token);
|
|
282
|
+
|
|
283
|
+
if("cards" in cards) {
|
|
284
|
+
const cardsMapped = cards.cards.map(mapCards)
|
|
285
|
+
this.#loadCardsList(cardsMapped, auth_token)
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
255
289
|
|
|
256
290
|
this.collectContainer = await initSkyflow(
|
|
257
291
|
vault_id,
|
|
@@ -260,6 +294,7 @@ export class InlineCheckout {
|
|
|
260
294
|
this.apiKeyTonder,
|
|
261
295
|
this.abortController.signal,
|
|
262
296
|
this.customStyles,
|
|
297
|
+
this.collectorIds
|
|
263
298
|
);
|
|
264
299
|
setTimeout(() => {
|
|
265
300
|
this.#removeGlobalLoader()
|
|
@@ -274,6 +309,7 @@ export class InlineCheckout {
|
|
|
274
309
|
|
|
275
310
|
removeCheckout() {
|
|
276
311
|
InlineCheckout.injected = false
|
|
312
|
+
InlineCheckout.cardsInjected = false
|
|
277
313
|
// Cancel all requests
|
|
278
314
|
this.abortController.abort();
|
|
279
315
|
this.abortController = new AbortController();
|
|
@@ -285,7 +321,7 @@ export class InlineCheckout {
|
|
|
285
321
|
async #getCardTokens() {
|
|
286
322
|
if (this.card?.skyflow_id) return this.card
|
|
287
323
|
try {
|
|
288
|
-
const collectResponse = await this.collectContainer.collect();
|
|
324
|
+
const collectResponse = await this.collectContainer.container.collect();
|
|
289
325
|
const cardTokens = await collectResponse["records"][0]["fields"];
|
|
290
326
|
return cardTokens;
|
|
291
327
|
} catch (error) {
|
|
@@ -303,8 +339,14 @@ export class InlineCheckout {
|
|
|
303
339
|
const { openpay_keys, reference, business } = this.merchantData
|
|
304
340
|
const total = Number(this.cartTotal)
|
|
305
341
|
|
|
306
|
-
|
|
307
|
-
|
|
342
|
+
let cardTokens = null;
|
|
343
|
+
if(this.radioChecked === "new"){
|
|
344
|
+
cardTokens = await this.#getCardTokens();
|
|
345
|
+
}else{
|
|
346
|
+
cardTokens = {
|
|
347
|
+
skyflow_id: this.radioChecked
|
|
348
|
+
}
|
|
349
|
+
}
|
|
308
350
|
try {
|
|
309
351
|
let deviceSessionIdTonder;
|
|
310
352
|
if (openpay_keys.merchant_id && openpay_keys.public_key) {
|
|
@@ -319,7 +361,23 @@ export class InlineCheckout {
|
|
|
319
361
|
this.customer,
|
|
320
362
|
this.abortController.signal
|
|
321
363
|
)
|
|
364
|
+
if(auth_token && this.email){
|
|
365
|
+
const saveCard = document.getElementById("save-checkout-card");
|
|
366
|
+
if(saveCard && "checked" in saveCard && saveCard.checked){
|
|
367
|
+
await registerCard(this.baseUrl, auth_token, { skyflow_id: cardTokens.skyflow_id });
|
|
368
|
+
|
|
369
|
+
this.cardsInjected = false;
|
|
370
|
+
|
|
371
|
+
const cards = await getCustomerCards(this.baseUrl, auth_token);
|
|
372
|
+
if("cards" in cards) {
|
|
373
|
+
const cardsMapped = cards.cards.map((card) => mapCards(card))
|
|
374
|
+
this.#loadCardsList(cardsMapped, auth_token)
|
|
375
|
+
}
|
|
322
376
|
|
|
377
|
+
showMessage("Tarjeta registrada con éxito", this.collectorIds.msgNotification);
|
|
378
|
+
|
|
379
|
+
}
|
|
380
|
+
}
|
|
323
381
|
var orderItems = {
|
|
324
382
|
business: this.apiKeyTonder,
|
|
325
383
|
client: auth_token,
|
|
@@ -401,4 +459,81 @@ export class InlineCheckout {
|
|
|
401
459
|
throw error;
|
|
402
460
|
}
|
|
403
461
|
};
|
|
462
|
+
|
|
463
|
+
#loadCardsList (cards, token) {
|
|
464
|
+
if(this.cardsInjected) return;
|
|
465
|
+
const injectInterval = setInterval(() => {
|
|
466
|
+
const queryElement = document.querySelector(`#${this.collectorIds.cardsListContainer}`);
|
|
467
|
+
if (queryElement && InlineCheckout.injected) {
|
|
468
|
+
queryElement.innerHTML = cardItemsTemplate(cards)
|
|
469
|
+
clearInterval(injectInterval)
|
|
470
|
+
this.#mountRadioButtons(token)
|
|
471
|
+
this.cardsInjected = true
|
|
472
|
+
}
|
|
473
|
+
}, 500);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
#mountRadioButtons (token) {
|
|
477
|
+
const radioButtons = document.getElementsByName(`card_selected`);
|
|
478
|
+
for (const radio of radioButtons) {
|
|
479
|
+
radio.style.display = "block";
|
|
480
|
+
radio.onclick = async (event) => {
|
|
481
|
+
await this.#handleRadioButtonClick(radio);
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
const cardsButtons = document.getElementsByClassName("card-delete-button");
|
|
485
|
+
for (const cardButton of cardsButtons) {
|
|
486
|
+
cardButton.addEventListener("click", (event) => {
|
|
487
|
+
event.preventDefault();
|
|
488
|
+
this.#handleDeleteCardButtonClick(token, cardButton)
|
|
489
|
+
}, false);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
async #handleRadioButtonClick (radio) {
|
|
494
|
+
if(radio.id === this.radioChecked || ( radio.id === "new" && this.radioChecked === undefined)) return;
|
|
495
|
+
const containerForm = document.querySelector(".container-form");
|
|
496
|
+
if(containerForm) {
|
|
497
|
+
containerForm.style.display = radio.id === "new" ? "block" : "none";
|
|
498
|
+
}
|
|
499
|
+
if(radio.id === "new") {
|
|
500
|
+
if(this.radioChecked !== radio.id) {
|
|
501
|
+
this.#addGlobalLoader()
|
|
502
|
+
this.#mountTonder(false);
|
|
503
|
+
InlineCheckout.injected = true;
|
|
504
|
+
}
|
|
505
|
+
} else {
|
|
506
|
+
this.#unmountForm();
|
|
507
|
+
}
|
|
508
|
+
this.radioChecked = radio.id;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
async #handleDeleteCardButtonClick (customerToken, button) {
|
|
512
|
+
const id = button.attributes.getNamedItem("id")
|
|
513
|
+
const skyflow_id = id?.value?.split("_")?.[2]
|
|
514
|
+
if(skyflow_id) {
|
|
515
|
+
const cardClicked = document.querySelector(`#card_container-${skyflow_id}`);
|
|
516
|
+
if(cardClicked) {
|
|
517
|
+
cardClicked.style.display = "none"
|
|
518
|
+
}
|
|
519
|
+
await deleteCustomerCard(this.baseUrl, customerToken, skyflow_id)
|
|
520
|
+
this.cardsInjected = false
|
|
521
|
+
const cards = await getCustomerCards(this.baseUrl, customerToken)
|
|
522
|
+
if("cards" in cards) {
|
|
523
|
+
const cardsMapped = cards.cards.map(mapCards)
|
|
524
|
+
this.#loadCardsList(cardsMapped, customerToken)
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
#unmountForm () {
|
|
530
|
+
InlineCheckout.injected = false
|
|
531
|
+
if(this.collectContainer) {
|
|
532
|
+
if("unmount" in this.collectContainer.elements.cardHolderNameElement) this.collectContainer.elements.cardHolderNameElement.unmount()
|
|
533
|
+
if("unmount" in this.collectContainer.elements.cardNumberElement) this.collectContainer.elements.cardNumberElement.unmount()
|
|
534
|
+
if("unmount" in this.collectContainer.elements.expiryYearElement) this.collectContainer.elements.expiryYearElement.unmount()
|
|
535
|
+
if("unmount" in this.collectContainer.elements.expiryMonthElement) this.collectContainer.elements.expiryMonthElement.unmount()
|
|
536
|
+
if("unmount" in this.collectContainer.elements.cvvElement) this.collectContainer.elements.cvvElement.unmount()
|
|
537
|
+
}
|
|
538
|
+
}
|
|
404
539
|
}
|
package/src/data/api.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { buildErrorResponse, buildErrorResponseFromCatch } from "../helpers/utils";
|
|
2
|
+
|
|
1
3
|
export async function getOpenpayDeviceSessionID(merchant_id, public_key, signal) {
|
|
2
4
|
let openpay = await window.OpenPay;
|
|
3
5
|
openpay.setId(merchant_id);
|
|
@@ -107,3 +109,64 @@ export async function startCheckoutRouter(baseUrlTonder, apiKeyTonder, routerIte
|
|
|
107
109
|
throw error
|
|
108
110
|
}
|
|
109
111
|
}
|
|
112
|
+
|
|
113
|
+
export async function registerCard(baseUrlTonder, customerToken, data) {
|
|
114
|
+
try {
|
|
115
|
+
const response = await fetch(`${baseUrlTonder}/api/v1/cards/`, {
|
|
116
|
+
method: 'POST',
|
|
117
|
+
headers: {
|
|
118
|
+
'Authorization': `Token ${customerToken}`,
|
|
119
|
+
'Content-Type': 'application/json'
|
|
120
|
+
},
|
|
121
|
+
body: JSON.stringify(data)
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (response.ok) return await response.json();
|
|
125
|
+
if (response.status === 409){
|
|
126
|
+
const res_json = await response.json()
|
|
127
|
+
if(res_json.error = 'Card number already exists.'){
|
|
128
|
+
return {
|
|
129
|
+
code: 200,
|
|
130
|
+
body: res_json,
|
|
131
|
+
name: '',
|
|
132
|
+
message: res_json.error,
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
throw await buildErrorResponse(response);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
throw buildErrorResponseFromCatch(error);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export async function deleteCustomerCard(baseUrlTonder, customerToken, skyflowId = "") {
|
|
142
|
+
try {
|
|
143
|
+
const response = await fetch(`${baseUrlTonder}/api/v1/cards/${skyflowId}`, {
|
|
144
|
+
method: 'DELETE',
|
|
145
|
+
headers: {
|
|
146
|
+
'Authorization': `Token ${customerToken}`,
|
|
147
|
+
'Content-Type': 'application/json'
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
if (response.ok) return true;
|
|
152
|
+
throw await buildErrorResponse(response);
|
|
153
|
+
} catch (error) {
|
|
154
|
+
throw buildErrorResponseFromCatch(error);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
export async function getCustomerCards(baseUrlTonder, customerToken, query = "") {
|
|
158
|
+
try {
|
|
159
|
+
const response = await fetch(`${baseUrlTonder}/api/v1/cards/${query}`, {
|
|
160
|
+
method: 'GET',
|
|
161
|
+
headers: {
|
|
162
|
+
'Authorization': `Token ${customerToken}`,
|
|
163
|
+
'Content-Type': 'application/json'
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
if (response.ok) return await response.json();
|
|
168
|
+
throw await buildErrorResponse(response);
|
|
169
|
+
} catch (error) {
|
|
170
|
+
throw buildErrorResponseFromCatch(error);
|
|
171
|
+
}
|
|
172
|
+
}
|
package/src/helpers/skyflow.js
CHANGED
|
@@ -6,7 +6,8 @@ export async function initSkyflow(
|
|
|
6
6
|
baseUrl,
|
|
7
7
|
apiKey,
|
|
8
8
|
signal,
|
|
9
|
-
customStyles = {}
|
|
9
|
+
customStyles = {},
|
|
10
|
+
collectorIds,
|
|
10
11
|
) {
|
|
11
12
|
const skyflow = await Skyflow.init({
|
|
12
13
|
vaultID: vaultId,
|
|
@@ -51,6 +52,15 @@ export async function initSkyflow(
|
|
|
51
52
|
max: 70,
|
|
52
53
|
},
|
|
53
54
|
};
|
|
55
|
+
const regexEmpty = RegExp("^(?!\s*$).+");
|
|
56
|
+
|
|
57
|
+
const regexMatchRule = {
|
|
58
|
+
type: Skyflow.ValidationRuleType.REGEX_MATCH_RULE,
|
|
59
|
+
params: {
|
|
60
|
+
regex: regexEmpty,
|
|
61
|
+
error: "El campo es requerido" // Optional, default error is 'VALIDATION FAILED'.
|
|
62
|
+
}
|
|
63
|
+
}
|
|
54
64
|
|
|
55
65
|
const cardHolderNameElement = await collectContainer.create({
|
|
56
66
|
table: "cards",
|
|
@@ -59,10 +69,15 @@ export async function initSkyflow(
|
|
|
59
69
|
label: collectStylesOptions.labels?.nameLabel,
|
|
60
70
|
placeholder: collectStylesOptions.placeholders?.namePlaceholder,
|
|
61
71
|
type: Skyflow.ElementType.CARDHOLDER_NAME,
|
|
62
|
-
validations: [lengthMatchRule],
|
|
72
|
+
validations: [lengthMatchRule, regexMatchRule],
|
|
63
73
|
});
|
|
64
74
|
|
|
65
|
-
|
|
75
|
+
handleSkyflowElementEvents(
|
|
76
|
+
cardHolderNameElement,
|
|
77
|
+
collectorIds.holderName,
|
|
78
|
+
"errorCardHolderIdTonder",
|
|
79
|
+
"titular de la tarjeta"
|
|
80
|
+
);
|
|
66
81
|
|
|
67
82
|
// Create collect elements.
|
|
68
83
|
const cardNumberElement = await collectContainer.create({
|
|
@@ -76,9 +91,16 @@ export async function initSkyflow(
|
|
|
76
91
|
label: collectStylesOptions.labels?.cardLabel,
|
|
77
92
|
placeholder: collectStylesOptions.placeholders?.cardPlaceholder,
|
|
78
93
|
type: Skyflow.ElementType.CARD_NUMBER,
|
|
94
|
+
validations: [regexMatchRule],
|
|
79
95
|
});
|
|
80
96
|
|
|
81
|
-
|
|
97
|
+
handleSkyflowElementEvents(
|
|
98
|
+
cardNumberElement,
|
|
99
|
+
collectorIds.cardNumber,
|
|
100
|
+
"errorCardNumberIdTonder",
|
|
101
|
+
"número de tarjeta"
|
|
102
|
+
);
|
|
103
|
+
|
|
82
104
|
|
|
83
105
|
const cvvElement = await collectContainer.create({
|
|
84
106
|
table: "cards",
|
|
@@ -87,9 +109,14 @@ export async function initSkyflow(
|
|
|
87
109
|
label: collectStylesOptions.labels?.cvvLabel,
|
|
88
110
|
placeholder: collectStylesOptions.placeholders?.cvvPlaceholder,
|
|
89
111
|
type: Skyflow.ElementType.CVV,
|
|
112
|
+
validations: [regexMatchRule],
|
|
90
113
|
});
|
|
91
114
|
|
|
92
|
-
|
|
115
|
+
handleSkyflowElementEvents(
|
|
116
|
+
cvvElement,
|
|
117
|
+
collectorIds.cvv,
|
|
118
|
+
"errorCvvIdTonder"
|
|
119
|
+
);
|
|
93
120
|
|
|
94
121
|
const expiryMonthElement = await collectContainer.create({
|
|
95
122
|
table: "cards",
|
|
@@ -98,9 +125,14 @@ export async function initSkyflow(
|
|
|
98
125
|
label: collectStylesOptions.labels?.expiryDateLabel,
|
|
99
126
|
placeholder: collectStylesOptions.placeholders?.expiryMonthPlaceholder,
|
|
100
127
|
type: Skyflow.ElementType.EXPIRATION_MONTH,
|
|
128
|
+
validations: [regexMatchRule],
|
|
101
129
|
});
|
|
102
130
|
|
|
103
|
-
|
|
131
|
+
handleSkyflowElementEvents(
|
|
132
|
+
expiryMonthElement,
|
|
133
|
+
collectorIds.expirationMonth,
|
|
134
|
+
"errorExpiryMonthIdTonder"
|
|
135
|
+
);
|
|
104
136
|
|
|
105
137
|
const expiryYearElement = await collectContainer.create({
|
|
106
138
|
table: "cards",
|
|
@@ -109,9 +141,14 @@ export async function initSkyflow(
|
|
|
109
141
|
label: "",
|
|
110
142
|
placeholder: collectStylesOptions.placeholders?.expiryYearPlaceholder,
|
|
111
143
|
type: Skyflow.ElementType.EXPIRATION_YEAR,
|
|
144
|
+
validations: [regexMatchRule],
|
|
112
145
|
});
|
|
113
146
|
|
|
114
|
-
|
|
147
|
+
handleSkyflowElementEvents(
|
|
148
|
+
expiryYearElement,
|
|
149
|
+
collectorIds.expirationYear,
|
|
150
|
+
"errorExpiryYearIdTonder"
|
|
151
|
+
);
|
|
115
152
|
|
|
116
153
|
await mountElements(
|
|
117
154
|
cardNumberElement,
|
|
@@ -121,7 +158,16 @@ export async function initSkyflow(
|
|
|
121
158
|
cardHolderNameElement,
|
|
122
159
|
)
|
|
123
160
|
|
|
124
|
-
return
|
|
161
|
+
return {
|
|
162
|
+
container: collectContainer,
|
|
163
|
+
elements: {
|
|
164
|
+
cardHolderNameElement,
|
|
165
|
+
cardNumberElement,
|
|
166
|
+
cvvElement,
|
|
167
|
+
expiryMonthElement,
|
|
168
|
+
expiryYearElement
|
|
169
|
+
}
|
|
170
|
+
}
|
|
125
171
|
}
|
|
126
172
|
|
|
127
173
|
async function mountElements(
|
|
@@ -137,3 +183,30 @@ async function mountElements(
|
|
|
137
183
|
expiryYearElement.mount("#collectExpirationYear");
|
|
138
184
|
cardHolderNameElement.mount("#collectCardholderName");
|
|
139
185
|
}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
function handleSkyflowElementEvents(element, elementId, errorElementId, fieldMessage= "", requiredMessage = "El campo es requerido", invalidMessage= "El campo es inválido") {
|
|
189
|
+
if ("on" in element) {
|
|
190
|
+
element.on(Skyflow.EventName.CHANGE, (state) => {
|
|
191
|
+
let errorElement = document.getElementById(errorElementId);
|
|
192
|
+
if (errorElement && state.isValid && !state.isEmpty) {
|
|
193
|
+
errorElement.remove();
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
element.on(Skyflow.EventName.BLUR, (state) => {
|
|
198
|
+
let container = document.getElementById(elementId);
|
|
199
|
+
let errorElement = document.getElementById(errorElementId);
|
|
200
|
+
if (errorElement) {
|
|
201
|
+
errorElement.remove();
|
|
202
|
+
}
|
|
203
|
+
if (!state.isValid) {
|
|
204
|
+
let errorLabel = document.createElement("div");
|
|
205
|
+
errorLabel.classList.add("error-custom-inputs-tonder");
|
|
206
|
+
errorLabel.id = errorElementId;
|
|
207
|
+
errorLabel.textContent = state.isEmpty ? requiredMessage : fieldMessage != "" ?`El campo ${fieldMessage} es inválido`: invalidMessage;
|
|
208
|
+
container?.appendChild(errorLabel);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|