@tonder.io/ionic-full-sdk 0.0.34-beta → 0.0.35-beta

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.
@@ -39,3 +39,17 @@ export type PaymentData = {
39
39
  items: OrderItem[];
40
40
  };
41
41
  };
42
+ export type TonderAPM = {
43
+ pk: string;
44
+ payment_method: string;
45
+ priority: number;
46
+ category: string;
47
+ unavailable_countries: string[];
48
+ status: string;
49
+ };
50
+ export type APM = {
51
+ id: string;
52
+ payment_method: string;
53
+ priority: number;
54
+ category: string;
55
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonder.io/ionic-full-sdk",
3
- "version": "0.0.34-beta",
3
+ "version": "0.0.35-beta",
4
4
  "description": "Tonder ionic full SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.js",
@@ -10,7 +10,7 @@
10
10
  "author": "",
11
11
  "license": "ISC",
12
12
  "dependencies": {
13
- "@tonder.io/ionic-lite-sdk": "^0.0.33-beta",
13
+ "@tonder.io/ionic-lite-sdk": "^0.0.34-beta",
14
14
  "crypto-js": "^4.1.1",
15
15
  "skyflow-js": "^1.34.1"
16
16
  },
@@ -1,4 +1,4 @@
1
- import { Card, cardItemsTemplate, cardTemplate, CollectorIds } from '../helpers/template'
1
+ import { apmItemsTemplate, Card, cardItemsTemplate, cardTemplate, CollectorIds } from '../helpers/template'
2
2
  import { LiteCheckout } from '@tonder.io/ionic-lite-sdk';
3
3
  import {
4
4
  showError,
@@ -13,6 +13,7 @@ import { Business, Customer, PaymentData, OrderItem } from '@tonder.io/ionic-lit
13
13
  import { CustomerRegisterResponse, StartCheckoutResponse } from '@tonder.io/ionic-lite-sdk/dist/types/responses';
14
14
  import { StartCheckoutRequest, CreatePaymentRequest, CreateOrderRequest } from '@tonder.io/ionic-lite-sdk/dist/types/requests';
15
15
  import { InCollectorContainer } from '../helpers/skyflow';
16
+ import { APM } from 'src/types/commons';
16
17
 
17
18
  export type InlineCheckoutConstructor = {
18
19
  returnUrl: string,
@@ -59,6 +60,8 @@ export class InlineCheckout {
59
60
  containerId: string
60
61
  injected: boolean
61
62
  cardsInjected: boolean
63
+ apmsInjected = false
64
+ apmsData: APM[] = []
62
65
  collectorIds: CollectorIds
63
66
  platforms?: string[]
64
67
  liteCheckout: LiteCheckout
@@ -118,7 +121,8 @@ export class InlineCheckout {
118
121
  tonderPayButton: "tonderPayButton",
119
122
  msgError: "msgError",
120
123
  msgNotification: "msgNotification",
121
- tonderSaveCardButton: "tonderSaveCardButton"
124
+ tonderSaveCardButton: "tonderSaveCardButton",
125
+ apmsListContainer: "apmsListContainer"
122
126
  }
123
127
  this.clientCards = []
124
128
  this.radioChecked = "new"
@@ -172,7 +176,7 @@ export class InlineCheckout {
172
176
  if (!this.renderSaveCardButton) return;
173
177
 
174
178
  const saveButton: HTMLElement | null = document.querySelector(`#${this.collectorIds.tonderSaveCardButton}`);
175
-
179
+
176
180
  if (!saveButton) {
177
181
  console.error("Save button not found");
178
182
  return;
@@ -180,9 +184,9 @@ export class InlineCheckout {
180
184
 
181
185
 
182
186
  saveButton.style.display = "block";
183
-
187
+
184
188
  saveButton.textContent = `Guardar`;
185
-
189
+
186
190
  saveButton.onclick = async (event) => {
187
191
  event.preventDefault();
188
192
  await this.#handleSaveCardClick(saveButton);
@@ -263,7 +267,7 @@ export class InlineCheckout {
263
267
  });
264
268
  }
265
269
 
266
- #mountRadioButtons (token: string) {
270
+ #mountRadioButtons (token: string = "") {
267
271
  const radioButtons: NodeListOf<HTMLElement> = document.getElementsByName(`card_selected`);
268
272
  for (const radio of radioButtons) {
269
273
  radio.style.display = "block";
@@ -361,7 +365,7 @@ export class InlineCheckout {
361
365
  const injectInterval = setInterval(() => {
362
366
  const queryElement = document.querySelector(`#${this.containerId}`)
363
367
  if (queryElement) {
364
- queryElement.innerHTML = cardTemplate(this.customStyles ? true : false, this.collectorIds, this.isEnrollmentCard)
368
+ queryElement.innerHTML = cardTemplate(this.customStyles ? true : false, this.collectorIds, this.isEnrollmentCard, { renderPaymentButton: this.renderPaymentButton })
365
369
  this.#mountTonder();
366
370
  clearInterval(injectInterval);
367
371
  this.injected = true
@@ -415,6 +419,31 @@ export class InlineCheckout {
415
419
  return await this.liteCheckout.customerRegister(email);
416
420
  }
417
421
 
422
+ async #mountAPMs(){
423
+ try{
424
+ const apms: APM[] = await this.liteCheckout.getActiveAPMs();
425
+ if(apms.length > 0){
426
+ this.apmsData = apms;
427
+ this.#loadAPMList(apms)
428
+ }
429
+ }catch(e){
430
+ console.warn("Error getting APMS")
431
+ }
432
+ }
433
+
434
+ #loadAPMList(apms: APM[]) {
435
+ if (this.apmsInjected) return;
436
+ const injectInterval = setInterval(() => {
437
+ const queryElement = document.querySelector(`#${this.collectorIds.apmsListContainer}`);
438
+ if (queryElement && this.injected) {
439
+ queryElement.innerHTML = apmItemsTemplate(this.customStyles ? true : false, apms);
440
+ clearInterval(injectInterval);
441
+ this.#mountRadioButtons();
442
+ this.apmsInjected = true;
443
+ }
444
+ }, 500);
445
+ }
446
+
418
447
  async #mountTonder() {
419
448
  if(this.isEnrollmentCard){
420
449
  this.#mountSaveCardButton()
@@ -449,6 +478,8 @@ export class InlineCheckout {
449
478
  }
450
479
 
451
480
  }
481
+
482
+ await this.#mountAPMs();
452
483
 
453
484
  this.collectContainer = await initSkyflow(
454
485
  vault_id,
@@ -468,6 +499,7 @@ export class InlineCheckout {
468
499
 
469
500
  this.injected = false
470
501
  this.cardsInjected = false
502
+ this.apmsInjected = false
471
503
  // Cancel all requests
472
504
  this.abortController.abort();
473
505
  this.abortController = new AbortController();
@@ -513,7 +545,6 @@ export class InlineCheckout {
513
545
  }
514
546
 
515
547
  async #getCardTokens(tonderButton: string){
516
- console.log("this.collectContainer: ", this.collectContainer)
517
548
  if(this.collectContainer && "container" in this.collectContainer && "collect" in this.collectContainer.container) {
518
549
  try {
519
550
  const collectResponseSkyflowTonder: any = await this.collectContainer?.container.collect();
@@ -530,7 +561,7 @@ export class InlineCheckout {
530
561
  try {
531
562
 
532
563
  const selector: any = document.querySelector(`#${this.collectorIds.tonderSaveCardButton}`);
533
-
564
+
534
565
  if(selector){
535
566
  selector.disabled = disabled;
536
567
  selector.innerHTML = text
@@ -545,7 +576,7 @@ export class InlineCheckout {
545
576
  if(this.merchantData && "openpay_keys" in this.merchantData) {
546
577
  const cardTokensSkyflowTonder: any = await this.#getCardTokens(this.collectorIds.tonderSaveCardButton!);
547
578
  const customerResponse : CustomerRegisterResponse | ErrorResponse = await this.getCustomer(this.email);
548
-
579
+
549
580
  if("auth_token" in customerResponse) {
550
581
  const { auth_token, id: cutomerId } = customerResponse;
551
582
  console.log("cardTokensSkyflowTonder: ", cardTokensSkyflowTonder)
@@ -697,10 +728,11 @@ export class InlineCheckout {
697
728
  const jsonResponsePayment = await this.liteCheckout.createPayment(
698
729
  paymentItems
699
730
  );
700
-
731
+
732
+ const selected_apm: APM | undefined | null = this.apmsData ? this.apmsData.find((iapm) => iapm.id === this.radioChecked):null;
733
+
701
734
  // Checkout router
702
735
  const routerItems: StartCheckoutRequest = {
703
- card: cardTokensSkyflowTonder,
704
736
  name: this.firstName,
705
737
  last_name: this.lastName ?? "",
706
738
  email_client: this.email,
@@ -721,7 +753,11 @@ export class InlineCheckout {
721
753
  source: 'sdk',
722
754
  metadata: this.metadata,
723
755
  browser_info: getBrowserInfo(),
724
- currency: this.currency
756
+ currency: this.currency,
757
+ ...( !!selected_apm
758
+ ? {payment_method: selected_apm.payment_method}
759
+ : {card: cardTokensSkyflowTonder}
760
+ )
725
761
  };
726
762
 
727
763
  const jsonResponseRouter = await this.liteCheckout.handleCheckoutRouter(
@@ -1,4 +1,6 @@
1
+ import { APM } from 'src/types/commons';
1
2
  import { getCardType } from './utils';
3
+ import { getPaymentMethodDetails } from '@tonder.io/ionic-lite-sdk/dist/helpers/utils';
2
4
 
3
5
  export type CollectorIds = {
4
6
  holderName: string,
@@ -10,7 +12,8 @@ export type CollectorIds = {
10
12
  tonderSaveCardButton?: string,
11
13
  msgError: string,
12
14
  msgNotification: string,
13
- cardsListContainer: string
15
+ cardsListContainer: string,
16
+ apmsListContainer?: string
14
17
  }
15
18
 
16
19
  export type Card = {
@@ -22,7 +25,7 @@ export type Card = {
22
25
  skyflow_id: string
23
26
  }
24
27
 
25
- export const cardTemplate = (external: boolean, collectorIds: CollectorIds, isEnrollmentCard: boolean = false) => `
28
+ export const cardTemplate = (external: boolean, collectorIds: CollectorIds, isEnrollmentCard: boolean = false, data: {renderPaymentButton?: boolean} = {}) => `
26
29
  <div class="container-tonder">
27
30
  <div id="${collectorIds.cardsListContainer}" class="cards-list-container"></div>
28
31
  ${!isEnrollmentCard ? `
@@ -53,8 +56,11 @@ export const cardTemplate = (external: boolean, collectorIds: CollectorIds, isEn
53
56
  <div id="${collectorIds.msgError}"></div>
54
57
  <div id="${collectorIds.msgNotification}"></div>
55
58
  </div>
56
- <button id="${collectorIds.tonderPayButton}" class="pay-button">Pagar</button>
57
- <button id="${collectorIds.tonderSaveCardButton ? collectorIds.tonderSaveCardButton:''}" class="save-card-button">Guardar</button>
59
+ <div id="apmsListContainer" class="apms-list-container"></div>
60
+ <div class="container-pay-button">
61
+ <button id="${collectorIds.tonderPayButton}" class="pay-button">Pagar</button>
62
+ <button id="${collectorIds.tonderSaveCardButton ? collectorIds.tonderSaveCardButton:''}" class="save-card-button">Guardar</button>
63
+ </div>
58
64
  </div>
59
65
 
60
66
  ${external ? `` : `<style>
@@ -93,6 +99,10 @@ ${external ? `` : `<style>
93
99
  border: solid 1px #e3e3e3;
94
100
  }
95
101
 
102
+ .container-pay-button{
103
+ padding: ${!!data['renderPaymentButton'] ? '30px 25px':''};
104
+ }
105
+
96
106
  .collect-row {
97
107
  display: flex !important;
98
108
  justify-content: space-between !important;
@@ -224,6 +234,14 @@ ${external ? `` : `<style>
224
234
  gap: 33% 20px;
225
235
  }
226
236
 
237
+ .apms-list-container {
238
+ display: flex;
239
+ flex-direction: column;
240
+ gap: 33% 20px;
241
+ max-height: 300px;
242
+ overflow-y: auto;
243
+ }
244
+
227
245
  .checkbox label {
228
246
  margin-left: 10px;
229
247
  font-size: '12px';
@@ -518,4 +536,164 @@ export const cardItemsTemplate = (external: boolean, cards: Card[]) => {
518
536
  ${cardItemStyle}
519
537
  `
520
538
  return cardItem;
539
+ }
540
+
541
+ export const apmItemsTemplate = (external: boolean, apms: APM[]) => {
542
+
543
+ const apmItemsHTML = apms.reduce((_, apm) => {
544
+ const apm_data = getPaymentMethodDetails(apm.payment_method);
545
+ return `
546
+ <div class="apm-item" id="card_container-${apm.id}">
547
+ <input id="${apm.id}" class="card_selected" name="card_selected" type="radio"/>
548
+ <label class="apm-item-label" for="${apm.id}">
549
+ <div class="apm-image">
550
+ <div class="apm-image-border"></div>
551
+ <img src="${apm_data.icon}" />
552
+ </div>
553
+ <div class="apm-name">${apm_data.label}</div>
554
+ </label>
555
+ </div>`
556
+ }, ``);
557
+
558
+ const apmItemStyle = external ? '' :`
559
+ <style>
560
+ .apm-item-label {
561
+ display: flex;
562
+ justify-content: flex-start;
563
+ align-items: center;
564
+ color: #1D1D1D;
565
+ gap: 33% 10px;
566
+ margin-top: 15px;
567
+ margin-bottom: 15px;
568
+ width: 100%;
569
+ }
570
+
571
+ .apm-item {
572
+ position: relative;
573
+ display: flex;
574
+ justify-content: start;
575
+ align-items: center;
576
+ gap: 33% 15px;
577
+ border-bottom: 1px solid #e2e8f0;
578
+ padding: 0px 30px;
579
+ }
580
+
581
+ .apm-item:first-child {
582
+ border-top: 1px solid #e2e8f0;
583
+ }
584
+
585
+ .apm-item .apm-name {
586
+ font-size: 16px;
587
+ }
588
+ .apm-image {
589
+ width: 30px;
590
+ height: 30px;
591
+ position: relative;
592
+ display: flex;
593
+ justify-content: center;
594
+ align-items: center;
595
+ }
596
+ .apm-image img {
597
+ width: auto;
598
+ height: 30px;
599
+ }
600
+ .apm-image-border{
601
+ position: absolute;
602
+ border: 1px solid #bababa36;
603
+ border-radius: 4px;
604
+ pointer-events: none;
605
+ box-sizing: border-box;
606
+ width: 100%;
607
+ height: 97%;
608
+ }
609
+
610
+ .card_selected {
611
+ position: relative;
612
+ width: 16px;
613
+ min-width: 16px;
614
+ height: 16px;
615
+ appearance: none;
616
+ cursor: pointer;
617
+ border-radius: 100%;
618
+ border: 1px #bababa solid;
619
+ color: #3bc635;
620
+ transition-property: all;
621
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
622
+ transition-duration: 150ms;
623
+ }
624
+
625
+ .card_selected:before {
626
+ width: 8px;
627
+ height: 8px;
628
+ content: "";
629
+ position: absolute;
630
+ top: 50%;
631
+ left: 50%;
632
+ display: block;
633
+ transform: translate(-50%, -50%);
634
+ border-radius: 100%;
635
+ background-color: #3bc635;
636
+ opacity: 0;
637
+ transition-property: opacity;
638
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
639
+ transition-duration: 150ms;
640
+ }
641
+
642
+ .card_selected:checked {
643
+ border: 1px #3bc635 solid;
644
+ position: relative;
645
+ width: 16px;
646
+ height: 16px;
647
+ min-width: 16px;
648
+ appearance: none;
649
+ cursor: pointer;
650
+ border-radius: 100%;
651
+ color: #3bc635;
652
+ transition-property: all;
653
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
654
+ transition-duration: 150ms;
655
+ }
656
+
657
+ .card_selected:checked:before {
658
+ content: "";
659
+ border: 1px #3bc635 solid;
660
+ width: 8px;
661
+ height: 8px;
662
+ position: absolute;
663
+ top: 50%;
664
+ left: 50%;
665
+ display: block;
666
+ transform: translate(-50%, -50%);
667
+ border-radius: 100%;
668
+ background-color: #3bc635;
669
+ opacity: 50;
670
+ transition-property: opacity;
671
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
672
+ transition-duration: 150ms;
673
+ }
674
+
675
+ .card_selected:hover:before {
676
+ width: 8px;
677
+ height: 8px;
678
+ content: "";
679
+ position: absolute;
680
+ top: 50%;
681
+ left: 50%;
682
+ display: block;
683
+ transform: translate(-50%, -50%);
684
+ border-radius: 100%;
685
+ background-color: #3bc635;
686
+ transition-property: opacity;
687
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
688
+ transition-duration: 150ms;
689
+ opacity: 10;
690
+ }
691
+
692
+ </style>
693
+ `
694
+ const apmItem = `
695
+ ${apmItemsHTML}
696
+ ${apmItemStyle}
697
+ `
698
+ return apmItem;
521
699
  }
@@ -41,4 +41,20 @@ export type PaymentData = {
41
41
  total: string | number,
42
42
  items: OrderItem[]
43
43
  }
44
+ }
45
+
46
+ export type TonderAPM = {
47
+ pk: string;
48
+ payment_method: string;
49
+ priority: number;
50
+ category: string;
51
+ unavailable_countries: string[];
52
+ status: string;
53
+ }
54
+
55
+ export type APM = {
56
+ id: string;
57
+ payment_method: string;
58
+ priority: number;
59
+ category: string;
44
60
  }