@tonder.io/ionic-full-sdk 0.0.46-beta.9 → 0.0.47-beta.DEV1406.a897fdd
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 +4 -1
- package/dist/classes/inlineCheckout.d.ts +5 -0
- package/dist/helpers/skyflow.d.ts +9 -0
- package/dist/helpers/template.d.ts +5 -1
- package/dist/helpers/utils.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/types/inlineCheckout.d.ts +2 -0
- package/package.json +4 -2
- package/rollup.config.js +6 -1
- package/src/classes/inlineCheckout.ts +140 -46
- package/src/helpers/skyflow.ts +311 -190
- package/src/helpers/styles.ts +9 -8
- package/src/helpers/template.ts +179 -27
- package/src/helpers/utils.ts +12 -0
- package/src/types/inlineCheckout.ts +2 -0
|
@@ -2,9 +2,9 @@ import { apmItemsTemplate, Card, cardItemsTemplate, cardTemplate, CollectorIds }
|
|
|
2
2
|
import {
|
|
3
3
|
showError,
|
|
4
4
|
showMessage,
|
|
5
|
-
mapCards,
|
|
5
|
+
mapCards, generateRandomString,
|
|
6
6
|
} from '../helpers/utils';
|
|
7
|
-
import {
|
|
7
|
+
import {initSkyflow, initUpdateSkyflow} from '../helpers/skyflow'
|
|
8
8
|
import { ErrorResponse } from '@tonder.io/ionic-lite-sdk/dist/classes/errorResponse';
|
|
9
9
|
import { CustomerRegisterResponse } from '@tonder.io/ionic-lite-sdk/dist/types/responses';
|
|
10
10
|
import {BaseInlineCheckout} from "@tonder.io/ionic-lite-sdk";
|
|
@@ -13,11 +13,13 @@ import {ISaveCardSkyflowRequest} from "@tonder.io/ionic-lite-sdk/dist/types/card
|
|
|
13
13
|
import {ITonderPaymentMethod} from "@tonder.io/ionic-lite-sdk/dist/types/paymentMethod";
|
|
14
14
|
import {IInlineCheckoutOptions, InCollectorContainer} from "../types/commons";
|
|
15
15
|
import {IInlineCheckout} from "../types/inlineCheckout";
|
|
16
|
-
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
import Accordion from "accordion-js";
|
|
17
18
|
|
|
18
19
|
export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckout{
|
|
19
20
|
paymentData = {}
|
|
20
21
|
collectContainer: InCollectorContainer | null;
|
|
22
|
+
updateCollectContainer: InCollectorContainer | null;
|
|
21
23
|
deletingCards: string[] = [];
|
|
22
24
|
renderPaymentButton: boolean
|
|
23
25
|
renderSaveCardButton?: boolean
|
|
@@ -25,6 +27,7 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
25
27
|
injectInterval: any
|
|
26
28
|
abortRefreshCardsController: AbortController;
|
|
27
29
|
containerId: string
|
|
30
|
+
accordionC: {open: any; closeAll: any} | null = null;
|
|
28
31
|
injected: boolean
|
|
29
32
|
cardsInjected: boolean
|
|
30
33
|
apmsInjected = false
|
|
@@ -49,12 +52,12 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
49
52
|
customization,
|
|
50
53
|
}: IInlineCheckoutOptions) {
|
|
51
54
|
super({
|
|
52
|
-
apiKey: apiKey,
|
|
53
|
-
returnUrl: returnUrl,
|
|
54
|
-
mode: mode,
|
|
55
|
-
callBack: callBack,
|
|
56
|
-
customization: customization,
|
|
57
|
-
tdsIframeId: collectorIds &&
|
|
55
|
+
apiKey: apiKey,
|
|
56
|
+
returnUrl: returnUrl,
|
|
57
|
+
mode: mode,
|
|
58
|
+
callBack: callBack,
|
|
59
|
+
customization: customization,
|
|
60
|
+
tdsIframeId: collectorIds && 'tdsIframe' in collectorIds ? collectorIds?.tdsIframe : "tdsIframe",
|
|
58
61
|
tonderPayButtonId: collectorIds ? collectorIds?.tonderPayButton : "tonderPayButton"
|
|
59
62
|
});
|
|
60
63
|
this.renderPaymentButton = renderPaymentButton || false;
|
|
@@ -65,7 +68,7 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
65
68
|
this.containerId = containerId ? containerId : "tonder-checkout"
|
|
66
69
|
this.injected = false;
|
|
67
70
|
this.cardsInjected = false;
|
|
68
|
-
this.collectorIds =
|
|
71
|
+
this.collectorIds = {
|
|
69
72
|
cardsListContainer: "cardsListContainer",
|
|
70
73
|
holderName: "collectCardholderName",
|
|
71
74
|
cardNumber: "collectCardNumber",
|
|
@@ -79,8 +82,10 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
79
82
|
apmsListContainer: "apmsListContainer",
|
|
80
83
|
tdsIframe: "tdsIframe"
|
|
81
84
|
}
|
|
85
|
+
this.collectorIds = collectorIds ? {...this.collectorIds, ...collectorIds} :this.collectorIds
|
|
82
86
|
this.radioChecked = "new"
|
|
83
87
|
this.collectContainer = null;
|
|
88
|
+
this.updateCollectContainer = null;
|
|
84
89
|
|
|
85
90
|
this.isOpenPaySandbox = isOpenPaySandbox === undefined ? true : isOpenPaySandbox
|
|
86
91
|
this.isEnrollmentCard = isEnrollmentCard === undefined ? false : isEnrollmentCard
|
|
@@ -92,6 +97,7 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
92
97
|
this.customer = {...this.customer!, email}
|
|
93
98
|
}
|
|
94
99
|
|
|
100
|
+
// TODO: DEPRECATED
|
|
95
101
|
public setPaymentData (data: IProcessPaymentRequest) {
|
|
96
102
|
if (!data) return
|
|
97
103
|
this.paymentData = data
|
|
@@ -183,8 +189,10 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
183
189
|
const injectInterval = setInterval(() => {
|
|
184
190
|
const queryElement = document.querySelector(`#${this.collectorIds.cardsListContainer}`);
|
|
185
191
|
if (queryElement && this.injected) {
|
|
186
|
-
|
|
192
|
+
const acId = generateRandomString(10)
|
|
193
|
+
queryElement.innerHTML = cardItemsTemplate(!!this.customStyles, cards, {acId: acId,collectorIds: this.collectorIds, renderPaymentButton: this.renderPaymentButton})
|
|
187
194
|
clearInterval(injectInterval)
|
|
195
|
+
this.#generateCardsAccordion(acId)
|
|
188
196
|
this.#mountRadioButtons(customerToken)
|
|
189
197
|
this.cardsInjected = true
|
|
190
198
|
}
|
|
@@ -192,24 +200,92 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
192
200
|
}
|
|
193
201
|
}
|
|
194
202
|
|
|
195
|
-
#
|
|
203
|
+
#generateCardsAccordion(acId: string){
|
|
204
|
+
this.accordionC = new Accordion(`.accordion-container${acId}`, {
|
|
205
|
+
triggerClass: "card-item-label",
|
|
206
|
+
duration: 300,
|
|
207
|
+
collapse: true,
|
|
208
|
+
showMultiple: false,
|
|
209
|
+
onOpen: async (currentElement: any) => {
|
|
210
|
+
await this.#handleOpenCardAccordion(currentElement)
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async #handleOpenCardAccordion(currentElement: any){
|
|
216
|
+
const { vault_id, vault_url } = this.merchantData!;
|
|
217
|
+
const container_radio_id = currentElement.id.replace("card_container-", "");
|
|
218
|
+
|
|
219
|
+
if (this.updateCollectContainer && "unmount" in this.updateCollectContainer?.elements?.cvvElement) {
|
|
220
|
+
this.updateCollectContainer.elements.cvvElement.unmount()
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
document.querySelectorAll(".cvvContainer").forEach((container) => {
|
|
224
|
+
container.classList.remove("show");
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
const radio_card = document.getElementById(container_radio_id) as HTMLInputElement;
|
|
228
|
+
if (radio_card) radio_card.checked = true;
|
|
229
|
+
|
|
230
|
+
try{
|
|
231
|
+
this.updateCollectContainer = await initUpdateSkyflow(
|
|
232
|
+
container_radio_id,
|
|
233
|
+
vault_id,
|
|
234
|
+
vault_url,
|
|
235
|
+
this.baseUrl,
|
|
236
|
+
this.abortController.signal,
|
|
237
|
+
this.customStyles,
|
|
238
|
+
this.collectorIds,
|
|
239
|
+
this.apiKeyTonder
|
|
240
|
+
|
|
241
|
+
);
|
|
242
|
+
setTimeout(() => {
|
|
243
|
+
const containerCvv = document.querySelector(`#cvvContainer${container_radio_id}`)
|
|
244
|
+
if(containerCvv) containerCvv.classList.add("show");
|
|
245
|
+
}, 5)
|
|
246
|
+
this.#mountPayButton(container_radio_id)
|
|
247
|
+
}catch (e){
|
|
248
|
+
console.error("Ha ocurrido un error", e);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (radio_card) await this.#handleRadioButtonClick(radio_card)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
#mountPayButton(cardId="") {
|
|
196
256
|
if (!this.renderPaymentButton) return;
|
|
257
|
+
const btnID = `#${this.collectorIds.tonderPayButton}${cardId}`;
|
|
258
|
+
const payButton: HTMLElement | null = document.querySelector(btnID);
|
|
259
|
+
const containerID = `#acContainer${cardId}`;
|
|
260
|
+
const container = document.querySelector(containerID);
|
|
197
261
|
|
|
198
|
-
const payButton: HTMLElement | null = document.querySelector(`#${this.collectorIds.tonderPayButton}`);
|
|
199
|
-
|
|
200
262
|
if (!payButton) {
|
|
201
263
|
console.error("Pay button not found");
|
|
202
264
|
return;
|
|
203
265
|
}
|
|
204
266
|
|
|
267
|
+
if (cardId !== "") {
|
|
268
|
+
const sdkPayButton: HTMLElement | null = document.querySelector(`#${this.collectorIds.tonderPayButton}`);
|
|
269
|
+
if(sdkPayButton){
|
|
270
|
+
sdkPayButton.style.display = "none";
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
205
274
|
const LOCALE_MONEY = "en-Latn-US";
|
|
206
275
|
|
|
207
276
|
payButton.style.display = "block";
|
|
208
|
-
|
|
277
|
+
|
|
209
278
|
const inCartTotal = Intl.NumberFormat(LOCALE_MONEY, { minimumFractionDigits: 2 }).format(Number(this.cartTotal || 0));
|
|
210
|
-
|
|
279
|
+
|
|
211
280
|
payButton.textContent = `Pagar $${inCartTotal}`;
|
|
212
|
-
|
|
281
|
+
|
|
282
|
+
document.querySelectorAll(".ac-card-panel-container").forEach((cont) => {
|
|
283
|
+
cont.classList.remove("show");
|
|
284
|
+
});
|
|
285
|
+
if (container) {
|
|
286
|
+
container.classList.add("show");
|
|
287
|
+
}
|
|
288
|
+
|
|
213
289
|
payButton.onclick = async (event) => {
|
|
214
290
|
event.preventDefault();
|
|
215
291
|
await this.#handlePaymentClick(payButton);
|
|
@@ -221,7 +297,7 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
221
297
|
const prevButtonContent = payButton.innerHTML;
|
|
222
298
|
payButton.innerHTML = `<div class="lds-dual-ring"></div>`;
|
|
223
299
|
try {
|
|
224
|
-
await this.payment(
|
|
300
|
+
await this.payment({} as IProcessPaymentRequest);
|
|
225
301
|
} catch (error) {
|
|
226
302
|
console.error("Payment error:", error);
|
|
227
303
|
} finally {
|
|
@@ -264,10 +340,23 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
264
340
|
}
|
|
265
341
|
}
|
|
266
342
|
|
|
267
|
-
#updatePayButton() {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
343
|
+
#updatePayButton(data?: {cardId?: string | null; updatedTextContent?: boolean; textContent?: string; disabled?: boolean}) {
|
|
344
|
+
try{
|
|
345
|
+
const btnID = data?.cardId ? `#${this.collectorIds.tonderPayButton}${data.cardId}`: `#${this.collectorIds.tonderPayButton}`;
|
|
346
|
+
const updatedText = data?.updatedTextContent || true;
|
|
347
|
+
const btnTextContent = data?.textContent || `Pagar $${this.cartTotal}`;
|
|
348
|
+
const disabledBtn = data?.disabled;
|
|
349
|
+
|
|
350
|
+
const payButton: HTMLElement | null = document.querySelector(btnID);
|
|
351
|
+
if (!payButton) return
|
|
352
|
+
if (updatedText) payButton.textContent = btnTextContent;
|
|
353
|
+
if (disabledBtn !== undefined && 'disabled' in payButton) {
|
|
354
|
+
payButton.disabled = disabledBtn;
|
|
355
|
+
}
|
|
356
|
+
}catch (e){
|
|
357
|
+
console.error("Pay button not found due to update", e);
|
|
358
|
+
}
|
|
359
|
+
|
|
271
360
|
}
|
|
272
361
|
|
|
273
362
|
#mountRadioButtons (token: string = "") {
|
|
@@ -276,7 +365,8 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
276
365
|
radio.style.display = "block";
|
|
277
366
|
radio.onclick = async (event) => {
|
|
278
367
|
//event.preventDefault();
|
|
279
|
-
|
|
368
|
+
const position = Array.from(radioButtons).indexOf(radio);
|
|
369
|
+
await this.#handleRadioButtonClick(radio, position);
|
|
280
370
|
};
|
|
281
371
|
}
|
|
282
372
|
const cardsButtons: HTMLCollectionOf<Element> = document.getElementsByClassName("card-delete-button");
|
|
@@ -320,21 +410,30 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
320
410
|
this.cardsInjected = false;
|
|
321
411
|
await this.#loadCardsList(customerToken)
|
|
322
412
|
}
|
|
323
|
-
async #handleRadioButtonClick (radio: HTMLElement) {
|
|
413
|
+
async #handleRadioButtonClick (radio: HTMLElement, position: number | null = null) {
|
|
324
414
|
const containerForm: HTMLElement | null = document.querySelector(".container-form");
|
|
325
415
|
if(containerForm) {
|
|
326
416
|
containerForm.style.display = radio.id === "new" ? "block" : "none";
|
|
327
417
|
}
|
|
328
418
|
if(radio.id === "new") {
|
|
419
|
+
this.#handleOpenCloseCardAccordion(null, true)
|
|
329
420
|
if(this.radioChecked !== radio.id) {
|
|
330
421
|
await this.#mountForm();
|
|
422
|
+
this.#mountPayButton()
|
|
331
423
|
}
|
|
332
424
|
} else {
|
|
425
|
+
this.#handleOpenCloseCardAccordion(position, position !== null)
|
|
333
426
|
this.#unmountForm();
|
|
334
427
|
}
|
|
335
428
|
this.radioChecked = radio.id;
|
|
336
429
|
}
|
|
337
430
|
|
|
431
|
+
#handleOpenCloseCardAccordion(position: number | null = null, closeAll = false){
|
|
432
|
+
if(closeAll && this.accordionC && 'closeAll' in this.accordionC) this.accordionC.closeAll();
|
|
433
|
+
if(position !== null && this.accordionC && 'open' in this.accordionC) {
|
|
434
|
+
this.accordionC.open(position)
|
|
435
|
+
}
|
|
436
|
+
}
|
|
338
437
|
async #mountAPMs(){
|
|
339
438
|
try{
|
|
340
439
|
const apms = await this._fetchCustomerPaymentMethods();
|
|
@@ -403,9 +502,9 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
403
502
|
#unmountForm () {
|
|
404
503
|
|
|
405
504
|
this.injected = false
|
|
406
|
-
|
|
505
|
+
|
|
407
506
|
if(this.collectContainer) {
|
|
408
|
-
if("unmount" in this.collectContainer.elements.cardHolderNameElement) this.collectContainer.elements.cardHolderNameElement.unmount()
|
|
507
|
+
if("unmount" in this.collectContainer.elements.cardHolderNameElement) this.collectContainer.elements.cardHolderNameElement.unmount()
|
|
409
508
|
if("unmount" in this.collectContainer.elements.cardNumberElement) this.collectContainer.elements.cardNumberElement.unmount()
|
|
410
509
|
if("unmount" in this.collectContainer.elements.expiryYearElement) this.collectContainer.elements.expiryYearElement.unmount()
|
|
411
510
|
if("unmount" in this.collectContainer.elements.expiryMonthElement) this.collectContainer.elements.expiryMonthElement.unmount()
|
|
@@ -436,18 +535,19 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
436
535
|
|
|
437
536
|
}
|
|
438
537
|
|
|
439
|
-
async #getCardTokens(tonderButton: string){
|
|
440
|
-
if(this.collectContainer && "container" in this.collectContainer && "collect" in this.collectContainer.container) {
|
|
538
|
+
async #getCardTokens(tonderButton: string, cardSelected: string | null = null){
|
|
441
539
|
try {
|
|
442
|
-
const
|
|
443
|
-
|
|
540
|
+
const containerCollect = cardSelected && cardSelected !== "new" ? this.updateCollectContainer?.container:this.collectContainer?.container;
|
|
541
|
+
if(containerCollect && "collect" in containerCollect){
|
|
542
|
+
const collectResponseSkyflowTonder: any = await containerCollect.collect();
|
|
543
|
+
return await collectResponseSkyflowTonder["records"][0]["fields"];
|
|
544
|
+
}else{
|
|
545
|
+
showError("Por favor, verifica todos los campos de tu tarjeta", this.collectorIds.msgError, tonderButton)
|
|
546
|
+
}
|
|
444
547
|
} catch (error) {
|
|
445
548
|
showError("Por favor, verifica todos los campos de tu tarjeta", this.collectorIds.msgError, tonderButton)
|
|
446
549
|
throw error;
|
|
447
550
|
}
|
|
448
|
-
} else {
|
|
449
|
-
showError("Por favor, verifica todos los campos de tu tarjeta", this.collectorIds.msgError, tonderButton)
|
|
450
|
-
}
|
|
451
551
|
}
|
|
452
552
|
async #updateSaveCardButton(disabled = false, text = "Guardar"){
|
|
453
553
|
try {
|
|
@@ -491,17 +591,7 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
491
591
|
async _checkout() {
|
|
492
592
|
|
|
493
593
|
try {
|
|
494
|
-
|
|
495
|
-
try {
|
|
496
|
-
|
|
497
|
-
const selector: any = document.querySelector(`#${this.collectorIds.tonderPayButton}`);
|
|
498
|
-
|
|
499
|
-
if(selector){
|
|
500
|
-
selector.disabled = true;
|
|
501
|
-
selector.innerHTML = "Cargando..."
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
} catch (error) { }
|
|
594
|
+
this.#updatePayButton({textContent: "Cargando...", disabled: true});
|
|
505
595
|
|
|
506
596
|
if(this.merchantData!) {
|
|
507
597
|
|
|
@@ -510,8 +600,10 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
510
600
|
let cardTokensSkyflowTonder: any;
|
|
511
601
|
|
|
512
602
|
if(this.radioChecked === "new" || this.radioChecked === undefined) {
|
|
513
|
-
cardTokensSkyflowTonder = await this.#getCardTokens(this.collectorIds.tonderPayButton
|
|
603
|
+
cardTokensSkyflowTonder = await this.#getCardTokens(this.collectorIds.tonderPayButton!, this.radioChecked)
|
|
514
604
|
} else {
|
|
605
|
+
this.#updatePayButton({cardId: this.radioChecked, textContent: "Cargando...", disabled: true});
|
|
606
|
+
await this.#getCardTokens(this.collectorIds.tonderPayButton!, this.radioChecked)
|
|
515
607
|
cardTokensSkyflowTonder = {
|
|
516
608
|
skyflow_id: this.radioChecked
|
|
517
609
|
}
|
|
@@ -532,6 +624,8 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
532
624
|
customer: customerResponse
|
|
533
625
|
});
|
|
534
626
|
|
|
627
|
+
|
|
628
|
+
this.#updatePayButton({cardId: this.radioChecked, disabled: false});
|
|
535
629
|
if (jsonResponseRouter) {
|
|
536
630
|
return jsonResponseRouter;
|
|
537
631
|
} else {
|
|
@@ -571,4 +665,4 @@ export class InlineCheckout extends BaseInlineCheckout implements IInlineCheckou
|
|
|
571
665
|
}
|
|
572
666
|
}
|
|
573
667
|
}
|
|
574
|
-
}
|
|
668
|
+
}
|