@xsolla/payment-client-core 0.1.4 → 0.1.5-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 (160) hide show
  1. package/esm2020/lib/core/device-finger-print/device-finger-print.service.mjs +26 -126
  2. package/esm2020/lib/core/device-finger-print/hash.type.mjs +1 -1
  3. package/esm2020/lib/core/encrypt-credit-card/encrypt-credit-card.service.mjs +72 -0
  4. package/esm2020/lib/core/encrypt-credit-card/encrypted-card.interface.mjs +2 -0
  5. package/esm2020/lib/core/encrypt-credit-card/open-card.interface.mjs +2 -0
  6. package/esm2020/lib/core/exceptions-handling/errors/encrypt-card-error.mjs +9 -0
  7. package/esm2020/lib/core/payment/actions/check-status/check-status.action.class.mjs +2 -3
  8. package/esm2020/lib/core/payment/actions/next-action.interface.mjs +1 -1
  9. package/esm2020/lib/core/payment/actions/next-actions.mjs +3 -1
  10. package/esm2020/lib/core/payment/actions/three-ds/three-ds.action.class.mjs +7 -0
  11. package/esm2020/lib/core/payment/actions/three-ds/three-ds.action.token.mjs +11 -0
  12. package/esm2020/lib/core/payment/actions/three-ds/three-ds.action.type.mjs +2 -0
  13. package/esm2020/lib/core/payment/credit-card-payment-methods-id.variable.mjs +15 -0
  14. package/esm2020/lib/core/payment/form/controls/phone-control.config.mjs +8 -0
  15. package/esm2020/lib/core/payment/form/converters/birth-date.converter.mjs +38 -0
  16. package/esm2020/lib/core/payment/form/converters/card-expiration.converter.mjs +36 -0
  17. package/esm2020/lib/core/payment/form/converters/cardholder-name.converter.mjs +25 -0
  18. package/esm2020/lib/core/payment/form/converters/converters-map.mjs +21 -1
  19. package/esm2020/lib/core/payment/form/converters/cpf-name-regex.variable.mjs +2 -0
  20. package/esm2020/lib/core/payment/form/converters/cpf-name.converter.mjs +34 -0
  21. package/esm2020/lib/core/payment/form/converters/cpf-number.converter.mjs +31 -0
  22. package/esm2020/lib/core/payment/form/converters/cvv.converter.mjs +50 -0
  23. package/esm2020/lib/core/payment/form/converters/phone.converter.mjs +37 -0
  24. package/esm2020/lib/core/payment/form/converters/street-number/street-number-from-state.interface.mjs +2 -0
  25. package/esm2020/lib/core/payment/form/converters/street-number/street-number.converter.mjs +28 -0
  26. package/esm2020/lib/core/payment/form/converters/text.converter.mjs +19 -0
  27. package/esm2020/lib/core/payment/form/form.module.mjs +28 -1
  28. package/esm2020/lib/core/payment/form/validators/birth-date.validator.mjs +37 -0
  29. package/esm2020/lib/core/payment/form/validators/max-length-validator.mjs +6 -0
  30. package/esm2020/lib/core/payment/form/validators/min-length-validator.mjs +6 -0
  31. package/esm2020/lib/core/payment/form/validators/phone-validator.mjs +6 -0
  32. package/esm2020/lib/core/payment/initialize/initialize-request-params.interface.mjs +1 -1
  33. package/esm2020/lib/core/payment/initialize/initialize.service.mjs +28 -19
  34. package/esm2020/lib/core/payment/initialize/response/initialize-response.class.mjs +43 -0
  35. package/esm2020/lib/core/payment/initialize/response/initialize-response.token.mjs +8 -0
  36. package/esm2020/lib/core/payment/payment.interface.mjs +1 -1
  37. package/esm2020/lib/core/payment/payment.service.mjs +19 -5
  38. package/esm2020/lib/core/payment/status/check-status/check-status.service.mjs +8 -13
  39. package/esm2020/lib/core/payment/status/check-status/response/check-status-response.class.mjs +1 -1
  40. package/esm2020/lib/core/payment/submit/submit.service.mjs +13 -16
  41. package/esm2020/lib/core/payment/sync/field-async-validation.interface.mjs +1 -1
  42. package/esm2020/lib/core/payment/sync/field-sync-state.interface.mjs +1 -1
  43. package/esm2020/lib/core/payment/sync/request/sync-request.class.mjs +31 -0
  44. package/esm2020/lib/core/payment/sync/request/sync-request.token.mjs +8 -0
  45. package/esm2020/lib/core/payment/sync/response/sync-response.class.mjs +17 -0
  46. package/esm2020/lib/core/payment/sync/response/sync-response.token.mjs +8 -0
  47. package/esm2020/lib/core/payment/sync/sync.service.mjs +15 -15
  48. package/esm2020/lib/core/payment/three-ds/api/notify-dfp-status/notify-dfp-status.service.mjs +49 -0
  49. package/esm2020/lib/core/payment/three-ds/api/notify-dfp-status/request/notify-dfp-status-request.class.mjs +8 -0
  50. package/esm2020/lib/core/payment/three-ds/api/notify-dfp-status/request/notify-dfp-status-request.token.mjs +8 -0
  51. package/esm2020/lib/core/payment/three-ds/api/status-three-ds/request/status-three-ds-request.class.mjs +7 -0
  52. package/esm2020/lib/core/payment/three-ds/api/status-three-ds/request/status-three-ds-request.token.mjs +8 -0
  53. package/esm2020/lib/core/payment/three-ds/api/status-three-ds/response/status-three-ds-response.class.mjs +7 -0
  54. package/esm2020/lib/core/payment/three-ds/api/status-three-ds/response/status-three-ds-response.token.mjs +8 -0
  55. package/esm2020/lib/core/payment/three-ds/api/status-three-ds/status-three-ds-response.interface.mjs +2 -0
  56. package/esm2020/lib/core/payment/three-ds/api/status-three-ds/status-three-ds.service.mjs +60 -0
  57. package/esm2020/lib/core/payment/three-ds/api/status-three-ds/status-types.enum.mjs +7 -0
  58. package/esm2020/lib/core/payment/three-ds/api/status-three-ds/three-ds-checkout-form.interface.mjs +2 -0
  59. package/esm2020/lib/core/payment/three-ds/dfp-collect/dfp-collect.service.mjs +105 -0
  60. package/esm2020/lib/core/payment/three-ds/reinsurance-check/reinsurance-check.service.mjs +41 -0
  61. package/esm2020/lib/core/payment/three-ds/reinsurance-check/timer.interface.mjs +2 -0
  62. package/esm2020/lib/core/payment/three-ds/three-ds-20/status-update.interface.mjs +2 -0
  63. package/esm2020/lib/core/payment/three-ds/three-ds-20/three-ds20.service.mjs +109 -0
  64. package/esm2020/lib/core/payment/three-ds/three-ds-form.interface.mjs +2 -0
  65. package/esm2020/lib/core/payment/three-ds/three-ds-status-websocket-types.enum.mjs +5 -0
  66. package/esm2020/lib/core/payment/three-ds/three-ds.service.mjs +40 -0
  67. package/esm2020/lib/core/payment/xps-api/xps-api.service.mjs +79 -0
  68. package/esm2020/lib/core/payment/xps-request-params.interface.mjs +2 -0
  69. package/esm2020/lib/core/payment/xps-request.interface.mjs +2 -0
  70. package/esm2020/lib/core/payment/xps-response.error.mjs +7 -0
  71. package/esm2020/lib/core/payment/xps-response.interface.mjs +1 -1
  72. package/esm2020/lib/core-library.module.mjs +13 -4
  73. package/esm2020/lib/core-library.service.mjs +2 -2
  74. package/fesm2015/xsolla-payment-client-core.mjs +1899 -1057
  75. package/fesm2015/xsolla-payment-client-core.mjs.map +1 -1
  76. package/fesm2020/xsolla-payment-client-core.mjs +1852 -1017
  77. package/fesm2020/xsolla-payment-client-core.mjs.map +1 -1
  78. package/lib/core/device-finger-print/device-finger-print.service.d.ts +3 -31
  79. package/lib/core/device-finger-print/hash.type.d.ts +1 -1
  80. package/lib/core/encrypt-credit-card/encrypt-credit-card.service.d.ts +16 -0
  81. package/lib/core/encrypt-credit-card/encrypted-card.interface.d.ts +6 -0
  82. package/lib/core/encrypt-credit-card/open-card.interface.d.ts +6 -0
  83. package/lib/core/exceptions-handling/errors/encrypt-card-error.d.ts +5 -0
  84. package/lib/core/payment/actions/next-action.interface.d.ts +2 -1
  85. package/lib/core/payment/actions/three-ds/three-ds.action.class.d.ts +8 -0
  86. package/lib/core/payment/actions/three-ds/three-ds.action.token.d.ts +4 -0
  87. package/lib/core/payment/actions/three-ds/three-ds.action.type.d.ts +5 -0
  88. package/lib/core/payment/credit-card-payment-methods-id.variable.d.ts +6 -0
  89. package/lib/core/payment/form/controls/phone-control.config.d.ts +6 -0
  90. package/lib/core/payment/form/converters/birth-date.converter.d.ts +13 -0
  91. package/lib/core/payment/form/converters/card-expiration.converter.d.ts +16 -0
  92. package/lib/core/payment/form/converters/cardholder-name.converter.d.ts +13 -0
  93. package/lib/core/payment/form/converters/cpf-name-regex.variable.d.ts +1 -0
  94. package/lib/core/payment/form/converters/cpf-name.converter.d.ts +13 -0
  95. package/lib/core/payment/form/converters/cpf-number.converter.d.ts +11 -0
  96. package/lib/core/payment/form/converters/cvv.converter.d.ts +18 -0
  97. package/lib/core/payment/form/converters/phone.converter.d.ts +13 -0
  98. package/lib/core/payment/form/converters/street-number/street-number-from-state.interface.d.ts +3 -0
  99. package/lib/core/payment/form/converters/street-number/street-number.converter.d.ts +14 -0
  100. package/lib/core/payment/form/converters/text.converter.d.ts +11 -0
  101. package/lib/core/payment/form/validators/birth-date.validator.d.ts +2 -0
  102. package/lib/core/payment/form/validators/max-length-validator.d.ts +2 -0
  103. package/lib/core/payment/form/validators/min-length-validator.d.ts +2 -0
  104. package/lib/core/payment/form/validators/phone-validator.d.ts +2 -0
  105. package/lib/core/payment/initialize/initialize-request-params.interface.d.ts +1 -0
  106. package/lib/core/payment/initialize/initialize.service.d.ts +8 -6
  107. package/lib/core/payment/initialize/{initialize-response.class.d.ts → response/initialize-response.class.d.ts} +2 -2
  108. package/lib/core/payment/payment.interface.d.ts +2 -2
  109. package/lib/core/payment/payment.service.d.ts +4 -2
  110. package/lib/core/payment/status/check-status/check-status.service.d.ts +3 -4
  111. package/lib/core/payment/submit/submit.service.d.ts +5 -4
  112. package/lib/core/payment/sync/field-async-validation.interface.d.ts +1 -1
  113. package/lib/core/payment/sync/field-sync-state.interface.d.ts +1 -1
  114. package/lib/core/payment/sync/{sync-request.class.d.ts → request/sync-request.class.d.ts} +3 -3
  115. package/lib/core/payment/sync/{sync-response.class.d.ts → response/sync-response.class.d.ts} +2 -2
  116. package/lib/core/payment/sync/sync.service.d.ts +8 -7
  117. package/lib/core/payment/three-ds/api/notify-dfp-status/notify-dfp-status.service.d.ts +14 -0
  118. package/lib/core/payment/three-ds/api/notify-dfp-status/request/notify-dfp-status-request.class.d.ts +10 -0
  119. package/lib/core/payment/three-ds/api/notify-dfp-status/request/notify-dfp-status-request.token.d.ts +6 -0
  120. package/lib/core/payment/three-ds/api/status-three-ds/request/status-three-ds-request.class.d.ts +5 -0
  121. package/lib/core/payment/three-ds/api/status-three-ds/request/status-three-ds-request.token.d.ts +6 -0
  122. package/lib/core/payment/three-ds/api/status-three-ds/response/status-three-ds-response.class.d.ts +7 -0
  123. package/lib/core/payment/three-ds/api/status-three-ds/response/status-three-ds-response.token.d.ts +6 -0
  124. package/lib/core/payment/three-ds/api/status-three-ds/status-three-ds-response.interface.d.ts +7 -0
  125. package/lib/core/payment/three-ds/api/status-three-ds/status-three-ds.service.d.ts +21 -0
  126. package/lib/core/payment/three-ds/api/status-three-ds/status-types.enum.d.ts +5 -0
  127. package/lib/core/payment/three-ds/api/status-three-ds/three-ds-checkout-form.interface.d.ts +7 -0
  128. package/lib/core/payment/three-ds/dfp-collect/dfp-collect.service.d.ts +20 -0
  129. package/lib/core/payment/three-ds/reinsurance-check/reinsurance-check.service.d.ts +12 -0
  130. package/lib/core/payment/three-ds/reinsurance-check/timer.interface.d.ts +9 -0
  131. package/lib/core/payment/three-ds/three-ds-20/status-update.interface.d.ts +12 -0
  132. package/lib/core/payment/three-ds/three-ds-20/three-ds20.service.d.ts +32 -0
  133. package/lib/core/payment/three-ds/three-ds-form.interface.d.ts +11 -0
  134. package/lib/core/payment/three-ds/three-ds-status-websocket-types.enum.d.ts +3 -0
  135. package/lib/core/payment/three-ds/three-ds.service.d.ts +14 -0
  136. package/lib/core/payment/xps-api/xps-api.service.d.ts +20 -0
  137. package/lib/core/payment/xps-request-params.interface.d.ts +3 -0
  138. package/lib/core/payment/xps-request.interface.d.ts +10 -0
  139. package/lib/core/payment/xps-response.error.d.ts +4 -0
  140. package/lib/core/payment/xps-response.interface.d.ts +2 -10
  141. package/package.json +2 -3
  142. package/xsolla-payment-client-core-0.1.5-2.tgz +0 -0
  143. package/esm2020/lib/core/device-finger-print/device-finger-print-components.interface.mjs +0 -2
  144. package/esm2020/lib/core/device-finger-print/fingerprint-js.interface.mjs +0 -2
  145. package/esm2020/lib/core/exceptions-handling/errors/default-terminal-error.class.mjs +0 -8
  146. package/esm2020/lib/core/payment/initialize/initialize-response.class.mjs +0 -43
  147. package/esm2020/lib/core/payment/initialize/initialize-response.token.mjs +0 -8
  148. package/esm2020/lib/core/payment/sync/sync-request.class.mjs +0 -31
  149. package/esm2020/lib/core/payment/sync/sync-request.token.mjs +0 -8
  150. package/esm2020/lib/core/payment/sync/sync-response.class.mjs +0 -17
  151. package/esm2020/lib/core/payment/sync/sync-response.token.mjs +0 -8
  152. package/esm2020/lib/core/payment/xps-request.abstract.mjs +0 -8
  153. package/lib/core/device-finger-print/device-finger-print-components.interface.d.ts +0 -4
  154. package/lib/core/device-finger-print/fingerprint-js.interface.d.ts +0 -6
  155. package/lib/core/exceptions-handling/errors/default-terminal-error.class.d.ts +0 -4
  156. package/lib/core/payment/xps-request.abstract.d.ts +0 -6
  157. package/xsolla-payment-client-core-0.1.4.tgz +0 -0
  158. /package/lib/core/payment/initialize/{initialize-response.token.d.ts → response/initialize-response.token.d.ts} +0 -0
  159. /package/lib/core/payment/sync/{sync-request.token.d.ts → request/sync-request.token.d.ts} +0 -0
  160. /package/lib/core/payment/sync/{sync-response.token.d.ts → response/sync-response.token.d.ts} +0 -0
@@ -1,9 +1,10 @@
1
1
  import { __awaiter } from 'tslib';
2
2
  import * as i0 from '@angular/core';
3
3
  import { InjectionToken, Injectable, Inject, isDevMode, NgModule } from '@angular/core';
4
- import { firstValueFrom, lastValueFrom, map, Subject, tap, BehaviorSubject, filter as filter$1, takeUntil, skip, throwError } from 'rxjs';
4
+ import { firstValueFrom, lastValueFrom, map, Subject, BehaviorSubject, filter as filter$1, takeUntil, skip, throwError } from 'rxjs';
5
5
  import * as i1 from '@angular/common/http';
6
6
  import { HttpParams, HttpHeaders, HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
7
+ import JSEncrypt from 'jsencrypt';
7
8
  import { UntypedFormGroup, Validators, UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
8
9
  import { filter, map as map$1, catchError } from 'rxjs/operators';
9
10
  import * as i1$1 from '@angular/router';
@@ -605,6 +606,15 @@ var InputEventName;
605
606
  InputEventName["focus"] = "focus";
606
607
  })(InputEventName || (InputEventName = {}));
607
608
 
609
+ class ShowErrorsAction {
610
+ constructor(errors) {
611
+ this.type = 'show_errors';
612
+ this.data = {
613
+ errors,
614
+ };
615
+ }
616
+ }
617
+
608
618
  class InitializeResponse {
609
619
  constructor(response) {
610
620
  this.paymentForm = null;
@@ -655,14 +665,87 @@ const initializeResponseFactoryProvider = {
655
665
  useValue: (...args) => new InitializeResponse(...args),
656
666
  };
657
667
 
658
- class ShowErrorsAction {
659
- constructor(errors) {
660
- this.type = 'show_errors';
661
- this.data = {
662
- errors,
663
- };
668
+ const masterCardAndVisaPaymentMethodId = 26;
669
+ const maestroPaymentMethodId = 490;
670
+ const creditCardPaymentMethodId = 1380;
671
+ const americanExpressMethodId = 714;
672
+ const specialCards = [
673
+ maestroPaymentMethodId,
674
+ masterCardAndVisaPaymentMethodId,
675
+ americanExpressMethodId,
676
+ ];
677
+ const cardsWith3ds = [
678
+ masterCardAndVisaPaymentMethodId,
679
+ maestroPaymentMethodId,
680
+ creditCardPaymentMethodId,
681
+ ];
682
+
683
+ class XpsApiService {
684
+ constructor(window, secureApiClient, settingsService, countryService) {
685
+ this.window = window;
686
+ this.secureApiClient = secureApiClient;
687
+ this.settingsService = settingsService;
688
+ this.countryService = countryService;
689
+ this.directPaymentApiRoute = 'directpayment';
690
+ }
691
+ directPaymentRequest(parameters) {
692
+ var _a, _b, _c, _d, _e;
693
+ return __awaiter(this, void 0, void 0, function* () {
694
+ const pid = (_c = (_b = (_a = parameters.pid) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : parameters.xps_fix_pid) !== null && _c !== void 0 ? _c : '';
695
+ const paymentWithSavedMethod = (_e = (_d = parameters.paymentWithSavedMethod) !== null && _d !== void 0 ? _d : parameters.xps_paymentWithSavedMethod) !== null && _e !== void 0 ? _e : '';
696
+ const requestParams = Object.assign(Object.assign(Object.assign(Object.assign({}, this.collectAnalyticsParameters(pid, paymentWithSavedMethod)), this.collectUserSessionId()), { country: this.countryService.getCountry() }), parameters);
697
+ return lastValueFrom(this.secureApiClient.post(this.directPaymentApiRoute, new URLSearchParams(Object.assign({}, requestParams)), {
698
+ headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
699
+ responseType: 'json',
700
+ }));
701
+ });
702
+ }
703
+ collectAnalyticsParameters(paymentMethodId, paymentWithSavedMethod) {
704
+ const parameters = {};
705
+ parameters.paymentWithSavedMethod = paymentWithSavedMethod
706
+ ? paymentWithSavedMethod
707
+ : "0" /* XpsBoolean.false */;
708
+ if (!paymentMethodId) {
709
+ return parameters;
710
+ }
711
+ /* If payment method with 3DSecure */
712
+ if (cardsWith3ds.includes(Number(paymentMethodId))) {
713
+ parameters.container3DS = JSON.stringify({
714
+ browserjavaenabled: this.window.navigator.javaEnabled(),
715
+ browserlanguage: this.window.navigator.language,
716
+ browsercolordepth: this.window.screen.colorDepth,
717
+ browserscreenheight: this.window.screen.availHeight,
718
+ browserscreenwidth: this.window.screen.availWidth,
719
+ browsertz: new Date().getTimezoneOffset(),
720
+ browserappname: this.window.navigator.appName,
721
+ browserlocaltime: new Date().toString(),
722
+ browserplatform: this.window.navigator.platform || '',
723
+ browsercookiesenabled: this.window.navigator.cookieEnabled,
724
+ });
725
+ }
726
+ return parameters;
727
+ }
728
+ collectUserSessionId() {
729
+ var _a, _b;
730
+ const parameters = {};
731
+ parameters.xps_idUserSession = (_a = this.settingsService.user.session_id) !== null && _a !== void 0 ? _a : '';
732
+ parameters.user_session_id = (_b = this.settingsService.user.session_id) !== null && _b !== void 0 ? _b : '';
733
+ return parameters;
664
734
  }
665
735
  }
736
+ XpsApiService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: XpsApiService, deps: [{ token: windowToken }, { token: SecureApiClient }, { token: SettingsService }, { token: CountryService }], target: i0.ɵɵFactoryTarget.Injectable });
737
+ XpsApiService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: XpsApiService, providedIn: 'root' });
738
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: XpsApiService, decorators: [{
739
+ type: Injectable,
740
+ args: [{
741
+ providedIn: 'root',
742
+ }]
743
+ }], ctorParameters: function () {
744
+ return [{ type: undefined, decorators: [{
745
+ type: Inject,
746
+ args: [windowToken]
747
+ }] }, { type: SecureApiClient }, { type: SettingsService }, { type: CountryService }];
748
+ } });
666
749
 
667
750
  class ShowFieldsAction {
668
751
  constructor(submitResponse) {
@@ -694,17 +777,16 @@ const showFieldsActionFactoryProvider = {
694
777
 
695
778
  class CheckStatusAction {
696
779
  constructor(submitResponse) {
697
- var _a, _b, _c, _d, _e, _f;
780
+ var _a, _b, _c, _d, _e, _f, _g;
698
781
  this.type = 'check_status';
699
- const status = submitResponse.parameters.status;
700
782
  this.data = {
701
- invoice: status === null || status === void 0 ? void 0 : status.invoice,
702
- signature: (_a = submitResponse.parameters.form.signature) === null || _a === void 0 ? void 0 : _a.value,
703
- locale: (_b = submitResponse.parameters.form.locale) === null || _b === void 0 ? void 0 : _b.value,
704
- testPs: (_c = submitResponse.parameters.form.testPs) === null || _c === void 0 ? void 0 : _c.value,
705
- testXsolla: (_d = submitResponse.parameters.form.testXsolla) === null || _d === void 0 ? void 0 : _d.value,
706
- testProject: (_e = submitResponse.parameters.form.testProject) === null || _e === void 0 ? void 0 : _e.value,
707
- userReturnStatus: (_f = submitResponse.parameters.form.userReturnStatus) === null || _f === void 0 ? void 0 : _f.value,
783
+ invoice: parseInt((_a = submitResponse.parameters.form.fix_invoice) === null || _a === void 0 ? void 0 : _a.value),
784
+ signature: (_b = submitResponse.parameters.form.signature) === null || _b === void 0 ? void 0 : _b.value,
785
+ locale: (_c = submitResponse.parameters.form.locale) === null || _c === void 0 ? void 0 : _c.value,
786
+ testPs: (_d = submitResponse.parameters.form.testPs) === null || _d === void 0 ? void 0 : _d.value,
787
+ testXsolla: (_e = submitResponse.parameters.form.testXsolla) === null || _e === void 0 ? void 0 : _e.value,
788
+ testProject: (_f = submitResponse.parameters.form.testProject) === null || _f === void 0 ? void 0 : _f.value,
789
+ userReturnStatus: (_g = submitResponse.parameters.form.userReturnStatus) === null || _g === void 0 ? void 0 : _g.value,
708
790
  };
709
791
  }
710
792
  }
@@ -787,6 +869,22 @@ const showErrorsActionFactoryProvider = {
787
869
  },
788
870
  };
789
871
 
872
+ class ThreeDsAction {
873
+ constructor(statusUpdate) {
874
+ this.type = '3DS';
875
+ this.data = statusUpdate;
876
+ }
877
+ }
878
+
879
+ const threeDsActionFactoryToken = new InjectionToken('ThreeDsAction');
880
+ const threeDsActionFactoryProvider = {
881
+ provide: threeDsActionFactoryToken,
882
+ useValue: {
883
+ factory: (...args) => new ThreeDsAction(...args),
884
+ isSuitable: () => false,
885
+ },
886
+ };
887
+
790
888
  const nextActionsToken = new InjectionToken('Action');
791
889
  const nextActions = [
792
890
  showFieldsActionFactoryProvider,
@@ -796,6 +894,7 @@ const nextActions = [
796
894
  const flowUpdateNextActions = [
797
895
  statusUpdatedActionFactoryProvider,
798
896
  showErrorsActionFactoryProvider,
897
+ threeDsActionFactoryProvider,
799
898
  ];
800
899
 
801
900
  class NextActionService {
@@ -856,522 +955,457 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
856
955
  }] }, { type: i0.Injector }];
857
956
  } });
858
957
 
859
- class InitializeService {
860
- constructor(responseFactory, secureApi, settingsService, countryService, nextActionService) {
861
- this.responseFactory = responseFactory;
862
- this.secureApi = secureApi;
863
- this.settingsService = settingsService;
864
- this.countryService = countryService;
865
- this.nextActionService = nextActionService;
866
- this.apiRoute = 'directpayment';
867
- // TODO PAYMENTS-15743: replace with new refer id for headless core
868
- this.ps4ReferId = '22';
869
- }
870
- request(config) {
871
- return __awaiter(this, void 0, void 0, function* () {
872
- const requestParams = {
873
- access_token: this.settingsService.token,
874
- pid: String(config.paymentMethodId),
875
- refer: this.ps4ReferId,
876
- country: this.countryService.getCountry(),
877
- returnUrl: config.returnUrl,
878
- };
879
- return lastValueFrom(this.secureApi
880
- .post(this.apiRoute, new URLSearchParams(Object.assign({}, requestParams)), {
881
- headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
882
- responseType: 'json',
883
- })
884
- .pipe(map((response) => this.responseFactory(response)), tap((response) => {
885
- var _a, _b;
886
- if ((_b = (_a = response.paymentForm) === null || _a === void 0 ? void 0 : _a.errors) === null || _b === void 0 ? void 0 : _b.length) {
887
- this.nextActionService.emitFlowUpdates(new ShowErrorsAction(response.paymentForm.errors));
888
- }
889
- }))).catch((error) => {
890
- throw new ResponseError(error.message);
891
- });
892
- });
893
- }
894
- }
895
- InitializeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, deps: [{ token: initializeResponseFactoryToken }, { token: SecureApiClient }, { token: SettingsService }, { token: CountryService }, { token: NextActionService }], target: i0.ɵɵFactoryTarget.Injectable });
896
- InitializeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, providedIn: 'root' });
897
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, decorators: [{
898
- type: Injectable,
899
- args: [{
900
- providedIn: 'root',
901
- }]
902
- }], ctorParameters: function () {
903
- return [{ type: undefined, decorators: [{
904
- type: Inject,
905
- args: [initializeResponseFactoryToken]
906
- }] }, { type: SecureApiClient }, { type: SettingsService }, { type: CountryService }, { type: NextActionService }];
907
- } });
958
+ var ErrorTags;
959
+ (function (ErrorTags) {
960
+ ErrorTags["APP"] = "appError";
961
+ ErrorTags["HTTP"] = "httpError";
962
+ ErrorTags["JS"] = "jsError";
963
+ ErrorTags["WS"] = "webSocket";
964
+ ErrorTags["ENCRYPT"] = "encrypt";
965
+ ErrorTags["APPLEPAY"] = "applepay";
966
+ ErrorTags["HEADLESS_UI"] = "headlessUi";
967
+ ErrorTags["GOOGLEPAY"] = "googlepay";
968
+ ErrorTags["PAYTM"] = "paytm";
969
+ })(ErrorTags || (ErrorTags = {}));
908
970
 
909
- class XpsApiPartRequest {
910
- addXpsParameters(parameters) {
911
- for (const key in parameters) {
912
- this[`xps_${key}`] = parameters[key];
971
+ class TaggedError extends Error {
972
+ constructor(message, tags) {
973
+ super(message);
974
+ this.tags = [];
975
+ this.parentTag = ErrorTags.HEADLESS_UI;
976
+ this.tags = this.childTag
977
+ ? [this.parentTag, this.childTag]
978
+ : [this.parentTag];
979
+ if (tags) {
980
+ const newTags = tags.filter((t, i, arr) => !this.tags.includes(t) && arr.indexOf(t) == i);
981
+ this.tags = [...this.tags, ...newTags];
913
982
  }
914
983
  }
915
984
  }
916
985
 
917
- class TokenError extends AppError {
918
- constructor() {
919
- super('XPS API needs token.');
986
+ class EncryptCreditCardError extends TaggedError {
987
+ constructor(message, tags) {
988
+ tags = tags ? [...tags, ErrorTags.ENCRYPT] : [ErrorTags.ENCRYPT];
989
+ super(message, tags);
920
990
  }
921
991
  }
922
992
 
923
- class SubmitRequest extends XpsApiPartRequest {
924
- constructor(parameters) {
925
- super();
926
- const { token, fields, form, dfpHash } = parameters;
927
- if (token === null) {
928
- throw new TokenError();
929
- }
930
- this.access_token = token;
931
- if (dfpHash) {
932
- this.xps_dfp_hash = dfpHash;
933
- }
934
- this.addXpsParameters(this.getFieldsValues(fields, form));
935
- }
936
- getFieldsValues(fields, form) {
937
- return fields.reduce((xpsParams, field) => {
938
- const formControl = form.get(field.name);
939
- xpsParams[field.name] = formControl ? formControl.value : field === null || field === void 0 ? void 0 : field.value;
940
- return xpsParams;
941
- }, {});
942
- }
943
- }
993
+ const fourBlockMask = '9999 9999 9999 9999';
944
994
 
945
- const submitRequestFactoryToken = new InjectionToken('SubmitRequest');
946
- const submitRequestFactoryProvider = {
947
- provide: submitRequestFactoryToken,
948
- useValue: (...args) => new SubmitRequest(...args),
995
+ var CreditCardTypes;
996
+ (function (CreditCardTypes) {
997
+ CreditCardTypes["DEFAULT"] = "0";
998
+ CreditCardTypes["VISA"] = "1";
999
+ CreditCardTypes["MASTERCARD"] = "2";
1000
+ CreditCardTypes["MAESTRO"] = "3";
1001
+ CreditCardTypes["AMERICAN_EXPRESS"] = "4";
1002
+ CreditCardTypes["DINERS_CLUBS"] = "5";
1003
+ CreditCardTypes["DISCOVER"] = "6";
1004
+ CreditCardTypes["JCB"] = "9";
1005
+ CreditCardTypes["DANKORT"] = "11";
1006
+ CreditCardTypes["HIPERCARD"] = "12";
1007
+ CreditCardTypes["ELO"] = "13";
1008
+ CreditCardTypes["AURA"] = "14";
1009
+ CreditCardTypes["NARANJA"] = "15";
1010
+ CreditCardTypes["MIR"] = "16";
1011
+ CreditCardTypes["CHINA_UNION_PAY"] = "17";
1012
+ CreditCardTypes["POSTEPAY"] = "18";
1013
+ })(CreditCardTypes || (CreditCardTypes = {}));
1014
+
1015
+ const visa = {
1016
+ id: CreditCardTypes.VISA,
1017
+ minLength: 13,
1018
+ maxLength: 16,
1019
+ iconName: 'visa',
1020
+ mask: fourBlockMask,
1021
+ checkNumber(number) {
1022
+ return number.startsWith('4');
1023
+ },
949
1024
  };
950
1025
 
951
- const submitResponseFactoryToken = new InjectionToken('SubmitResponse');
952
- const submitResponseFactoryProvider = {
953
- provide: submitResponseFactoryToken,
954
- useValue: (...args) => new SubmitResponse(...args),
1026
+ const mastercard = {
1027
+ id: CreditCardTypes.MASTERCARD,
1028
+ minLength: 16,
1029
+ maxLength: 16,
1030
+ iconName: 'mastercard',
1031
+ mask: fourBlockMask,
1032
+ checkNumber(number) {
1033
+ const subLength = 6;
1034
+ const cardNumberSub = number.substring(0, subLength);
1035
+ return (new RegExp(/^5[1-5]/).test(number) ||
1036
+ (cardNumberSub >= '222100' && cardNumberSub <= '272099'));
1037
+ },
955
1038
  };
956
1039
 
957
- class TerminalError extends AppError {
958
- constructor(message, code) {
959
- super(message);
960
- this.code = code;
961
- }
962
- }
1040
+ const defaultMask = '9999 9999 9999 9999 999';
963
1041
 
964
- class DefaultTerminalError extends TerminalError {
965
- constructor() {
966
- const message = `It's not you, it's us, but we can help. Please contact our customer support.`;
967
- super(message, '1000-0002');
968
- }
969
- }
1042
+ const maestro = {
1043
+ id: CreditCardTypes.MAESTRO,
1044
+ minLength: 12,
1045
+ maxLength: 19,
1046
+ iconName: 'maestro',
1047
+ mask: defaultMask,
1048
+ checkNumber(number) {
1049
+ return new RegExp(/^(5018)|^(5020)|^(5038)|^(5893)|^(6304)|^(6759)|^(6761)|^(6762)|^(6763)|^(0604)|^(6706)|^(6771)|^(6709)/).test(number);
1050
+ },
1051
+ maxCvvLength: 3,
1052
+ };
970
1053
 
971
- class DeviceFingerPrintService {
972
- constructor(secureApi, settingsService, window) {
973
- this.secureApi = secureApi;
974
- this.settingsService = settingsService;
975
- this.window = window;
976
- this.apiRoute = 'dfp';
977
- this.fingerprintApiUrl = 'https://afs.xsolla.com/dfp/api/v1/';
978
- }
979
- init() {
980
- return __awaiter(this, void 0, void 0, function* () {
981
- if (!this.settingsService.isInitialized) {
982
- return;
983
- }
984
- this.fingerprintJs = yield this.loadFingerprintJs();
985
- this.hash = yield this.buildHash();
986
- this.antifraudFingerprintLibrary =
987
- yield this.loadAntifraudFingerprintLibrary();
988
- });
989
- }
990
- // eslint-disable-next-line @typescript-eslint/require-await
991
- getHash() {
992
- return __awaiter(this, void 0, void 0, function* () {
993
- return this.hash;
994
- });
995
- }
996
- loadFingerprintJs() {
997
- return __awaiter(this, void 0, void 0, function* () {
998
- const { default: library, murmurX64Hash128: getHash } = yield import('@fingerprintjs/fingerprintjs');
999
- return { library, getHash };
1000
- });
1001
- }
1002
- loadAntifraudFingerprintLibrary() {
1003
- return __awaiter(this, void 0, void 0, function* () {
1004
- const library = yield import('@xsolla/antifraud-fingerprint');
1005
- return library.default;
1006
- });
1007
- }
1008
- // eslint-disable-next-line @typescript-eslint/require-await
1009
- makeAntifraudFingerprint() {
1010
- return __awaiter(this, void 0, void 0, function* () {
1011
- if (!this.settingsService.token) {
1012
- return null;
1013
- }
1014
- const antifraudFingerprint = this.antifraudFingerprintLibrary;
1015
- try {
1016
- return new antifraudFingerprint({
1017
- api: {
1018
- url: this.fingerprintApiUrl,
1019
- token: this.settingsService.token,
1020
- timeout: 3000,
1021
- },
1022
- retry: {
1023
- num: 1,
1024
- timeout: 500,
1025
- },
1026
- });
1027
- }
1028
- catch (error) {
1029
- return null;
1030
- }
1031
- });
1032
- }
1033
- /**
1034
- *Загружаем библиотеку, генерируем данные,
1035
- *хешируем с помощью BASE64 и отправляем на бэкенд,
1036
- *в ответ получаем dfp_hash.
1037
- **/
1038
- buildHash() {
1039
- return __awaiter(this, void 0, void 0, function* () {
1040
- const fingerPrintData = yield this.generate();
1041
- const hash = yield this.send(fingerPrintData).catch(() => {
1042
- return null;
1043
- });
1044
- return JSON.stringify(hash);
1045
- });
1046
- }
1047
- /**
1048
- *Новая версия библиотеки содержит не все компоненты, некоторые приходится имплементировать самостоятельно
1049
- **/
1050
- getHasLiedResolution() {
1051
- const { screen } = this.window;
1052
- return (screen.width < screen.availWidth || screen.height < screen.availHeight);
1053
- }
1054
- /**
1055
- *Бэкенд заточен под конкретные поля, которые необходимо смапить.
1056
- **/
1057
- getComponents(components) {
1058
- var _a, _b, _c, _d, _e, _f, _g, _h;
1059
- return {
1060
- user_agent: navigator.userAgent,
1061
- language: (_c = (_b = (_a = components.languages.value) === null || _a === void 0 ? void 0 : _a.shift()) === null || _b === void 0 ? void 0 : _b.shift()) !== null && _c !== void 0 ? _c : '',
1062
- color_depth: components.colorDepth.value,
1063
- device_memory: components.deviceMemory.value,
1064
- hardware_concurrency: components.hardwareConcurrency.value,
1065
- resolution: components.screenResolution.value,
1066
- available_resolution: components.screenResolution.value,
1067
- timezone_offset: new Date().getTimezoneOffset(),
1068
- session_storage: components.sessionStorage.value ? 1 : 0,
1069
- local_storage: components.localStorage.value ? 1 : 0,
1070
- indexed_db: components.indexedDB.value ? 1 : 0,
1071
- open_database: components.openDatabase.value ? 1 : 0,
1072
- navigator_platform: components.platform.value,
1073
- regular_plugins: (_e = (_d = components.plugins.value) === null || _d === void 0 ? void 0 : _d.map((plugin) => plugin.name)) !== null && _e !== void 0 ? _e : [],
1074
- canvas: (_f = components.canvas.value) === null || _f === void 0 ? void 0 : _f.text,
1075
- webgl: (_g = components.canvas.value) === null || _g === void 0 ? void 0 : _g.text,
1076
- webgl_vendor: components.vendor.value,
1077
- has_lied_resolution: this.getHasLiedResolution(),
1078
- touch_support: Object.values((_h = components.touchSupport.value) !== null && _h !== void 0 ? _h : {}),
1079
- js_fonts: components.fonts.value,
1080
- };
1081
- }
1082
- /**
1083
- * Получаем данные dfp с помощью FingerprintJS, мапим необходимые поля, добавляем хэш
1084
- **/
1085
- generate() {
1086
- return __awaiter(this, void 0, void 0, function* () {
1087
- const { library, getHash } = this.fingerprintJs;
1088
- const fingerprint = yield library.load();
1089
- const commonFingerPrintData = yield fingerprint.get();
1090
- const fingerPrintData = this.getComponents(commonFingerPrintData.components);
1091
- fingerPrintData.hash = getHash(JSON.stringify(fingerPrintData));
1092
- return fingerPrintData;
1093
- });
1094
- }
1095
- /**
1096
- * Отправка dfp на сервер, в ответ получаем dfp_hash
1097
- **/
1098
- send(fingerPrintData) {
1099
- return __awaiter(this, void 0, void 0, function* () {
1100
- const token = this.settingsService.token;
1101
- if (token === null) {
1102
- throw new DefaultTerminalError();
1103
- }
1104
- const requestBody = {
1105
- access_token: token,
1106
- 'dfp[200]': '',
1107
- };
1108
- requestBody['dfp[200]'] = btoa(encodeURIComponent(JSON.stringify(fingerPrintData)));
1109
- return lastValueFrom(this.secureApi.post(this.apiRoute, new URLSearchParams(requestBody), {
1110
- headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
1111
- responseType: 'json',
1112
- }))
1113
- .then((response) => {
1114
- return response.dfp_hash;
1115
- })
1116
- .then((hash) => __awaiter(this, void 0, void 0, function* () {
1117
- const fingerprint = yield this.makeAntifraudFingerprint();
1118
- if (!fingerprint) {
1119
- return null;
1120
- }
1121
- yield (fingerprint === null || fingerprint === void 0 ? void 0 : fingerprint.dispatch(hash['200']).catch((err) => console.log(err)));
1122
- const afsHash = yield fingerprint.hash();
1123
- return Object.assign({ '301': afsHash }, hash);
1124
- }))
1125
- .catch((error) => {
1126
- var _a, _b, _c, _d, _e, _f;
1127
- const response = error.getHttpErrorData().response;
1128
- throw new TerminalError((_c = (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.errors[0]) === null || _b === void 0 ? void 0 : _b.message) !== null && _c !== void 0 ? _c : '', (_f = (_e = (_d = response.data) === null || _d === void 0 ? void 0 : _d.errors[0]) === null || _e === void 0 ? void 0 : _e.support_code) !== null && _f !== void 0 ? _f : '');
1129
- });
1130
- });
1131
- }
1132
- }
1133
- DeviceFingerPrintService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, deps: [{ token: SecureApiClient }, { token: SettingsService }, { token: windowToken }], target: i0.ɵɵFactoryTarget.Injectable });
1134
- DeviceFingerPrintService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, providedIn: 'root' });
1135
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, decorators: [{
1136
- type: Injectable,
1137
- args: [{
1138
- providedIn: 'root',
1139
- }]
1140
- }], ctorParameters: function () {
1141
- return [{ type: SecureApiClient }, { type: SettingsService }, { type: undefined, decorators: [{
1142
- type: Inject,
1143
- args: [windowToken]
1144
- }] }];
1145
- } });
1054
+ const americanExpress = {
1055
+ id: CreditCardTypes.AMERICAN_EXPRESS,
1056
+ minLength: 15,
1057
+ maxLength: 15,
1058
+ iconName: 'american-express',
1059
+ mask: '9999 999999 99999',
1060
+ checkNumber(number) {
1061
+ return new RegExp(/^(34)|^(37)/).test(number);
1062
+ },
1063
+ maxCvvLength: 4,
1064
+ };
1146
1065
 
1147
- class SubmitService {
1148
- constructor(requestFactory, responseFactory, settingsService, deviceFingerPrintService, secureApi) {
1149
- this.requestFactory = requestFactory;
1150
- this.responseFactory = responseFactory;
1151
- this.settingsService = settingsService;
1152
- this.deviceFingerPrintService = deviceFingerPrintService;
1153
- this.secureApi = secureApi;
1154
- this.directPaymentApiRoute = 'directpayment';
1155
- }
1156
- // NB: Never add 'async' statement for this method!
1157
- // 'Async' statement wraps current promise into another.
1158
- // In this way two promises become unequal, that can broke XPS API requests logic.
1159
- // eslint-disable-next-line @typescript-eslint/promise-function-async
1160
- request(fields, form) {
1161
- const responsePromise = this.deviceFingerPrintService
1162
- .getHash()
1163
- // eslint-disable-next-line @typescript-eslint/promise-function-async
1164
- .then((dfpHash) => {
1165
- const requestParams = this.requestFactory({
1166
- token: this.settingsService.token,
1167
- fields,
1168
- form,
1169
- dfpHash,
1170
- });
1171
- return lastValueFrom(this.secureApi.post(this.directPaymentApiRoute, new URLSearchParams(Object.assign({}, requestParams)), {
1172
- headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
1173
- responseType: 'json',
1174
- }))
1175
- .then((response) => this.responseFactory(response))
1176
- .catch((error) => {
1177
- throw new ResponseError(error.message);
1178
- });
1179
- });
1180
- return responsePromise;
1181
- }
1182
- }
1183
- SubmitService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, deps: [{ token: submitRequestFactoryToken }, { token: submitResponseFactoryToken }, { token: SettingsService }, { token: DeviceFingerPrintService }, { token: SecureApiClient }], target: i0.ɵɵFactoryTarget.Injectable });
1184
- SubmitService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, providedIn: 'root' });
1185
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, decorators: [{
1186
- type: Injectable,
1187
- args: [{ providedIn: 'root' }]
1188
- }], ctorParameters: function () {
1189
- return [{ type: undefined, decorators: [{
1190
- type: Inject,
1191
- args: [submitRequestFactoryToken]
1192
- }] }, { type: undefined, decorators: [{
1193
- type: Inject,
1194
- args: [submitResponseFactoryToken]
1195
- }] }, { type: SettingsService }, { type: DeviceFingerPrintService }, { type: SecureApiClient }];
1196
- } });
1066
+ const dinersClubs = {
1067
+ id: CreditCardTypes.DINERS_CLUBS,
1068
+ minLength: 14,
1069
+ maxLength: 14,
1070
+ iconName: 'dinersclub',
1071
+ mask: '9999 9999 9999 99',
1072
+ checkNumber(number) {
1073
+ const regex = /^(36[0-9]|3(?:0[0-59]|[68][0-9])[0-9])/;
1074
+ return regex.test(number);
1075
+ },
1076
+ };
1197
1077
 
1198
- class EmitDataService {
1199
- constructor() {
1200
- this.dataSubject = new Subject();
1201
- this.data$ = this.dataSubject.asObservable();
1202
- }
1203
- emit(data) {
1204
- this.dataSubject.next(data);
1205
- }
1206
- }
1078
+ const discover = {
1079
+ id: CreditCardTypes.DISCOVER,
1080
+ minLength: 16,
1081
+ maxLength: 19,
1082
+ iconName: 'discover',
1083
+ mask: defaultMask,
1084
+ checkNumber(number) {
1085
+ return new RegExp(/^(6011)|^(622(1(2[6-9]|[3-9][0-9])|[2-8][0-9]{2}|9([01][0-9]|2[0-5])))|^(64[4-9])|^65/).test(number);
1086
+ },
1087
+ };
1207
1088
 
1208
- class XpsRequest {
1209
- addXpsParameters(parameters) {
1210
- for (const key in parameters) {
1211
- this[`xps_${key}`] = parameters[key];
1212
- }
1213
- }
1214
- }
1089
+ const jcb = {
1090
+ id: CreditCardTypes.JCB,
1091
+ minLength: 15,
1092
+ maxLength: 16,
1093
+ iconName: 'jcb',
1094
+ mask: fourBlockMask,
1095
+ checkNumber(number) {
1096
+ return new RegExp(/^35(2[89]|[3-8][0-9])/).test(number);
1097
+ },
1098
+ };
1215
1099
 
1216
- /* eslint-disable @typescript-eslint/naming-convention */
1217
- class SyncRequest extends XpsRequest {
1218
- constructor(parameters) {
1219
- super();
1220
- this.xps_fix_command = 'calculate';
1221
- this.access_token = parameters.token;
1222
- const fieldsValues = this.getFieldsValues(parameters.changedField, parameters.fields, parameters.form);
1223
- this.addXpsParameters(Object.assign(Object.assign({}, fieldsValues), { change_element: parameters.changedField.name }));
1224
- }
1225
- getFieldsValues(changedField, fields, form) {
1226
- var _a;
1227
- const fieldsMap = this.getFieldsMap(fields);
1228
- return (_a = changedField === null || changedField === void 0 ? void 0 : changedField.javascript) === null || _a === void 0 ? void 0 : _a.change.params.reduce((xpsParams, fieldName) => {
1229
- var _a;
1230
- const formControl = form.get(fieldName);
1231
- const field = fieldsMap.get(fieldName);
1232
- if (formControl || field) {
1233
- xpsParams[fieldName] = (_a = formControl === null || formControl === void 0 ? void 0 : formControl.value) !== null && _a !== void 0 ? _a : field === null || field === void 0 ? void 0 : field.value;
1234
- }
1235
- return xpsParams;
1236
- }, {});
1237
- }
1238
- getFieldsMap(fields) {
1239
- const map = new Map();
1240
- fields.forEach((field) => map.set(field.name, field));
1241
- return map;
1242
- }
1243
- }
1100
+ const dankort = {
1101
+ id: CreditCardTypes.DANKORT,
1102
+ minLength: 16,
1103
+ maxLength: 16,
1104
+ iconName: 'dankort',
1105
+ mask: fourBlockMask,
1106
+ checkNumber(number) {
1107
+ const subLength = 4;
1108
+ const cardNumberSub = number.substring(0, subLength);
1109
+ return cardNumberSub === '5019';
1110
+ },
1111
+ };
1244
1112
 
1245
- const syncRequestFactoryToken = new InjectionToken('SyncRequest');
1246
- const syncRequestFactoryProvider = {
1247
- provide: syncRequestFactoryToken,
1248
- useValue: (...args) => new SyncRequest(...args),
1113
+ const hipercard = {
1114
+ id: CreditCardTypes.HIPERCARD,
1115
+ minLength: 13,
1116
+ maxLength: 19,
1117
+ iconName: 'hipercard',
1118
+ mask: defaultMask,
1119
+ checkNumber(number) {
1120
+ return new RegExp(/^((606282|637095|637568)[0-9]|38[0-9]{14,17})/).test(number);
1121
+ },
1249
1122
  };
1250
1123
 
1251
- class SyncResponse {
1252
- constructor(changedField, response) {
1253
- var _a;
1254
- this.error = null;
1255
- const fieldError = (_a = response === null || response === void 0 ? void 0 : response.errors) === null || _a === void 0 ? void 0 : _a.find((error) => error.element_name === changedField.name);
1256
- if (fieldError) {
1257
- this.error = {
1258
- asyncError: {
1259
- code: fieldError.code,
1260
- message: fieldError.message,
1261
- },
1262
- };
1263
- }
1264
- this.fields = Object.keys(response.form).map((key) => response.form[key]);
1265
- this.parameters = response;
1266
- }
1267
- }
1124
+ const elo = {
1125
+ id: CreditCardTypes.ELO,
1126
+ minLength: 16,
1127
+ maxLength: 19,
1128
+ iconName: 'elo',
1129
+ mask: defaultMask,
1130
+ checkNumber(number) {
1131
+ return new RegExp(/^(40117[8-9]|431274|438935|451416|457393|45763[1-2]|506(699|7[0-6][0-9]|77[0-8])|509\d{3}|504175|627780|636297|636368|65003[1-3]|6500(3[5-9]|4[0-9]|5[0-1])|6504(0[5-9]|[1-3][0-9])|650(4[8-9][0-9]|5[0-2][0-9]|53[0-8])|6505(4[1-9]|[5-8][0-9]|9[0-8])|6507(0[0-9]|1[0-8])|65072[0-7]|6509(0[1-9]|1[0-9]|20)|6516(5[2-9]|[6-7][0-9])|6550([0-1][0-9]|2[1-9]|[3-4][0-9]|5[0-8]))/).test(number);
1132
+ },
1133
+ };
1268
1134
 
1269
- const syncResponseFactoryToken = new InjectionToken('SyncResponse');
1270
- const syncResponseFactoryProvider = {
1271
- provide: syncResponseFactoryToken,
1272
- useValue: (...args) => new SyncResponse(...args),
1135
+ const aura = {
1136
+ id: CreditCardTypes.AURA,
1137
+ minLength: 16,
1138
+ maxLength: 19,
1139
+ iconName: 'aura',
1140
+ mask: defaultMask,
1141
+ checkNumber(number) {
1142
+ const subLength = 8;
1143
+ const cardNumberSub = number.substring(0, subLength);
1144
+ return ['50786000', '50786018', '50786019'].includes(cardNumberSub);
1145
+ },
1273
1146
  };
1274
1147
 
1275
- class SyncService extends EmitDataService {
1276
- constructor(requestFactory, responseFactory, secureApi, nextActionService, settingsService) {
1277
- super();
1278
- this.requestFactory = requestFactory;
1279
- this.responseFactory = responseFactory;
1280
- this.secureApi = secureApi;
1281
- this.nextActionService = nextActionService;
1282
- this.settingsService = settingsService;
1283
- this.apiRoute = 'directpayment';
1284
- this.prevFieldSyncStates = {};
1285
- this.form = new UntypedFormGroup({});
1286
- this.fields = [];
1287
- this.fieldAsyncValidation = new Subject();
1288
- }
1289
- get fieldAsyncValidation$() {
1290
- return this.fieldAsyncValidation.asObservable();
1148
+ const naranja = {
1149
+ id: CreditCardTypes.NARANJA,
1150
+ minLength: 12,
1151
+ maxLength: 19,
1152
+ iconName: 'naranja',
1153
+ mask: defaultMask,
1154
+ checkNumber(number) {
1155
+ const subLength = 6;
1156
+ const cardNumberSub = number.substring(0, subLength);
1157
+ return cardNumberSub === '589562';
1158
+ },
1159
+ };
1160
+
1161
+ const mir = {
1162
+ id: CreditCardTypes.MIR,
1163
+ minLength: 16,
1164
+ maxLength: 16,
1165
+ iconName: 'mir',
1166
+ mask: defaultMask,
1167
+ checkNumber(number) {
1168
+ const subLength = 4;
1169
+ const cardNumberSub = number.substring(0, subLength);
1170
+ return cardNumberSub >= '2200' && cardNumberSub <= '2204';
1171
+ },
1172
+ };
1173
+
1174
+ const chinaUnionPay = {
1175
+ id: CreditCardTypes.CHINA_UNION_PAY,
1176
+ minLength: 16,
1177
+ maxLength: 19,
1178
+ iconName: 'unionpay',
1179
+ mask: '999 9999 9999 99999999',
1180
+ checkNumber(number) {
1181
+ return number.startsWith('62');
1182
+ },
1183
+ };
1184
+
1185
+ const defaultCard = {
1186
+ id: CreditCardTypes.DEFAULT,
1187
+ minLength: 12,
1188
+ maxLength: 19,
1189
+ iconName: null,
1190
+ mask: defaultMask,
1191
+ checkNumber() {
1192
+ return false;
1193
+ },
1194
+ };
1195
+
1196
+ const postePay = {
1197
+ id: CreditCardTypes.POSTEPAY,
1198
+ minLength: 12,
1199
+ maxLength: 19,
1200
+ iconName: 'poste_pay',
1201
+ mask: '9999 9999 9999 9999 999',
1202
+ checkNumber(number) {
1203
+ const regex = /^(5018)|^(5020)|^(5038)|^(5893)|^(6304)|^(6759)|^(6761)|^(6762)|^(6763)|^(0604)|^(6706)|^(6771)|^(6709)/;
1204
+ return regex.test(number);
1205
+ },
1206
+ };
1207
+
1208
+ /**
1209
+ * order does matter
1210
+ * settings with more specific pattern should be placed above
1211
+ * Example:
1212
+ * - 12*
1213
+ * - 12
1214
+ * - 1
1215
+ * "12*" pattern should be checked first, otherwise pattern "1" will be taken
1216
+ * before "12*" checked
1217
+ */
1218
+ const orderedCardSettings = [
1219
+ aura,
1220
+ naranja,
1221
+ maestro,
1222
+ postePay,
1223
+ elo,
1224
+ discover,
1225
+ dankort,
1226
+ hipercard,
1227
+ mir,
1228
+ jcb,
1229
+ dinersClubs,
1230
+ americanExpress,
1231
+ mastercard,
1232
+ chinaUnionPay,
1233
+ visa,
1234
+ defaultCard,
1235
+ ];
1236
+
1237
+ const creditCardsMap = {
1238
+ [CreditCardTypes.DEFAULT]: defaultCard,
1239
+ [CreditCardTypes.VISA]: visa,
1240
+ [CreditCardTypes.MASTERCARD]: mastercard,
1241
+ [CreditCardTypes.MAESTRO]: maestro,
1242
+ [CreditCardTypes.AMERICAN_EXPRESS]: americanExpress,
1243
+ [CreditCardTypes.DINERS_CLUBS]: dinersClubs,
1244
+ [CreditCardTypes.DISCOVER]: discover,
1245
+ [CreditCardTypes.JCB]: jcb,
1246
+ [CreditCardTypes.DANKORT]: dankort,
1247
+ [CreditCardTypes.HIPERCARD]: hipercard,
1248
+ [CreditCardTypes.ELO]: elo,
1249
+ [CreditCardTypes.AURA]: aura,
1250
+ [CreditCardTypes.NARANJA]: naranja,
1251
+ [CreditCardTypes.MIR]: mir,
1252
+ [CreditCardTypes.CHINA_UNION_PAY]: chinaUnionPay,
1253
+ [CreditCardTypes.POSTEPAY]: postePay,
1254
+ };
1255
+
1256
+ class CreditCardService {
1257
+ getBinNumber(cardNumber) {
1258
+ const binNumberLength = 6;
1259
+ return cardNumber.replace(/\s+/g, '').substring(0, binNumberLength);
1291
1260
  }
1292
- setup(form, fields) {
1293
- this.reset();
1294
- this.form = form;
1295
- this.fields = fields;
1261
+ getAccountSuffix(cardNumber) {
1262
+ const accountSuffixLength = 4;
1263
+ return cardNumber
1264
+ .replace(/\s+/g, '')
1265
+ .substring(cardNumber.length - accountSuffixLength);
1296
1266
  }
1297
- reset() {
1298
- this.prevFieldSyncStates = {};
1299
- this.form = new UntypedFormGroup({});
1300
- this.fields = [];
1267
+ getTypeByNumber(cardNumber) {
1268
+ cardNumber = cardNumber.replace(/\s+/g, '');
1269
+ const cardSettings = orderedCardSettings.find((settings) => {
1270
+ const isNumberMatched = settings.checkNumber(cardNumber);
1271
+ return isNumberMatched ? settings.id : false;
1272
+ });
1273
+ return cardSettings ? cardSettings.id : defaultCard.id;
1301
1274
  }
1302
- validate(field) {
1303
- return __awaiter(this, void 0, void 0, function* () {
1304
- if (!this.isReadyField(field)) {
1305
- return Promise.resolve(null);
1306
- }
1307
- const control = this.form.get(field.name);
1308
- const value = control === null || control === void 0 ? void 0 : control.value;
1309
- const prevFieldState = this.getPrevFieldSyncState(field);
1310
- const isInitialValue = value === field.value && !prevFieldState;
1311
- if (isInitialValue) {
1312
- return Promise.resolve(null);
1313
- }
1314
- if (prevFieldState && value === prevFieldState.value) {
1315
- return Promise.resolve(prevFieldState.result).then((response) => {
1316
- var _a;
1317
- return (_a = response === null || response === void 0 ? void 0 : response.error) !== null && _a !== void 0 ? _a : null;
1318
- });
1319
- }
1320
- const requestPromise = this.request(field);
1321
- this.setPrevFieldSyncState(field, value, requestPromise);
1322
- return requestPromise.then((response) => {
1323
- var _a;
1324
- this.fieldAsyncValidation.next({
1325
- value,
1326
- field,
1327
- response,
1328
- });
1329
- return (_a = response.error) !== null && _a !== void 0 ? _a : null;
1330
- });
1275
+ getCreditCardSettings(cardType) {
1276
+ const creditCard = creditCardsMap[cardType];
1277
+ if (!creditCard) {
1278
+ return defaultCard;
1279
+ }
1280
+ return creditCard;
1281
+ }
1282
+ }
1283
+ CreditCardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1284
+ CreditCardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, providedIn: 'root' });
1285
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, decorators: [{
1286
+ type: Injectable,
1287
+ args: [{
1288
+ providedIn: 'root',
1289
+ }]
1290
+ }] });
1291
+
1292
+ class EncryptCreditCardService {
1293
+ constructor(creditCardService) {
1294
+ this.creditCardService = creditCardService;
1295
+ this.secureFieldNames = [
1296
+ 'xps_card_number',
1297
+ 'xps_cvv',
1298
+ 'xps_extra_cvv',
1299
+ 'xps_card_year',
1300
+ 'xps_card_month',
1301
+ ];
1302
+ this.jsEncrypt = new JSEncrypt();
1303
+ }
1304
+ setPublicKey(publicKey) {
1305
+ this.jsEncrypt.setPublicKey(publicKey);
1306
+ }
1307
+ encryptCreditCard(request) {
1308
+ if (request.xps_card_number) {
1309
+ const openCard = this.createOpenCard(request);
1310
+ request.xps_open_card = JSON.stringify(openCard);
1311
+ }
1312
+ const encryptedCard = this.createEncryptedCard(request);
1313
+ if (!request.xps_encrypted_card && JSON.stringify(encryptedCard) !== '{}') {
1314
+ request.xps_encrypted_card = this.encrypt(JSON.stringify(encryptedCard));
1315
+ }
1316
+ this.secureFieldNames.forEach((secureFieldName) => {
1317
+ delete request[secureFieldName];
1331
1318
  });
1319
+ return request;
1332
1320
  }
1333
- getSyncValidationErrors(field) {
1321
+ encrypt(value) {
1334
1322
  var _a;
1335
- const control = this.form.get(field.name);
1336
- return (_a = control === null || control === void 0 ? void 0 : control.errors) !== null && _a !== void 0 ? _a : null;
1323
+ if (!((_a = this.jsEncrypt) === null || _a === void 0 ? void 0 : _a.getPublicKey())) {
1324
+ throw new EncryptCreditCardError('Empty public key');
1325
+ }
1326
+ const encryptedValue = this.jsEncrypt.encrypt(value);
1327
+ if (!encryptedValue) {
1328
+ throw new EncryptCreditCardError('Encryption returns false instead of encrypted string');
1329
+ }
1330
+ return encryptedValue;
1331
+ }
1332
+ createEncryptedCard(request) {
1333
+ const encryptedCard = {
1334
+ card_number: request.xps_card_number,
1335
+ card_year: request.xps_card_year,
1336
+ card_month: request.xps_card_month,
1337
+ cvv: request.xps_cvv,
1338
+ };
1339
+ if (request.xps_extra_cvv) {
1340
+ encryptedCard.cvv = request.xps_extra_cvv;
1341
+ }
1342
+ return encryptedCard;
1337
1343
  }
1338
- request(field) {
1344
+ createOpenCard(request) {
1345
+ return {
1346
+ card_bin: this.creditCardService.getBinNumber(request.xps_card_number),
1347
+ card_suffix: this.creditCardService.getAccountSuffix(request.xps_card_number),
1348
+ card_year: request.xps_card_year,
1349
+ card_month: request.xps_card_month,
1350
+ };
1351
+ }
1352
+ }
1353
+ EncryptCreditCardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EncryptCreditCardService, deps: [{ token: CreditCardService }], target: i0.ɵɵFactoryTarget.Injectable });
1354
+ EncryptCreditCardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EncryptCreditCardService, providedIn: 'root' });
1355
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EncryptCreditCardService, decorators: [{
1356
+ type: Injectable,
1357
+ args: [{ providedIn: 'root' }]
1358
+ }], ctorParameters: function () { return [{ type: CreditCardService }]; } });
1359
+
1360
+ class InitializeService {
1361
+ constructor(responseFactory, xpsApiService, settingsService, countryService, nextActionService, encryptCreditCardService) {
1362
+ this.responseFactory = responseFactory;
1363
+ this.xpsApiService = xpsApiService;
1364
+ this.settingsService = settingsService;
1365
+ this.countryService = countryService;
1366
+ this.nextActionService = nextActionService;
1367
+ this.encryptCreditCardService = encryptCreditCardService;
1368
+ // TODO PAYMENTS-15743: replace with new refer id for headless core
1369
+ this.ps4ReferId = '22';
1370
+ }
1371
+ request(config) {
1339
1372
  return __awaiter(this, void 0, void 0, function* () {
1340
- const requestParams = this.requestFactory({
1341
- token: this.settingsService.token,
1342
- changedField: field,
1343
- fields: this.fields,
1344
- form: this.form,
1345
- });
1346
- return lastValueFrom(this.secureApi.post(this.apiRoute, new URLSearchParams(requestParams), {
1347
- headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
1348
- responseType: 'json',
1349
- })).then((response) => {
1350
- var _a;
1351
- if ((_a = response.errors) === null || _a === void 0 ? void 0 : _a.length) {
1352
- this.nextActionService.emitFlowUpdates(new ShowErrorsAction(response.errors));
1373
+ const requestParams = {
1374
+ access_token: this.settingsService.token,
1375
+ pid: String(config.paymentMethodId),
1376
+ refer: this.ps4ReferId,
1377
+ country: this.countryService.getCountry(),
1378
+ returnUrl: config.returnUrl,
1379
+ };
1380
+ return this.xpsApiService
1381
+ .directPaymentRequest(requestParams)
1382
+ .then((response) => {
1383
+ var _a, _b;
1384
+ const initializeResponse = this.responseFactory(response);
1385
+ if ((_b = (_a = initializeResponse.paymentForm) === null || _a === void 0 ? void 0 : _a.errors) === null || _b === void 0 ? void 0 : _b.length) {
1386
+ this.nextActionService.emitFlowUpdates(new ShowErrorsAction(initializeResponse.paymentForm.errors));
1353
1387
  }
1354
- this.emit(response);
1355
- return this.responseFactory(field, response);
1388
+ if (initializeResponse.paymentForm) {
1389
+ this.setCreditCardEncryptKey(initializeResponse.paymentForm);
1390
+ }
1391
+ return initializeResponse;
1392
+ })
1393
+ .catch((error) => {
1394
+ throw new ResponseError(error.message);
1356
1395
  });
1357
1396
  });
1358
1397
  }
1359
- isReadyField(field) {
1360
- var _a, _b;
1361
- const isSyncEnabled = !!((_a = field.javascript) === null || _a === void 0 ? void 0 : _a.change);
1362
- const isExistsInForm = !!((_b = this.form) === null || _b === void 0 ? void 0 : _b.get(field.name));
1363
- return isSyncEnabled && isExistsInForm;
1364
- }
1365
- getPrevFieldSyncState(field) {
1366
- return this.prevFieldSyncStates[field.name];
1367
- }
1368
- setPrevFieldSyncState(field, value, result) {
1369
- this.prevFieldSyncStates[field.name] = { value, result };
1398
+ setCreditCardEncryptKey(paymentForm) {
1399
+ const publicKeyField = paymentForm.fields.find((field) => field.name === 'public_key');
1400
+ if (!publicKeyField) {
1401
+ return;
1402
+ }
1403
+ this.encryptCreditCardService.setPublicKey(atob(publicKeyField.value));
1370
1404
  }
1371
1405
  }
1372
- SyncService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, deps: [{ token: syncRequestFactoryToken }, { token: syncResponseFactoryToken }, { token: SecureApiClient }, { token: NextActionService }, { token: SettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
1373
- SyncService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, providedIn: 'root' });
1374
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, decorators: [{
1406
+ InitializeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, deps: [{ token: initializeResponseFactoryToken }, { token: XpsApiService }, { token: SettingsService }, { token: CountryService }, { token: NextActionService }, { token: EncryptCreditCardService }], target: i0.ɵɵFactoryTarget.Injectable });
1407
+ InitializeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, providedIn: 'root' });
1408
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, decorators: [{
1375
1409
  type: Injectable,
1376
1410
  args: [{
1377
1411
  providedIn: 'root',
@@ -1379,561 +1413,613 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
1379
1413
  }], ctorParameters: function () {
1380
1414
  return [{ type: undefined, decorators: [{
1381
1415
  type: Inject,
1382
- args: [syncRequestFactoryToken]
1383
- }] }, { type: undefined, decorators: [{
1384
- type: Inject,
1385
- args: [syncResponseFactoryToken]
1386
- }] }, { type: SecureApiClient }, { type: NextActionService }, { type: SettingsService }];
1416
+ args: [initializeResponseFactoryToken]
1417
+ }] }, { type: XpsApiService }, { type: SettingsService }, { type: CountryService }, { type: NextActionService }, { type: EncryptCreditCardService }];
1387
1418
  } });
1388
1419
 
1389
- class ControlConfig {
1390
- constructor() {
1391
- this.shouldHideUserInput = false;
1420
+ class XpsApiPartRequest {
1421
+ addXpsParameters(parameters) {
1422
+ for (const key in parameters) {
1423
+ this[`xps_${key}`] = parameters[key];
1424
+ }
1392
1425
  }
1393
1426
  }
1394
1427
 
1395
- class TextControlConfig extends ControlConfig {
1428
+ class TokenError extends AppError {
1396
1429
  constructor() {
1397
- super(...arguments);
1398
- this.controlType = 'text';
1430
+ super('XPS API needs token.');
1399
1431
  }
1400
1432
  }
1401
1433
 
1402
- function convert(validator, message) {
1403
- return (control) => {
1404
- const errors = validator(control);
1405
- if (!errors) {
1406
- return errors;
1434
+ class SubmitRequest extends XpsApiPartRequest {
1435
+ constructor(parameters) {
1436
+ super();
1437
+ const { token, fields, form, dfpHash } = parameters;
1438
+ if (token === null) {
1439
+ throw new TokenError();
1407
1440
  }
1408
- const firstErrorKey = Object.keys(errors)[0];
1409
- const firstError = errors[firstErrorKey];
1410
- const error = typeof firstError === 'object' && firstError !== null ? firstError : {};
1411
- error.message = message;
1412
- errors[firstErrorKey] = error;
1413
- return errors;
1414
- };
1441
+ this.access_token = token;
1442
+ if (dfpHash) {
1443
+ this.xps_dfp_hash = dfpHash;
1444
+ }
1445
+ this.addXpsParameters(this.getFieldsValues(fields, form));
1446
+ }
1447
+ getFieldsValues(fields, form) {
1448
+ return fields.reduce((xpsParams, field) => {
1449
+ const formControl = form.get(field.name);
1450
+ xpsParams[field.name] = formControl ? formControl.value : field === null || field === void 0 ? void 0 : field.value;
1451
+ return xpsParams;
1452
+ }, {});
1453
+ }
1415
1454
  }
1416
1455
 
1417
- const emailRegexp = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i; // eslint-disable-line
1418
- function convertedEmailValidator() {
1419
- return convert(Validators.pattern(emailRegexp), 'Enter a valid email');
1420
- }
1456
+ const submitRequestFactoryToken = new InjectionToken('SubmitRequest');
1457
+ const submitRequestFactoryProvider = {
1458
+ provide: submitRequestFactoryToken,
1459
+ useValue: (...args) => new SubmitRequest(...args),
1460
+ };
1421
1461
 
1422
- function convertedRequiredValidator() {
1423
- return convert(Validators.required, 'Required');
1424
- }
1462
+ const submitResponseFactoryToken = new InjectionToken('SubmitResponse');
1463
+ const submitResponseFactoryProvider = {
1464
+ provide: submitResponseFactoryToken,
1465
+ useValue: (...args) => new SubmitResponse(...args),
1466
+ };
1425
1467
 
1426
- class Converter {
1427
- constructor(syncService) {
1428
- this.syncService = syncService;
1429
- }
1430
- convertToConfig(field, formState) {
1431
- const config = this.createControlConfig(field, formState);
1432
- if (formState === null || formState === void 0 ? void 0 : formState.disabled) {
1433
- config.disabled = true;
1434
- }
1435
- return config;
1436
- }
1437
- convertToFormControl(field) {
1438
- return new UntypedFormControl(this.getValue(field), this.getValidators(field), this.getAsyncValidators(field));
1468
+ class DeviceFingerPrintService {
1469
+ constructor(settingsService) {
1470
+ this.settingsService = settingsService;
1439
1471
  }
1440
- getValidators(field) {
1441
- const validators = [];
1442
- if (field.isMandatory === "1" /* XpsBoolean.true */) {
1443
- validators.push(convertedRequiredValidator());
1444
- }
1445
- if (field.regex) {
1446
- const match = /^\/(.*)\/([gim]*)$/.exec(field.regex);
1447
- if (match) {
1448
- const pattern = new RegExp(match[1], match[2]);
1449
- const errorMessage = field.validation_error_msg
1450
- ? field.validation_error_msg
1451
- : 'Enter valid data';
1452
- validators.push(convert(Validators.pattern(pattern), errorMessage));
1453
- }
1472
+ init() {
1473
+ if (!this.settingsService.isInitialized) {
1474
+ return;
1454
1475
  }
1455
- return validators;
1456
- }
1457
- getAsyncValidators(field) {
1458
- return () => __awaiter(this, void 0, void 0, function* () { return this.syncService.validate(field); });
1459
- }
1460
- createDefaultControlConfig(controlConfigClass, field) {
1461
- const config = new controlConfigClass();
1462
- this.copyCommonOptions(config, field);
1463
- return config;
1464
- }
1465
- getValue(field) {
1466
- return field.value;
1476
+ this.antifraudFingerprintLibrary = this.loadAntifraudFingerprintLibrary();
1477
+ this.hash = this.buildHash();
1467
1478
  }
1468
- getDataType() {
1469
- return 'text';
1479
+ getHash() {
1480
+ return __awaiter(this, void 0, void 0, function* () {
1481
+ return this.hash;
1482
+ });
1470
1483
  }
1471
- getAutocomplete() {
1472
- return 'off';
1484
+ loadAntifraudFingerprintLibrary() {
1485
+ return __awaiter(this, void 0, void 0, function* () {
1486
+ const library = yield import('@xsolla/antifraud-fingerprint');
1487
+ return library.AntifraudFingerprint;
1488
+ });
1473
1489
  }
1474
- shouldHideUserInput() {
1475
- return false;
1490
+ buildHash() {
1491
+ return __awaiter(this, void 0, void 0, function* () {
1492
+ const hash = yield this.generate();
1493
+ return JSON.stringify(hash);
1494
+ });
1476
1495
  }
1477
- getCommonControlConfig(field) {
1478
- return {
1479
- name: field.name,
1480
- title: field.title,
1481
- labelHint: field.label_hint,
1482
- dataType: this.getDataType(),
1483
- readonly: field.isReadonly === "1" /* XpsBoolean.true */,
1484
- placeholder: field.example,
1485
- autocomplete: this.getAutocomplete(),
1486
- };
1496
+ generate() {
1497
+ return __awaiter(this, void 0, void 0, function* () {
1498
+ const fingerprint = yield this.makeAntifraudFingerprint();
1499
+ if (!fingerprint) {
1500
+ return null;
1501
+ }
1502
+ yield fingerprint.dispatch().catch((err) => console.log(err));
1503
+ const afsHash = yield fingerprint.hash();
1504
+ return { '301': afsHash };
1505
+ });
1487
1506
  }
1488
- copyCommonOptions(target, field) {
1489
- const commonControlConfig = this.getCommonControlConfig(field);
1490
- Object.keys(commonControlConfig).forEach((sourceKey) => {
1491
- if (!(sourceKey in target)) {
1492
- target[sourceKey] = commonControlConfig[sourceKey];
1507
+ makeAntifraudFingerprint() {
1508
+ return __awaiter(this, void 0, void 0, function* () {
1509
+ if (!this.settingsService.token) {
1510
+ return null;
1511
+ }
1512
+ const antifraudFingerprint = yield this
1513
+ .antifraudFingerprintLibrary;
1514
+ try {
1515
+ return new antifraudFingerprint({
1516
+ api: {
1517
+ url: 'https://afs.xsolla.com/dfp/api/v1/',
1518
+ token: this.settingsService.token,
1519
+ timeout: 3000,
1520
+ },
1521
+ retry: {
1522
+ num: 1,
1523
+ timeout: 500,
1524
+ },
1525
+ });
1526
+ }
1527
+ catch (error) {
1528
+ return null;
1493
1529
  }
1494
1530
  });
1495
1531
  }
1496
1532
  }
1533
+ DeviceFingerPrintService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, deps: [{ token: SettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
1534
+ DeviceFingerPrintService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, providedIn: 'root' });
1535
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, decorators: [{
1536
+ type: Injectable,
1537
+ args: [{
1538
+ providedIn: 'root',
1539
+ }]
1540
+ }], ctorParameters: function () { return [{ type: SettingsService }]; } });
1497
1541
 
1498
- class EmailConverter extends Converter {
1499
- constructor(syncService) {
1500
- super(syncService);
1542
+ class SubmitService {
1543
+ constructor(requestFactory, responseFactory, settingsService, deviceFingerPrintService, xpsApiService, encryptCreditCardService) {
1544
+ this.requestFactory = requestFactory;
1545
+ this.responseFactory = responseFactory;
1546
+ this.settingsService = settingsService;
1547
+ this.deviceFingerPrintService = deviceFingerPrintService;
1548
+ this.xpsApiService = xpsApiService;
1549
+ this.encryptCreditCardService = encryptCreditCardService;
1501
1550
  }
1502
- getValidators(field) {
1503
- return super.getValidators(field).concat([convertedEmailValidator()]);
1551
+ // NB: Never add 'async' statement for this method!
1552
+ // 'Async' statement wraps current promise into another.
1553
+ // In this way two promises become unequal, that can broke XPS API requests logic.
1554
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
1555
+ request(fields, form) {
1556
+ return (this.deviceFingerPrintService
1557
+ .getHash()
1558
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
1559
+ .then((dfpHash) => {
1560
+ const requestParams = this.requestFactory({
1561
+ token: this.settingsService.token,
1562
+ fields,
1563
+ form,
1564
+ dfpHash,
1565
+ });
1566
+ const encryptedRequest = this.encryptCreditCardService.encryptCreditCard(requestParams);
1567
+ return this.xpsApiService
1568
+ .directPaymentRequest(encryptedRequest)
1569
+ .then((response) => this.responseFactory(response))
1570
+ .catch((error) => {
1571
+ throw new ResponseError(error.message);
1572
+ });
1573
+ }));
1504
1574
  }
1505
- createControlConfig(field) {
1506
- const config = this.createDefaultControlConfig(TextControlConfig, field);
1507
- config.autocomplete = 'email';
1508
- config.icon = 'mail';
1509
- return config;
1575
+ }
1576
+ SubmitService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, deps: [{ token: submitRequestFactoryToken }, { token: submitResponseFactoryToken }, { token: SettingsService }, { token: DeviceFingerPrintService }, { token: XpsApiService }, { token: EncryptCreditCardService }], target: i0.ɵɵFactoryTarget.Injectable });
1577
+ SubmitService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, providedIn: 'root' });
1578
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, decorators: [{
1579
+ type: Injectable,
1580
+ args: [{ providedIn: 'root' }]
1581
+ }], ctorParameters: function () {
1582
+ return [{ type: undefined, decorators: [{
1583
+ type: Inject,
1584
+ args: [submitRequestFactoryToken]
1585
+ }] }, { type: undefined, decorators: [{
1586
+ type: Inject,
1587
+ args: [submitResponseFactoryToken]
1588
+ }] }, { type: SettingsService }, { type: DeviceFingerPrintService }, { type: XpsApiService }, { type: EncryptCreditCardService }];
1589
+ } });
1590
+
1591
+ class EmitDataService {
1592
+ constructor() {
1593
+ this.dataSubject = new Subject();
1594
+ this.data$ = this.dataSubject.asObservable();
1510
1595
  }
1511
- getDataType() {
1512
- return 'email';
1596
+ emit(data) {
1597
+ this.dataSubject.next(data);
1513
1598
  }
1514
1599
  }
1515
- EmailConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
1516
- EmailConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter });
1517
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter, decorators: [{
1518
- type: Injectable
1519
- }], ctorParameters: function () { return [{ type: SyncService }]; } });
1520
-
1521
- const restrictedValueValidator = (restrictedValue) => {
1522
- return ({ value }) => {
1523
- return value !== restrictedValue ? null : { valueAllowed: false };
1524
- };
1525
- };
1526
1600
 
1527
- class ZipConverter extends Converter {
1528
- constructor(syncService, countryService) {
1529
- super(syncService);
1530
- this.countryService = countryService;
1531
- this.minLength = 3;
1532
- this.maxLength = 10;
1533
- this.usCountryLength = 5;
1534
- }
1535
- get isUsCountry() {
1536
- return this.countryService.getCountry() === 'US';
1601
+ /* eslint-disable @typescript-eslint/naming-convention */
1602
+ class SyncRequest extends XpsApiPartRequest {
1603
+ constructor(parameters) {
1604
+ super();
1605
+ this.xps_fix_command = 'calculate';
1606
+ this.access_token = parameters.token;
1607
+ const fieldsValues = this.getFieldsValues(parameters.changedField, parameters.fields, parameters.form);
1608
+ this.addXpsParameters(Object.assign(Object.assign({}, fieldsValues), { change_element: parameters.changedField.name }));
1537
1609
  }
1538
- getValidators(field) {
1539
- const minLength = this.isUsCountry ? this.usCountryLength : this.minLength;
1540
- const maxLength = this.isUsCountry ? this.usCountryLength : this.maxLength;
1541
- const validators = super
1542
- .getValidators(field)
1543
- .concat([
1544
- convert(Validators.minLength(minLength), `Enter at least ${minLength} characters`),
1545
- convert(Validators.maxLength(maxLength), `Enter no more than ${maxLength} characters`),
1546
- ]);
1547
- if (this.isUsCountry) {
1548
- validators.push(convert(restrictedValueValidator('00000'), 'Enter a valid ZIP code'));
1549
- }
1550
- return validators;
1551
- }
1552
- createControlConfig(field) {
1553
- const config = this.createDefaultControlConfig(TextControlConfig, field);
1554
- config.icon = 'location';
1555
- if (this.isUsCountry) {
1556
- config.maskConfig = {
1557
- guide: false,
1558
- unmaskModelValue: true,
1559
- showMask: true,
1560
- };
1561
- config.inputMode = 'numeric';
1562
- if (masksFunctionsMap['zip']) {
1563
- config.maskConfig.mask = masksFunctionsMap['zip'];
1610
+ getFieldsValues(changedField, fields, form) {
1611
+ var _a;
1612
+ const fieldsMap = this.getFieldsMap(fields);
1613
+ return (_a = changedField === null || changedField === void 0 ? void 0 : changedField.javascript) === null || _a === void 0 ? void 0 : _a.change.params.reduce((xpsParams, fieldName) => {
1614
+ var _a;
1615
+ const formControl = form.get(fieldName);
1616
+ const field = fieldsMap.get(fieldName);
1617
+ if (formControl || field) {
1618
+ xpsParams[fieldName] = (_a = formControl === null || formControl === void 0 ? void 0 : formControl.value) !== null && _a !== void 0 ? _a : field === null || field === void 0 ? void 0 : field.value;
1564
1619
  }
1565
- }
1566
- else {
1567
- config.maxLength = this.maxLength;
1568
- }
1569
- return config;
1570
- }
1571
- getAutocomplete() {
1572
- return 'postal-code';
1620
+ return xpsParams;
1621
+ }, {});
1573
1622
  }
1574
- getDataType() {
1575
- return 'text';
1623
+ getFieldsMap(fields) {
1624
+ const map = new Map();
1625
+ fields.forEach((field) => map.set(field.name, field));
1626
+ return map;
1576
1627
  }
1577
1628
  }
1578
- ZipConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ZipConverter, deps: [{ token: SyncService }, { token: CountryService }], target: i0.ɵɵFactoryTarget.Injectable });
1579
- ZipConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ZipConverter });
1580
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ZipConverter, decorators: [{
1581
- type: Injectable
1582
- }], ctorParameters: function () { return [{ type: SyncService }, { type: CountryService }]; } });
1583
1629
 
1584
- function isEmptyInputValue(value) {
1585
- return value == null || value.length === 0;
1586
- }
1630
+ const syncRequestFactoryToken = new InjectionToken('SyncRequest');
1631
+ const syncRequestFactoryProvider = {
1632
+ provide: syncRequestFactoryToken,
1633
+ useValue: (...args) => new SyncRequest(...args),
1634
+ };
1587
1635
 
1588
- function isString(value) {
1589
- return typeof value === 'string';
1636
+ class SyncResponse {
1637
+ constructor(changedField, response) {
1638
+ var _a;
1639
+ this.error = null;
1640
+ const fieldError = (_a = response === null || response === void 0 ? void 0 : response.errors) === null || _a === void 0 ? void 0 : _a.find((error) => error.element_name === changedField.name);
1641
+ if (fieldError) {
1642
+ this.error = {
1643
+ asyncError: {
1644
+ code: fieldError.code,
1645
+ message: fieldError.message,
1646
+ },
1647
+ };
1648
+ }
1649
+ this.fields = Object.keys(response.form).map((key) => response.form[key]);
1650
+ this.parameters = response;
1651
+ }
1590
1652
  }
1591
1653
 
1592
- /**
1593
- * Checks number match Luhn algorithm.
1594
- * Based on http://en.wikipedia.org/wiki/Luhn.
1595
- */
1596
- const luhnFormulaValidator = ({ value }) => {
1597
- if (isEmptyInputValue(value) || !isString(value)) {
1598
- return null;
1654
+ const syncResponseFactoryToken = new InjectionToken('SyncResponse');
1655
+ const syncResponseFactoryProvider = {
1656
+ provide: syncResponseFactoryToken,
1657
+ useValue: (...args) => new SyncResponse(...args),
1658
+ };
1659
+
1660
+ class SyncService extends EmitDataService {
1661
+ constructor(requestFactory, responseFactory, xpsApiService, nextActionService, settingsService, encryptCreditCardService) {
1662
+ super();
1663
+ this.requestFactory = requestFactory;
1664
+ this.responseFactory = responseFactory;
1665
+ this.xpsApiService = xpsApiService;
1666
+ this.nextActionService = nextActionService;
1667
+ this.settingsService = settingsService;
1668
+ this.encryptCreditCardService = encryptCreditCardService;
1669
+ this.prevFieldSyncStates = {};
1670
+ this.form = new UntypedFormGroup({});
1671
+ this.fields = [];
1672
+ this.fieldAsyncValidation = new Subject();
1599
1673
  }
1600
- const error = {
1601
- rewritableError: {
1602
- message: `Enter a valid card number`,
1603
- },
1604
- };
1605
- if (/[^0-9 -]+/.test(value)) {
1606
- // accept only spaces, digits and dashes
1607
- return error;
1674
+ get fieldAsyncValidation$() {
1675
+ return this.fieldAsyncValidation.asObservable();
1608
1676
  }
1609
- let resultSum = 0;
1610
- let digit = 0;
1611
- let isEven = false;
1612
- const modBase = 10;
1613
- const digitRadix = 10;
1614
- const maxNumber = 9;
1615
- const digits = value.replace(/\D/g, '');
1616
- // Checks if number match Luhn algorithm
1617
- // based on http://en.wikipedia.org/wiki/Luhn
1618
- for (let index = digits.length - 1; index >= 0; index--) {
1619
- const char = digits.charAt(index);
1620
- digit = parseInt(char, digitRadix);
1621
- if (isEven && (digit *= 2) > maxNumber) {
1622
- digit -= maxNumber;
1623
- }
1624
- resultSum += digit;
1625
- isEven = !isEven;
1677
+ setup(form, fields) {
1678
+ this.reset();
1679
+ this.form = form;
1680
+ this.fields = fields;
1626
1681
  }
1627
- return resultSum % modBase === 0 ? null : error;
1628
- };
1682
+ reset() {
1683
+ this.prevFieldSyncStates = {};
1684
+ this.form = new UntypedFormGroup({});
1685
+ this.fields = [];
1686
+ }
1687
+ validate(field) {
1688
+ return __awaiter(this, void 0, void 0, function* () {
1689
+ if (!this.isReadyField(field)) {
1690
+ return Promise.resolve(null);
1691
+ }
1692
+ const control = this.form.get(field.name);
1693
+ const value = control === null || control === void 0 ? void 0 : control.value;
1694
+ const prevFieldState = this.getPrevFieldSyncState(field);
1695
+ const isInitialValue = value === field.value && !prevFieldState;
1696
+ if (isInitialValue) {
1697
+ return Promise.resolve(null);
1698
+ }
1699
+ if (prevFieldState && value === prevFieldState.value) {
1700
+ return Promise.resolve(prevFieldState.result).then((response) => {
1701
+ var _a;
1702
+ return (_a = response === null || response === void 0 ? void 0 : response.error) !== null && _a !== void 0 ? _a : null;
1703
+ });
1704
+ }
1705
+ const requestPromise = this.request(field);
1706
+ this.setPrevFieldSyncState(field, value, requestPromise);
1707
+ return requestPromise.then((response) => {
1708
+ var _a;
1709
+ this.fieldAsyncValidation.next({
1710
+ value,
1711
+ field,
1712
+ response,
1713
+ });
1714
+ return (_a = response.error) !== null && _a !== void 0 ? _a : null;
1715
+ });
1716
+ });
1717
+ }
1718
+ getSyncValidationErrors(field) {
1719
+ var _a;
1720
+ const control = this.form.get(field.name);
1721
+ return (_a = control === null || control === void 0 ? void 0 : control.errors) !== null && _a !== void 0 ? _a : null;
1722
+ }
1723
+ request(field) {
1724
+ return __awaiter(this, void 0, void 0, function* () {
1725
+ const requestParams = this.requestFactory({
1726
+ token: this.settingsService.token,
1727
+ changedField: field,
1728
+ fields: this.fields,
1729
+ form: this.form,
1730
+ });
1731
+ const encryptedRequest = this.encryptCreditCardService.encryptCreditCard(requestParams);
1732
+ return this.xpsApiService
1733
+ .directPaymentRequest(encryptedRequest)
1734
+ .then((response) => {
1735
+ var _a;
1736
+ if ((_a = response.errors) === null || _a === void 0 ? void 0 : _a.length) {
1737
+ this.nextActionService.emitFlowUpdates(new ShowErrorsAction(response.errors));
1738
+ }
1739
+ this.emit(response);
1740
+ return this.responseFactory(field, response);
1741
+ });
1742
+ });
1743
+ }
1744
+ isReadyField(field) {
1745
+ var _a, _b;
1746
+ const isSyncEnabled = !!((_a = field.javascript) === null || _a === void 0 ? void 0 : _a.change);
1747
+ const isExistsInForm = !!((_b = this.form) === null || _b === void 0 ? void 0 : _b.get(field.name));
1748
+ return isSyncEnabled && isExistsInForm;
1749
+ }
1750
+ getPrevFieldSyncState(field) {
1751
+ return this.prevFieldSyncStates[field.name];
1752
+ }
1753
+ setPrevFieldSyncState(field, value, result) {
1754
+ this.prevFieldSyncStates[field.name] = { value, result };
1755
+ }
1756
+ }
1757
+ SyncService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, deps: [{ token: syncRequestFactoryToken }, { token: syncResponseFactoryToken }, { token: XpsApiService }, { token: NextActionService }, { token: SettingsService }, { token: EncryptCreditCardService }], target: i0.ɵɵFactoryTarget.Injectable });
1758
+ SyncService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, providedIn: 'root' });
1759
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, decorators: [{
1760
+ type: Injectable,
1761
+ args: [{
1762
+ providedIn: 'root',
1763
+ }]
1764
+ }], ctorParameters: function () {
1765
+ return [{ type: undefined, decorators: [{
1766
+ type: Inject,
1767
+ args: [syncRequestFactoryToken]
1768
+ }] }, { type: undefined, decorators: [{
1769
+ type: Inject,
1770
+ args: [syncResponseFactoryToken]
1771
+ }] }, { type: XpsApiService }, { type: NextActionService }, { type: SettingsService }, { type: EncryptCreditCardService }];
1772
+ } });
1629
1773
 
1630
- class CardNumberConfig extends ControlConfig {
1774
+ class ControlConfig {
1775
+ constructor() {
1776
+ this.shouldHideUserInput = false;
1777
+ }
1778
+ }
1779
+
1780
+ class TextControlConfig extends ControlConfig {
1631
1781
  constructor() {
1632
1782
  super(...arguments);
1633
- this.controlType = 'card-number';
1634
- this.availableCardTypes = [];
1635
- this.customError = '';
1783
+ this.controlType = 'text';
1636
1784
  }
1637
1785
  }
1638
1786
 
1639
- const fourBlockMask = '9999 9999 9999 9999';
1787
+ function convert(validator, message) {
1788
+ return (control) => {
1789
+ const errors = validator(control);
1790
+ if (!errors) {
1791
+ return errors;
1792
+ }
1793
+ const firstErrorKey = Object.keys(errors)[0];
1794
+ const firstError = errors[firstErrorKey];
1795
+ const error = typeof firstError === 'object' && firstError !== null ? firstError : {};
1796
+ error.message = message;
1797
+ errors[firstErrorKey] = error;
1798
+ return errors;
1799
+ };
1800
+ }
1640
1801
 
1641
- var CreditCardTypes;
1642
- (function (CreditCardTypes) {
1643
- CreditCardTypes["DEFAULT"] = "0";
1644
- CreditCardTypes["VISA"] = "1";
1645
- CreditCardTypes["MASTERCARD"] = "2";
1646
- CreditCardTypes["MAESTRO"] = "3";
1647
- CreditCardTypes["AMERICAN_EXPRESS"] = "4";
1648
- CreditCardTypes["DINERS_CLUBS"] = "5";
1649
- CreditCardTypes["DISCOVER"] = "6";
1650
- CreditCardTypes["JCB"] = "9";
1651
- CreditCardTypes["DANKORT"] = "11";
1652
- CreditCardTypes["HIPERCARD"] = "12";
1653
- CreditCardTypes["ELO"] = "13";
1654
- CreditCardTypes["AURA"] = "14";
1655
- CreditCardTypes["NARANJA"] = "15";
1656
- CreditCardTypes["MIR"] = "16";
1657
- CreditCardTypes["CHINA_UNION_PAY"] = "17";
1658
- CreditCardTypes["POSTEPAY"] = "18";
1659
- })(CreditCardTypes || (CreditCardTypes = {}));
1660
-
1661
- const visa = {
1662
- id: CreditCardTypes.VISA,
1663
- minLength: 13,
1664
- maxLength: 16,
1665
- iconName: 'visa',
1666
- mask: fourBlockMask,
1667
- checkNumber(number) {
1668
- return number.startsWith('4');
1669
- },
1670
- };
1671
-
1672
- const mastercard = {
1673
- id: CreditCardTypes.MASTERCARD,
1674
- minLength: 16,
1675
- maxLength: 16,
1676
- iconName: 'mastercard',
1677
- mask: fourBlockMask,
1678
- checkNumber(number) {
1679
- const subLength = 6;
1680
- const cardNumberSub = number.substring(0, subLength);
1681
- return (new RegExp(/^5[1-5]/).test(number) ||
1682
- (cardNumberSub >= '222100' && cardNumberSub <= '272099'));
1683
- },
1684
- };
1685
-
1686
- const defaultMask = '9999 9999 9999 9999 999';
1687
-
1688
- const maestro = {
1689
- id: CreditCardTypes.MAESTRO,
1690
- minLength: 12,
1691
- maxLength: 19,
1692
- iconName: 'maestro',
1693
- mask: defaultMask,
1694
- checkNumber(number) {
1695
- return new RegExp(/^(5018)|^(5020)|^(5038)|^(5893)|^(6304)|^(6759)|^(6761)|^(6762)|^(6763)|^(0604)|^(6706)|^(6771)|^(6709)/).test(number);
1696
- },
1697
- maxCvvLength: 3,
1698
- };
1699
-
1700
- const americanExpress = {
1701
- id: CreditCardTypes.AMERICAN_EXPRESS,
1702
- minLength: 15,
1703
- maxLength: 15,
1704
- iconName: 'american-express',
1705
- mask: '9999 999999 99999',
1706
- checkNumber(number) {
1707
- return new RegExp(/^(34)|^(37)/).test(number);
1708
- },
1709
- maxCvvLength: 4,
1710
- };
1711
-
1712
- const dinersClubs = {
1713
- id: CreditCardTypes.DINERS_CLUBS,
1714
- minLength: 14,
1715
- maxLength: 14,
1716
- iconName: 'dinersclub',
1717
- mask: '9999 9999 9999 99',
1718
- checkNumber(number) {
1719
- const regex = /^(36[0-9]|3(?:0[0-59]|[68][0-9])[0-9])/;
1720
- return regex.test(number);
1721
- },
1722
- };
1723
-
1724
- const discover = {
1725
- id: CreditCardTypes.DISCOVER,
1726
- minLength: 16,
1727
- maxLength: 19,
1728
- iconName: 'discover',
1729
- mask: defaultMask,
1730
- checkNumber(number) {
1731
- return new RegExp(/^(6011)|^(622(1(2[6-9]|[3-9][0-9])|[2-8][0-9]{2}|9([01][0-9]|2[0-5])))|^(64[4-9])|^65/).test(number);
1732
- },
1733
- };
1734
-
1735
- const jcb = {
1736
- id: CreditCardTypes.JCB,
1737
- minLength: 15,
1738
- maxLength: 16,
1739
- iconName: 'jcb',
1740
- mask: fourBlockMask,
1741
- checkNumber(number) {
1742
- return new RegExp(/^35(2[89]|[3-8][0-9])/).test(number);
1743
- },
1744
- };
1745
-
1746
- const dankort = {
1747
- id: CreditCardTypes.DANKORT,
1748
- minLength: 16,
1749
- maxLength: 16,
1750
- iconName: 'dankort',
1751
- mask: fourBlockMask,
1752
- checkNumber(number) {
1753
- const subLength = 4;
1754
- const cardNumberSub = number.substring(0, subLength);
1755
- return cardNumberSub === '5019';
1756
- },
1757
- };
1758
-
1759
- const hipercard = {
1760
- id: CreditCardTypes.HIPERCARD,
1761
- minLength: 13,
1762
- maxLength: 19,
1763
- iconName: 'hipercard',
1764
- mask: defaultMask,
1765
- checkNumber(number) {
1766
- return new RegExp(/^((606282|637095|637568)[0-9]|38[0-9]{14,17})/).test(number);
1767
- },
1768
- };
1769
-
1770
- const elo = {
1771
- id: CreditCardTypes.ELO,
1772
- minLength: 16,
1773
- maxLength: 19,
1774
- iconName: 'elo',
1775
- mask: defaultMask,
1776
- checkNumber(number) {
1777
- return new RegExp(/^(40117[8-9]|431274|438935|451416|457393|45763[1-2]|506(699|7[0-6][0-9]|77[0-8])|509\d{3}|504175|627780|636297|636368|65003[1-3]|6500(3[5-9]|4[0-9]|5[0-1])|6504(0[5-9]|[1-3][0-9])|650(4[8-9][0-9]|5[0-2][0-9]|53[0-8])|6505(4[1-9]|[5-8][0-9]|9[0-8])|6507(0[0-9]|1[0-8])|65072[0-7]|6509(0[1-9]|1[0-9]|20)|6516(5[2-9]|[6-7][0-9])|6550([0-1][0-9]|2[1-9]|[3-4][0-9]|5[0-8]))/).test(number);
1778
- },
1779
- };
1780
-
1781
- const aura = {
1782
- id: CreditCardTypes.AURA,
1783
- minLength: 16,
1784
- maxLength: 19,
1785
- iconName: 'aura',
1786
- mask: defaultMask,
1787
- checkNumber(number) {
1788
- const subLength = 8;
1789
- const cardNumberSub = number.substring(0, subLength);
1790
- return ['50786000', '50786018', '50786019'].includes(cardNumberSub);
1791
- },
1792
- };
1793
-
1794
- const naranja = {
1795
- id: CreditCardTypes.NARANJA,
1796
- minLength: 12,
1797
- maxLength: 19,
1798
- iconName: 'naranja',
1799
- mask: defaultMask,
1800
- checkNumber(number) {
1801
- const subLength = 6;
1802
- const cardNumberSub = number.substring(0, subLength);
1803
- return cardNumberSub === '589562';
1804
- },
1805
- };
1806
-
1807
- const mir = {
1808
- id: CreditCardTypes.MIR,
1809
- minLength: 16,
1810
- maxLength: 16,
1811
- iconName: 'mir',
1812
- mask: defaultMask,
1813
- checkNumber(number) {
1814
- const subLength = 4;
1815
- const cardNumberSub = number.substring(0, subLength);
1816
- return cardNumberSub >= '2200' && cardNumberSub <= '2204';
1817
- },
1818
- };
1802
+ const emailRegexp = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i; // eslint-disable-line
1803
+ function convertedEmailValidator() {
1804
+ return convert(Validators.pattern(emailRegexp), 'Enter a valid email');
1805
+ }
1819
1806
 
1820
- const chinaUnionPay = {
1821
- id: CreditCardTypes.CHINA_UNION_PAY,
1822
- minLength: 16,
1823
- maxLength: 19,
1824
- iconName: 'unionpay',
1825
- mask: '999 9999 9999 99999999',
1826
- checkNumber(number) {
1827
- return number.startsWith('62');
1828
- },
1829
- };
1807
+ function convertedRequiredValidator() {
1808
+ return convert(Validators.required, 'Required');
1809
+ }
1830
1810
 
1831
- const defaultCard = {
1832
- id: CreditCardTypes.DEFAULT,
1833
- minLength: 12,
1834
- maxLength: 19,
1835
- iconName: null,
1836
- mask: defaultMask,
1837
- checkNumber() {
1811
+ class Converter {
1812
+ constructor(syncService) {
1813
+ this.syncService = syncService;
1814
+ }
1815
+ convertToConfig(field, formState) {
1816
+ const config = this.createControlConfig(field, formState);
1817
+ if (formState === null || formState === void 0 ? void 0 : formState.disabled) {
1818
+ config.disabled = true;
1819
+ }
1820
+ return config;
1821
+ }
1822
+ convertToFormControl(field) {
1823
+ return new UntypedFormControl(this.getValue(field), this.getValidators(field), this.getAsyncValidators(field));
1824
+ }
1825
+ getValidators(field) {
1826
+ const validators = [];
1827
+ if (field.isMandatory === "1" /* XpsBoolean.true */) {
1828
+ validators.push(convertedRequiredValidator());
1829
+ }
1830
+ if (field.regex) {
1831
+ const match = /^\/(.*)\/([gim]*)$/.exec(field.regex);
1832
+ if (match) {
1833
+ const pattern = new RegExp(match[1], match[2]);
1834
+ const errorMessage = field.validation_error_msg
1835
+ ? field.validation_error_msg
1836
+ : 'Enter valid data';
1837
+ validators.push(convert(Validators.pattern(pattern), errorMessage));
1838
+ }
1839
+ }
1840
+ return validators;
1841
+ }
1842
+ getAsyncValidators(field) {
1843
+ return () => __awaiter(this, void 0, void 0, function* () { return this.syncService.validate(field); });
1844
+ }
1845
+ createDefaultControlConfig(controlConfigClass, field) {
1846
+ const config = new controlConfigClass();
1847
+ this.copyCommonOptions(config, field);
1848
+ return config;
1849
+ }
1850
+ getValue(field) {
1851
+ return field.value;
1852
+ }
1853
+ getDataType() {
1854
+ return 'text';
1855
+ }
1856
+ getAutocomplete() {
1857
+ return 'off';
1858
+ }
1859
+ shouldHideUserInput() {
1838
1860
  return false;
1839
- },
1840
- };
1841
-
1842
- const postePay = {
1843
- id: CreditCardTypes.POSTEPAY,
1844
- minLength: 12,
1845
- maxLength: 19,
1846
- iconName: 'poste_pay',
1847
- mask: '9999 9999 9999 9999 999',
1848
- checkNumber(number) {
1849
- const regex = /^(5018)|^(5020)|^(5038)|^(5893)|^(6304)|^(6759)|^(6761)|^(6762)|^(6763)|^(0604)|^(6706)|^(6771)|^(6709)/;
1850
- return regex.test(number);
1851
- },
1852
- };
1861
+ }
1862
+ getCommonControlConfig(field) {
1863
+ return {
1864
+ name: field.name,
1865
+ title: field.title,
1866
+ labelHint: field.label_hint,
1867
+ dataType: this.getDataType(),
1868
+ readonly: field.isReadonly === "1" /* XpsBoolean.true */,
1869
+ placeholder: field.example,
1870
+ autocomplete: this.getAutocomplete(),
1871
+ };
1872
+ }
1873
+ copyCommonOptions(target, field) {
1874
+ const commonControlConfig = this.getCommonControlConfig(field);
1875
+ Object.keys(commonControlConfig).forEach((sourceKey) => {
1876
+ if (!(sourceKey in target)) {
1877
+ target[sourceKey] = commonControlConfig[sourceKey];
1878
+ }
1879
+ });
1880
+ }
1881
+ }
1853
1882
 
1854
- /**
1855
- * order does matter
1856
- * settings with more specific pattern should be placed above
1857
- * Example:
1858
- * - 12*
1859
- * - 12
1860
- * - 1
1861
- * "12*" pattern should be checked first, otherwise pattern "1" will be taken
1862
- * before "12*" checked
1863
- */
1864
- const orderedCardSettings = [
1865
- aura,
1866
- naranja,
1867
- maestro,
1868
- postePay,
1869
- elo,
1870
- discover,
1871
- dankort,
1872
- hipercard,
1873
- mir,
1874
- jcb,
1875
- dinersClubs,
1876
- americanExpress,
1877
- mastercard,
1878
- chinaUnionPay,
1879
- visa,
1880
- defaultCard,
1881
- ];
1883
+ class EmailConverter extends Converter {
1884
+ constructor(syncService) {
1885
+ super(syncService);
1886
+ }
1887
+ getValidators(field) {
1888
+ return super.getValidators(field).concat([convertedEmailValidator()]);
1889
+ }
1890
+ createControlConfig(field) {
1891
+ const config = this.createDefaultControlConfig(TextControlConfig, field);
1892
+ config.autocomplete = 'email';
1893
+ config.icon = 'mail';
1894
+ return config;
1895
+ }
1896
+ getDataType() {
1897
+ return 'email';
1898
+ }
1899
+ }
1900
+ EmailConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
1901
+ EmailConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter });
1902
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter, decorators: [{
1903
+ type: Injectable
1904
+ }], ctorParameters: function () { return [{ type: SyncService }]; } });
1882
1905
 
1883
- const creditCardsMap = {
1884
- [CreditCardTypes.DEFAULT]: defaultCard,
1885
- [CreditCardTypes.VISA]: visa,
1886
- [CreditCardTypes.MASTERCARD]: mastercard,
1887
- [CreditCardTypes.MAESTRO]: maestro,
1888
- [CreditCardTypes.AMERICAN_EXPRESS]: americanExpress,
1889
- [CreditCardTypes.DINERS_CLUBS]: dinersClubs,
1890
- [CreditCardTypes.DISCOVER]: discover,
1891
- [CreditCardTypes.JCB]: jcb,
1892
- [CreditCardTypes.DANKORT]: dankort,
1893
- [CreditCardTypes.HIPERCARD]: hipercard,
1894
- [CreditCardTypes.ELO]: elo,
1895
- [CreditCardTypes.AURA]: aura,
1896
- [CreditCardTypes.NARANJA]: naranja,
1897
- [CreditCardTypes.MIR]: mir,
1898
- [CreditCardTypes.CHINA_UNION_PAY]: chinaUnionPay,
1899
- [CreditCardTypes.POSTEPAY]: postePay,
1906
+ const restrictedValueValidator = (restrictedValue) => {
1907
+ return ({ value }) => {
1908
+ return value !== restrictedValue ? null : { valueAllowed: false };
1909
+ };
1900
1910
  };
1901
1911
 
1902
- class CreditCardService {
1903
- getBinNumber(cardNumber) {
1904
- const binNumberLength = 6;
1905
- return cardNumber.replace(/\s+/g, '').substring(0, binNumberLength);
1912
+ class ZipConverter extends Converter {
1913
+ constructor(syncService, countryService) {
1914
+ super(syncService);
1915
+ this.countryService = countryService;
1916
+ this.minLength = 3;
1917
+ this.maxLength = 10;
1918
+ this.usCountryLength = 5;
1906
1919
  }
1907
- getAccountSuffix(cardNumber) {
1908
- const accountSuffixLength = 4;
1909
- return cardNumber
1910
- .replace(/\s+/g, '')
1911
- .substring(cardNumber.length - accountSuffixLength);
1920
+ get isUsCountry() {
1921
+ return this.countryService.getCountry() === 'US';
1922
+ }
1923
+ getValidators(field) {
1924
+ const minLength = this.isUsCountry ? this.usCountryLength : this.minLength;
1925
+ const maxLength = this.isUsCountry ? this.usCountryLength : this.maxLength;
1926
+ const validators = super
1927
+ .getValidators(field)
1928
+ .concat([
1929
+ convert(Validators.minLength(minLength), `Enter at least ${minLength} characters`),
1930
+ convert(Validators.maxLength(maxLength), `Enter no more than ${maxLength} characters`),
1931
+ ]);
1932
+ if (this.isUsCountry) {
1933
+ validators.push(convert(restrictedValueValidator('00000'), 'Enter a valid ZIP code'));
1934
+ }
1935
+ return validators;
1936
+ }
1937
+ createControlConfig(field) {
1938
+ const config = this.createDefaultControlConfig(TextControlConfig, field);
1939
+ config.icon = 'location';
1940
+ if (this.isUsCountry) {
1941
+ config.maskConfig = {
1942
+ guide: false,
1943
+ unmaskModelValue: true,
1944
+ showMask: true,
1945
+ };
1946
+ config.inputMode = 'numeric';
1947
+ if (masksFunctionsMap['zip']) {
1948
+ config.maskConfig.mask = masksFunctionsMap['zip'];
1949
+ }
1950
+ }
1951
+ else {
1952
+ config.maxLength = this.maxLength;
1953
+ }
1954
+ return config;
1955
+ }
1956
+ getAutocomplete() {
1957
+ return 'postal-code';
1958
+ }
1959
+ getDataType() {
1960
+ return 'text';
1961
+ }
1962
+ }
1963
+ ZipConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ZipConverter, deps: [{ token: SyncService }, { token: CountryService }], target: i0.ɵɵFactoryTarget.Injectable });
1964
+ ZipConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ZipConverter });
1965
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ZipConverter, decorators: [{
1966
+ type: Injectable
1967
+ }], ctorParameters: function () { return [{ type: SyncService }, { type: CountryService }]; } });
1968
+
1969
+ function isEmptyInputValue(value) {
1970
+ return value == null || value.length === 0;
1971
+ }
1972
+
1973
+ function isString(value) {
1974
+ return typeof value === 'string';
1975
+ }
1976
+
1977
+ /**
1978
+ * Checks number match Luhn algorithm.
1979
+ * Based on http://en.wikipedia.org/wiki/Luhn.
1980
+ */
1981
+ const luhnFormulaValidator = ({ value }) => {
1982
+ if (isEmptyInputValue(value) || !isString(value)) {
1983
+ return null;
1912
1984
  }
1913
- getTypeByNumber(cardNumber) {
1914
- cardNumber = cardNumber.replace(/\s+/g, '');
1915
- const cardSettings = orderedCardSettings.find((settings) => {
1916
- const isNumberMatched = settings.checkNumber(cardNumber);
1917
- return isNumberMatched ? settings.id : false;
1918
- });
1919
- return cardSettings ? cardSettings.id : defaultCard.id;
1985
+ const error = {
1986
+ rewritableError: {
1987
+ message: `Enter a valid card number`,
1988
+ },
1989
+ };
1990
+ if (/[^0-9 -]+/.test(value)) {
1991
+ // accept only spaces, digits and dashes
1992
+ return error;
1920
1993
  }
1921
- getCreditCardSettings(cardType) {
1922
- const creditCard = creditCardsMap[cardType];
1923
- if (!creditCard) {
1924
- return defaultCard;
1994
+ let resultSum = 0;
1995
+ let digit = 0;
1996
+ let isEven = false;
1997
+ const modBase = 10;
1998
+ const digitRadix = 10;
1999
+ const maxNumber = 9;
2000
+ const digits = value.replace(/\D/g, '');
2001
+ // Checks if number match Luhn algorithm
2002
+ // based on http://en.wikipedia.org/wiki/Luhn
2003
+ for (let index = digits.length - 1; index >= 0; index--) {
2004
+ const char = digits.charAt(index);
2005
+ digit = parseInt(char, digitRadix);
2006
+ if (isEven && (digit *= 2) > maxNumber) {
2007
+ digit -= maxNumber;
1925
2008
  }
1926
- return creditCard;
2009
+ resultSum += digit;
2010
+ isEven = !isEven;
2011
+ }
2012
+ return resultSum % modBase === 0 ? null : error;
2013
+ };
2014
+
2015
+ class CardNumberConfig extends ControlConfig {
2016
+ constructor() {
2017
+ super(...arguments);
2018
+ this.controlType = 'card-number';
2019
+ this.availableCardTypes = [];
2020
+ this.customError = '';
1927
2021
  }
1928
2022
  }
1929
- CreditCardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1930
- CreditCardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, providedIn: 'root' });
1931
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, decorators: [{
1932
- type: Injectable,
1933
- args: [{
1934
- providedIn: 'root',
1935
- }]
1936
- }] });
1937
2023
 
1938
2024
  class CreditCardMinLengthValidator {
1939
2025
  constructor(creditService) {
@@ -1956,56 +2042,366 @@ class CreditCardMinLengthValidator {
1956
2042
  };
1957
2043
  }
1958
2044
  }
1959
- CreditCardMinLengthValidator.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator, deps: [{ token: CreditCardService }], target: i0.ɵɵFactoryTarget.Injectable });
1960
- CreditCardMinLengthValidator.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator });
1961
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator, decorators: [{
1962
- type: Injectable
1963
- }], ctorParameters: function () { return [{ type: CreditCardService }]; } });
2045
+ CreditCardMinLengthValidator.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator, deps: [{ token: CreditCardService }], target: i0.ɵɵFactoryTarget.Injectable });
2046
+ CreditCardMinLengthValidator.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator });
2047
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator, decorators: [{
2048
+ type: Injectable
2049
+ }], ctorParameters: function () { return [{ type: CreditCardService }]; } });
2050
+
2051
+ class CardNumberConverter extends Converter {
2052
+ constructor(syncService, maxLengthValidator, minLengthValidator) {
2053
+ super(syncService);
2054
+ this.maxLengthValidator = maxLengthValidator;
2055
+ this.minLengthValidator = minLengthValidator;
2056
+ }
2057
+ getValidators(field) {
2058
+ return super
2059
+ .getValidators(field)
2060
+ .concat([
2061
+ luhnFormulaValidator,
2062
+ this.minLengthValidator.validate,
2063
+ this.maxLengthValidator.validate,
2064
+ ]);
2065
+ }
2066
+ createControlConfig(field, formState) {
2067
+ var _a, _b;
2068
+ const config = this.createDefaultControlConfig(CardNumberConfig, field);
2069
+ config.placeholder = config.title;
2070
+ config.availableCardTypes =
2071
+ (_a = formState === null || formState === void 0 ? void 0 : formState.availableCardTypes) !== null && _a !== void 0 ? _a : [];
2072
+ config.activeCardType = formState === null || formState === void 0 ? void 0 : formState.activeCardType;
2073
+ config.customError = formState === null || formState === void 0 ? void 0 : formState.customError;
2074
+ config.disabled = (_b = formState === null || formState === void 0 ? void 0 : formState.disabled) !== null && _b !== void 0 ? _b : false;
2075
+ return config;
2076
+ }
2077
+ getAutocomplete() {
2078
+ return 'cc-number';
2079
+ }
2080
+ getDataType() {
2081
+ return 'text';
2082
+ }
2083
+ }
2084
+ CardNumberConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardNumberConverter, deps: [{ token: SyncService }, { token: CreditCardMinLengthValidator }, { token: CreditCardMinLengthValidator }], target: i0.ɵɵFactoryTarget.Injectable });
2085
+ CardNumberConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardNumberConverter });
2086
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardNumberConverter, decorators: [{
2087
+ type: Injectable
2088
+ }], ctorParameters: function () { return [{ type: SyncService }, { type: CreditCardMinLengthValidator }, { type: CreditCardMinLengthValidator }]; } });
2089
+
2090
+ class CardExpirationConverter extends Converter {
2091
+ constructor(syncService) {
2092
+ super(syncService);
2093
+ }
2094
+ getValidators() {
2095
+ return [];
2096
+ }
2097
+ createControlConfig(field, formState) {
2098
+ var _a;
2099
+ const config = this.createDefaultControlConfig(TextControlConfig, field);
2100
+ config.maskConfig = {
2101
+ mask: '99',
2102
+ guide: false,
2103
+ };
2104
+ config.inputMode = 'numeric';
2105
+ config.title = 'date';
2106
+ config.disabled = (_a = formState === null || formState === void 0 ? void 0 : formState.disabled) !== null && _a !== void 0 ? _a : false;
2107
+ return config;
2108
+ }
2109
+ getAutocomplete() {
2110
+ return 'cc-exp';
2111
+ }
2112
+ getDataType() {
2113
+ return 'text';
2114
+ }
2115
+ }
2116
+ CardExpirationConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardExpirationConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
2117
+ CardExpirationConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardExpirationConverter });
2118
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardExpirationConverter, decorators: [{
2119
+ type: Injectable
2120
+ }], ctorParameters: function () { return [{ type: SyncService }]; } });
2121
+
2122
+ class CvvConverter extends Converter {
2123
+ constructor(syncService) {
2124
+ super(syncService);
2125
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
2126
+ this.maxFieldLength = 4;
2127
+ }
2128
+ getValidators() {
2129
+ return [];
2130
+ }
2131
+ createControlConfig(field, formState) {
2132
+ var _a;
2133
+ const config = this.createDefaultControlConfig(TextControlConfig, field);
2134
+ config.maskConfig = {
2135
+ mask: () => new Array(this.maxFieldLength).fill('9').join(''),
2136
+ unmaskModelValue: false,
2137
+ guide: false,
2138
+ };
2139
+ config.tooltip = {
2140
+ text: 'The code is on the back of your card',
2141
+ image: 'cvv',
2142
+ parentField: FieldNames.cvv,
2143
+ position: 'input',
2144
+ analyticsAction: 'show-cvv-tooltip',
2145
+ };
2146
+ config.inputMode = 'numeric';
2147
+ config.shouldHideUserInput = this.shouldHideUserInput();
2148
+ config.disabled = (_a = formState === null || formState === void 0 ? void 0 : formState.disabled) !== null && _a !== void 0 ? _a : false;
2149
+ return config;
2150
+ }
2151
+ getAutocomplete() {
2152
+ return 'cc-csc';
2153
+ }
2154
+ getDataType() {
2155
+ return 'password';
2156
+ }
2157
+ shouldHideUserInput() {
2158
+ return true;
2159
+ }
2160
+ }
2161
+ CvvConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CvvConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
2162
+ CvvConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CvvConverter });
2163
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CvvConverter, decorators: [{
2164
+ type: Injectable
2165
+ }], ctorParameters: function () { return [{ type: SyncService }]; } });
2166
+
2167
+ const birthdateValidator = ({ value }) => {
2168
+ if (isEmptyInputValue(value) || typeof value !== 'string') {
2169
+ return null;
2170
+ }
2171
+ const error = {
2172
+ invalidBirthDate: {
2173
+ message: `Enter a valid birth date`,
2174
+ },
2175
+ };
2176
+ const dateArr = value.split('/');
2177
+ const datePartsCount = 3;
2178
+ const dayIndex = 0;
2179
+ const monthIndex = 1;
2180
+ const yearIndex = 2;
2181
+ const maxMonths = 12;
2182
+ const maxDays = 31;
2183
+ const minAge = 16;
2184
+ const maxAge = 120;
2185
+ if (dateArr.length < datePartsCount) {
2186
+ return null;
2187
+ }
2188
+ if (+dateArr[monthIndex] > maxMonths || +dateArr[dayIndex] > maxDays) {
2189
+ return error;
2190
+ }
2191
+ const currentDate = new Date(+dateArr[yearIndex], +dateArr[monthIndex], +dateArr[dayIndex]);
2192
+ const nowDate = new Date();
2193
+ if (isNaN(currentDate.getFullYear()) ||
2194
+ nowDate.getFullYear() - currentDate.getFullYear() <= minAge ||
2195
+ nowDate.getFullYear() - currentDate.getFullYear() > maxAge) {
2196
+ return error;
2197
+ }
2198
+ else {
2199
+ return null;
2200
+ }
2201
+ };
2202
+
2203
+ class BirthDateConverter extends Converter {
2204
+ constructor(syncService) {
2205
+ super(syncService);
2206
+ }
2207
+ getValidators(field) {
2208
+ return super
2209
+ .getValidators(field)
2210
+ .concat([
2211
+ convert(Validators.pattern(/^[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{4}$/), `Enter a valid birth date`),
2212
+ birthdateValidator,
2213
+ ]);
2214
+ }
2215
+ createControlConfig(field) {
2216
+ const config = this.createDefaultControlConfig(TextControlConfig, field);
2217
+ config.maskConfig = {
2218
+ mask: '99/99/9999',
2219
+ unmaskModelValue: false,
2220
+ guide: false,
2221
+ };
2222
+ config.placeholder = `DD/MM/YYYY`;
2223
+ config.inputMode = 'numeric';
2224
+ return config;
2225
+ }
2226
+ }
2227
+ BirthDateConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: BirthDateConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
2228
+ BirthDateConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: BirthDateConverter });
2229
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: BirthDateConverter, decorators: [{
2230
+ type: Injectable
2231
+ }], ctorParameters: function () { return [{ type: SyncService }]; } });
2232
+
2233
+ class CardholderNameConverter extends Converter {
2234
+ constructor(syncService) {
2235
+ super(syncService);
2236
+ }
2237
+ createControlConfig(field) {
2238
+ return this.createDefaultControlConfig(TextControlConfig, field);
2239
+ }
2240
+ getAutocomplete() {
2241
+ return 'cc-name';
2242
+ }
2243
+ getDataType() {
2244
+ return 'text';
2245
+ }
2246
+ }
2247
+ CardholderNameConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardholderNameConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
2248
+ CardholderNameConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardholderNameConverter });
2249
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardholderNameConverter, decorators: [{
2250
+ type: Injectable
2251
+ }], ctorParameters: function () { return [{ type: SyncService }]; } });
2252
+
2253
+ const cpfNameRegex = /^[a-zA-ZÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ.'-]{2,50}(?: [a-zA-ZÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ.'-]{2,50}){1,8}$/i; // tslint:disable-line
2254
+
2255
+ class CpfNameConverter extends Converter {
2256
+ constructor(syncService) {
2257
+ super(syncService);
2258
+ }
2259
+ getValidators(field) {
2260
+ return super
2261
+ .getValidators(field)
2262
+ .concat([
2263
+ convert(Validators.pattern(cpfNameRegex), `Enter a valid name`),
2264
+ ]);
2265
+ }
2266
+ createControlConfig(field) {
2267
+ const config = this.createDefaultControlConfig(TextControlConfig, field);
2268
+ config.tooltip = {
2269
+ text: `Where to find your name`,
2270
+ image: 'cpf-name',
2271
+ };
2272
+ return config;
2273
+ }
2274
+ }
2275
+ CpfNameConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNameConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
2276
+ CpfNameConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNameConverter });
2277
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNameConverter, decorators: [{
2278
+ type: Injectable
2279
+ }], ctorParameters: function () { return [{ type: SyncService }]; } });
2280
+
2281
+ class CpfNumberConverter extends Converter {
2282
+ constructor(syncService) {
2283
+ super(syncService);
2284
+ }
2285
+ createControlConfig(field) {
2286
+ const config = this.createDefaultControlConfig(TextControlConfig, field);
2287
+ config.maskConfig = {
2288
+ mask: '999.999.999-99',
2289
+ unmaskModelValue: true,
2290
+ guide: false,
2291
+ };
2292
+ config.inputMode = 'numeric';
2293
+ config.placeholder = '000.000.000-00';
2294
+ config.tooltip = {
2295
+ text: `Where to find your registration number`,
2296
+ image: 'cpf-number',
2297
+ };
2298
+ return config;
2299
+ }
2300
+ }
2301
+ CpfNumberConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNumberConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
2302
+ CpfNumberConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNumberConverter });
2303
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNumberConverter, decorators: [{
2304
+ type: Injectable
2305
+ }], ctorParameters: function () { return [{ type: SyncService }]; } });
2306
+
2307
+ class StreetNumberConverter extends Converter {
2308
+ constructor(syncService) {
2309
+ super(syncService);
2310
+ }
2311
+ getValidators(field, formState) {
2312
+ const validators = super.getValidators(field);
2313
+ if ((formState === null || formState === void 0 ? void 0 : formState.country) === 'BL') {
2314
+ validators.push(convert(restrictedValueValidator('0'), `Enter a valid building number`));
2315
+ }
2316
+ return validators;
2317
+ }
2318
+ createControlConfig(field) {
2319
+ return this.createDefaultControlConfig(TextControlConfig, field);
2320
+ }
2321
+ }
2322
+ StreetNumberConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: StreetNumberConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
2323
+ StreetNumberConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: StreetNumberConverter });
2324
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: StreetNumberConverter, decorators: [{
2325
+ type: Injectable
2326
+ }], ctorParameters: function () { return [{ type: SyncService }]; } });
2327
+
2328
+ class TextConverter extends Converter {
2329
+ constructor(syncService) {
2330
+ super(syncService);
2331
+ }
2332
+ createControlConfig(field) {
2333
+ return this.createDefaultControlConfig(TextControlConfig, field);
2334
+ }
2335
+ }
2336
+ TextConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: TextConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
2337
+ TextConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: TextConverter });
2338
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: TextConverter, decorators: [{
2339
+ type: Injectable
2340
+ }], ctorParameters: function () { return [{ type: SyncService }]; } });
2341
+
2342
+ function phoneValidator() {
2343
+ return convert(Validators.pattern(/^\d*$/), 'Enter a valid phone');
2344
+ }
2345
+
2346
+ function minLengthValidator(minLength) {
2347
+ return convert(Validators.minLength(minLength), `Enter at least ${minLength} characters`);
2348
+ }
2349
+
2350
+ function maxLengthValidator(maxLength) {
2351
+ return convert(Validators.maxLength(maxLength), `Enter no more than ${maxLength} characters`);
2352
+ }
2353
+
2354
+ class PhoneControlConfig extends ControlConfig {
2355
+ constructor() {
2356
+ super(...arguments);
2357
+ this.controlType = 'phone';
2358
+ }
2359
+ }
1964
2360
 
1965
- class CardNumberConverter extends Converter {
1966
- constructor(syncService, maxLengthValidator, minLengthValidator) {
2361
+ class PhoneConverter extends Converter {
2362
+ constructor(syncService) {
1967
2363
  super(syncService);
1968
- this.maxLengthValidator = maxLengthValidator;
1969
- this.minLengthValidator = minLengthValidator;
1970
2364
  }
1971
2365
  getValidators(field) {
2366
+ const minLength = 10;
2367
+ const maxLength = 15;
1972
2368
  return super
1973
2369
  .getValidators(field)
1974
2370
  .concat([
1975
- luhnFormulaValidator,
1976
- this.minLengthValidator.validate,
1977
- this.maxLengthValidator.validate,
2371
+ convertedRequiredValidator(),
2372
+ phoneValidator(),
2373
+ minLengthValidator(minLength),
2374
+ maxLengthValidator(maxLength),
1978
2375
  ]);
1979
2376
  }
1980
- createControlConfig(field, formState) {
1981
- var _a, _b;
1982
- const config = this.createDefaultControlConfig(CardNumberConfig, field);
1983
- config.placeholder = config.title;
1984
- config.availableCardTypes =
1985
- (_a = formState === null || formState === void 0 ? void 0 : formState.availableCardTypes) !== null && _a !== void 0 ? _a : [];
1986
- config.activeCardType = formState === null || formState === void 0 ? void 0 : formState.activeCardType;
1987
- config.customError = formState === null || formState === void 0 ? void 0 : formState.customError;
1988
- config.disabled = (_b = formState === null || formState === void 0 ? void 0 : formState.disabled) !== null && _b !== void 0 ? _b : false;
2377
+ createControlConfig(field) {
2378
+ const config = this.createDefaultControlConfig(PhoneControlConfig, field);
2379
+ config.inputMode = 'numeric';
1989
2380
  return config;
1990
2381
  }
1991
- getAutocomplete() {
1992
- return 'cc-number';
1993
- }
1994
- getDataType() {
1995
- return 'text';
1996
- }
1997
2382
  }
1998
- CardNumberConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardNumberConverter, deps: [{ token: SyncService }, { token: CreditCardMinLengthValidator }, { token: CreditCardMinLengthValidator }], target: i0.ɵɵFactoryTarget.Injectable });
1999
- CardNumberConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardNumberConverter });
2000
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardNumberConverter, decorators: [{
2383
+ PhoneConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PhoneConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
2384
+ PhoneConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PhoneConverter });
2385
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PhoneConverter, decorators: [{
2001
2386
  type: Injectable
2002
- }], ctorParameters: function () { return [{ type: SyncService }, { type: CreditCardMinLengthValidator }, { type: CreditCardMinLengthValidator }]; } });
2387
+ }], ctorParameters: function () { return [{ type: SyncService }]; } });
2003
2388
 
2004
2389
  const convertersMapToken = new InjectionToken('ConvertersTokensMap');
2005
2390
  const convertersMap = {
2006
2391
  zip: ZipConverter,
2007
2392
  email: EmailConverter,
2008
2393
  card_number: CardNumberConverter,
2394
+ card_month: CardExpirationConverter,
2395
+ card_year: CardExpirationConverter,
2396
+ cvv: CvvConverter,
2397
+ extra_cvv: CvvConverter,
2398
+ cardholdername: CardholderNameConverter,
2399
+ cpf_number: CpfNumberConverter,
2400
+ cpf_name: CpfNameConverter,
2401
+ birth_date: BirthDateConverter,
2402
+ street_number: StreetNumberConverter,
2403
+ text: TextConverter,
2404
+ phone: PhoneConverter,
2009
2405
  };
2010
2406
 
2011
2407
  class ControlConfigService {
@@ -2169,6 +2565,13 @@ const statusSearchParamsMap = new Map([
2169
2565
  ],
2170
2566
  ]);
2171
2567
 
2568
+ class TerminalError extends AppError {
2569
+ constructor(message, code) {
2570
+ super(message);
2571
+ this.code = code;
2572
+ }
2573
+ }
2574
+
2172
2575
  class XpsApiPart {
2173
2576
  constructor() {
2174
2577
  this.response = new BehaviorSubject(null);
@@ -2426,23 +2829,20 @@ const checkStatusResponseFactoryProvider = {
2426
2829
  };
2427
2830
 
2428
2831
  class CheckStatusService extends XpsApiPart {
2429
- constructor(secureApiClient, settingsService, requestFactory, responseFactory) {
2832
+ constructor(xpsApiService, settingsService, requestFactory, responseFactory) {
2430
2833
  super();
2431
- this.secureApiClient = secureApiClient;
2834
+ this.xpsApiService = xpsApiService;
2432
2835
  this.settingsService = settingsService;
2433
2836
  this.requestFactory = requestFactory;
2434
2837
  this.responseFactory = responseFactory;
2435
- this.apiRoute = 'directpayment';
2436
2838
  }
2437
2839
  setRequestParams(invoice) {
2438
2840
  this.invoice = invoice;
2439
2841
  }
2440
2842
  request() {
2441
2843
  const requestParams = this.requestFactory(this.settingsService.token, this.invoice);
2442
- lastValueFrom(this.secureApiClient.post(this.apiRoute, new URLSearchParams(Object.assign({}, requestParams)), {
2443
- headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
2444
- responseType: 'json',
2445
- }))
2844
+ this.xpsApiService
2845
+ .directPaymentRequest(requestParams)
2446
2846
  .then((response) => {
2447
2847
  const checkStatusResponse = this.responseFactory({
2448
2848
  status: response.status,
@@ -2456,7 +2856,7 @@ class CheckStatusService extends XpsApiPart {
2456
2856
  });
2457
2857
  }
2458
2858
  }
2459
- CheckStatusService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CheckStatusService, deps: [{ token: SecureApiClient }, { token: SettingsService }, { token: checkStatusRequestFactoryToken }, { token: checkStatusResponseFactoryToken }], target: i0.ɵɵFactoryTarget.Injectable });
2859
+ CheckStatusService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CheckStatusService, deps: [{ token: XpsApiService }, { token: SettingsService }, { token: checkStatusRequestFactoryToken }, { token: checkStatusResponseFactoryToken }], target: i0.ɵɵFactoryTarget.Injectable });
2460
2860
  CheckStatusService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CheckStatusService, providedIn: 'root' });
2461
2861
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CheckStatusService, decorators: [{
2462
2862
  type: Injectable,
@@ -2464,7 +2864,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
2464
2864
  providedIn: 'root',
2465
2865
  }]
2466
2866
  }], ctorParameters: function () {
2467
- return [{ type: SecureApiClient }, { type: SettingsService }, { type: undefined, decorators: [{
2867
+ return [{ type: XpsApiService }, { type: SettingsService }, { type: undefined, decorators: [{
2468
2868
  type: Inject,
2469
2869
  args: [checkStatusRequestFactoryToken]
2470
2870
  }] }, { type: undefined, decorators: [{
@@ -2604,34 +3004,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
2604
3004
  }]
2605
3005
  }] });
2606
3006
 
2607
- var ErrorTags;
2608
- (function (ErrorTags) {
2609
- ErrorTags["APP"] = "appError";
2610
- ErrorTags["HTTP"] = "httpError";
2611
- ErrorTags["JS"] = "jsError";
2612
- ErrorTags["WS"] = "webSocket";
2613
- ErrorTags["ENCRYPT"] = "encrypt";
2614
- ErrorTags["APPLEPAY"] = "applepay";
2615
- ErrorTags["HEADLESS_UI"] = "headlessUi";
2616
- ErrorTags["GOOGLEPAY"] = "googlepay";
2617
- ErrorTags["PAYTM"] = "paytm";
2618
- })(ErrorTags || (ErrorTags = {}));
2619
-
2620
- class TaggedError extends Error {
2621
- constructor(message, tags) {
2622
- super(message);
2623
- this.tags = [];
2624
- this.parentTag = ErrorTags.HEADLESS_UI;
2625
- this.tags = this.childTag
2626
- ? [this.parentTag, this.childTag]
2627
- : [this.parentTag];
2628
- if (tags) {
2629
- const newTags = tags.filter((t, i, arr) => !this.tags.includes(t) && arr.indexOf(t) == i);
2630
- this.tags = [...this.tags, ...newTags];
2631
- }
2632
- }
2633
- }
2634
-
2635
3007
  class WsError extends TaggedError {
2636
3008
  constructor(message, channelName, tags) {
2637
3009
  tags = tags ? [...tags, ErrorTags.WS] : [ErrorTags.WS];
@@ -3530,11 +3902,445 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
3530
3902
  }]
3531
3903
  }] });
3532
3904
 
3905
+ var ThreeDsStatusWebSocketTypes;
3906
+ (function (ThreeDsStatusWebSocketTypes) {
3907
+ ThreeDsStatusWebSocketTypes["status3DS_changed"] = "status3DS_changed";
3908
+ })(ThreeDsStatusWebSocketTypes || (ThreeDsStatusWebSocketTypes = {}));
3909
+
3910
+ var ThreeDsStatusTypes;
3911
+ (function (ThreeDsStatusTypes) {
3912
+ ThreeDsStatusTypes["completed"] = "completed";
3913
+ ThreeDsStatusTypes["challenge"] = "challenge";
3914
+ ThreeDsStatusTypes["collectDfp"] = "collect_dfp";
3915
+ })(ThreeDsStatusTypes || (ThreeDsStatusTypes = {}));
3916
+
3917
+ class XpsResponseError extends AppError {
3918
+ constructor(message) {
3919
+ super('XPS response failed' + (message ? `: "${message}".` : '.'));
3920
+ }
3921
+ }
3922
+
3923
+ class StatusThreeDsRequest {
3924
+ constructor(token, threeDsId) {
3925
+ this.access_token = token;
3926
+ this.threeDSTrXid = threeDsId;
3927
+ }
3928
+ }
3929
+
3930
+ const statusThreeDsRequestFactoryToken = new InjectionToken('StatusThreeDsRequest');
3931
+ const statusThreeDsRequestFactoryProvider = {
3932
+ provide: statusThreeDsRequestFactoryToken,
3933
+ useValue: (...args) => new StatusThreeDsRequest(...args),
3934
+ };
3935
+
3936
+ class StatusThreeDsResponse {
3937
+ constructor(params) {
3938
+ this.status = params.status;
3939
+ this.checkoutForm = params.checkoutForm;
3940
+ }
3941
+ }
3942
+
3943
+ const statusThreeDsResponseFactoryToken = new InjectionToken('StatusThreeDsResponse');
3944
+ const statusThreeDsResponseFactoryProvider = {
3945
+ provide: statusThreeDsResponseFactoryToken,
3946
+ useValue: (...args) => new StatusThreeDsResponse(...args),
3947
+ };
3948
+
3949
+ class StatusThreeDsService {
3950
+ get response$() {
3951
+ return this.response.asObservable();
3952
+ }
3953
+ constructor(secureApi, settingsService, requestFactory, responseFactory) {
3954
+ this.secureApi = secureApi;
3955
+ this.settingsService = settingsService;
3956
+ this.requestFactory = requestFactory;
3957
+ this.responseFactory = responseFactory;
3958
+ this.apiRoute = 'secure3d/check';
3959
+ this.response = new Subject();
3960
+ }
3961
+ request(data) {
3962
+ const token = this.settingsService.token;
3963
+ if (!token) {
3964
+ throw new TokenError();
3965
+ }
3966
+ const requestParams = this.requestFactory(token, data.threeDSTrXid);
3967
+ void lastValueFrom(this.secureApi
3968
+ .post(this.apiRoute, new URLSearchParams(Object.assign({}, requestParams)), {
3969
+ headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
3970
+ responseType: 'json',
3971
+ })
3972
+ .pipe(map$1((response) => {
3973
+ const statusResponse = this.responseFactory({
3974
+ status: response.secure3d.status,
3975
+ checkoutForm: response.secure3d.checkout_form,
3976
+ });
3977
+ this.response.next(statusResponse);
3978
+ }))).catch((error) => {
3979
+ throw new XpsResponseError(error.message);
3980
+ });
3981
+ }
3982
+ }
3983
+ StatusThreeDsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: StatusThreeDsService, deps: [{ token: SecureApiClient }, { token: SettingsService }, { token: statusThreeDsRequestFactoryToken }, { token: statusThreeDsResponseFactoryToken }], target: i0.ɵɵFactoryTarget.Injectable });
3984
+ StatusThreeDsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: StatusThreeDsService, providedIn: 'root' });
3985
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: StatusThreeDsService, decorators: [{
3986
+ type: Injectable,
3987
+ args: [{
3988
+ providedIn: 'root',
3989
+ }]
3990
+ }], ctorParameters: function () {
3991
+ return [{ type: SecureApiClient }, { type: SettingsService }, { type: undefined, decorators: [{
3992
+ type: Inject,
3993
+ args: [statusThreeDsRequestFactoryToken]
3994
+ }] }, { type: undefined, decorators: [{
3995
+ type: Inject,
3996
+ args: [statusThreeDsResponseFactoryToken]
3997
+ }] }];
3998
+ } });
3999
+
4000
+ class NotifyDfpStatusRequest {
4001
+ constructor(params) {
4002
+ this.access_token = params.token;
4003
+ this.threeDSTrXid = params.threeDsTrXid;
4004
+ this.secure3dCompind = params.isCompind ? 'Y' : 'N';
4005
+ }
4006
+ }
4007
+
4008
+ const notifyDfpStatusRequestFactoryToken = new InjectionToken('NotifyDfpStatusRequest');
4009
+ const notifyDfpStatusRequestFactoryProvider = {
4010
+ provide: notifyDfpStatusRequestFactoryToken,
4011
+ useValue: (...args) => new NotifyDfpStatusRequest(...args),
4012
+ };
4013
+
4014
+ class NotifyDfpStatusService {
4015
+ constructor(secureApi, settingsService, requestFactory) {
4016
+ this.secureApi = secureApi;
4017
+ this.settingsService = settingsService;
4018
+ this.requestFactory = requestFactory;
4019
+ this.apiRouteComplete = 'secure3d/notify';
4020
+ }
4021
+ /*
4022
+ * isCompind is a flag of dfp expired state
4023
+ */
4024
+ request(threeDsId, isCompind) {
4025
+ const token = this.settingsService.token;
4026
+ if (!token) {
4027
+ throw new TokenError();
4028
+ }
4029
+ const requestParams = this.requestFactory({
4030
+ token: token,
4031
+ threeDsTrXid: threeDsId,
4032
+ isCompind,
4033
+ });
4034
+ lastValueFrom(this.secureApi.post(this.apiRouteComplete, new URLSearchParams(Object.assign({}, requestParams)), {
4035
+ headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
4036
+ responseType: 'json',
4037
+ })).catch((error) => {
4038
+ throw new XpsResponseError(error.message);
4039
+ });
4040
+ }
4041
+ }
4042
+ NotifyDfpStatusService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NotifyDfpStatusService, deps: [{ token: SecureApiClient }, { token: SettingsService }, { token: notifyDfpStatusRequestFactoryToken }], target: i0.ɵɵFactoryTarget.Injectable });
4043
+ NotifyDfpStatusService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NotifyDfpStatusService, providedIn: 'root' });
4044
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NotifyDfpStatusService, decorators: [{
4045
+ type: Injectable,
4046
+ args: [{
4047
+ providedIn: 'root',
4048
+ }]
4049
+ }], ctorParameters: function () {
4050
+ return [{ type: SecureApiClient }, { type: SettingsService }, { type: undefined, decorators: [{
4051
+ type: Inject,
4052
+ args: [notifyDfpStatusRequestFactoryToken]
4053
+ }] }];
4054
+ } });
4055
+
4056
+ class DfpCollectService {
4057
+ constructor(window, notifyDfpStatusService) {
4058
+ this.window = window;
4059
+ this.notifyDfpStatusService = notifyDfpStatusService;
4060
+ this.iframeName = 'iframeDFP';
4061
+ this.formName = 'formDFP';
4062
+ }
4063
+ collectDfpStatus(threeDsForm) {
4064
+ if (threeDsForm.waitCallback) {
4065
+ this.openIframeWithPostRequest(threeDsForm, false);
4066
+ }
4067
+ else {
4068
+ this.openIframeWithPostRequest(threeDsForm, true);
4069
+ }
4070
+ }
4071
+ /*
4072
+ * This method create invisible iframe with required params and after that it submit form in iframe
4073
+ * */
4074
+ openIframeWithPostRequest(threeDsForm, isNeedNotifyAfterLoad) {
4075
+ const iFrameElement = this.window.document.getElementById(this.iframeName);
4076
+ if (!iFrameElement) {
4077
+ this.createIframe(isNeedNotifyAfterLoad, threeDsForm.threeDSTrXid);
4078
+ this.postFormToIframe(threeDsForm.threeDSMethod, threeDsForm.threeDSMethodData);
4079
+ }
4080
+ }
4081
+ /*
4082
+ * isNeedNotifyAfterLoad is need to send notification of dft to server
4083
+ * */
4084
+ createIframe(isNeedNotifyAfterLoad, threeDsTrXid) {
4085
+ const attributes = {
4086
+ name: this.iframeName,
4087
+ id: this.iframeName,
4088
+ src: 'javascript:false',
4089
+ style: 'display:none',
4090
+ };
4091
+ const iFrame = this.window.document.createElement('iframe');
4092
+ this.setAttributes(iFrame, attributes);
4093
+ this.window.document.body.appendChild(iFrame);
4094
+ if (isNeedNotifyAfterLoad) {
4095
+ this.window.document.getElementById(this.iframeName).onload = () => {
4096
+ this.notifyDfpStatusService.request(threeDsTrXid, true);
4097
+ };
4098
+ }
4099
+ }
4100
+ /*
4101
+ * This method will submit form in our iframe. Form will be created, if it's don't exist
4102
+ * */
4103
+ postFormToIframe(url, threeDsMethod) {
4104
+ let form = this.window.document.getElementById(this.formName);
4105
+ if (!form) {
4106
+ form = this.createForm();
4107
+ this.window.document.body.appendChild(form);
4108
+ }
4109
+ form.setAttribute('action', url);
4110
+ form.setAttribute('target', this.iframeName);
4111
+ form.appendChild(this.createInput('threeDSMethodData', threeDsMethod));
4112
+ form.submit();
4113
+ }
4114
+ /*
4115
+ * This method will create invisible form with required params
4116
+ */
4117
+ createForm() {
4118
+ const form = this.window.document.createElement('form');
4119
+ const initAttributes = {
4120
+ name: this.formName,
4121
+ id: this.formName,
4122
+ style: 'display:none',
4123
+ method: 'POST',
4124
+ enctype: 'application/x-www-form-urlencoded',
4125
+ };
4126
+ this.setAttributes(form, initAttributes);
4127
+ return form;
4128
+ }
4129
+ createInput(name, value) {
4130
+ const input = this.window.document.createElement('input');
4131
+ input.type = 'hidden';
4132
+ input.name = name;
4133
+ input.value = value;
4134
+ return input;
4135
+ }
4136
+ /*
4137
+ * This method will set attributes to form/iframe
4138
+ * */
4139
+ setAttributes(element, attributes) {
4140
+ Object.keys(attributes).forEach((name) => {
4141
+ element.setAttribute(name, attributes[name]);
4142
+ });
4143
+ }
4144
+ }
4145
+ DfpCollectService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DfpCollectService, deps: [{ token: windowToken }, { token: NotifyDfpStatusService }], target: i0.ɵɵFactoryTarget.Injectable });
4146
+ DfpCollectService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DfpCollectService, providedIn: 'root' });
4147
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DfpCollectService, decorators: [{
4148
+ type: Injectable,
4149
+ args: [{
4150
+ providedIn: 'root',
4151
+ }]
4152
+ }], ctorParameters: function () {
4153
+ return [{ type: undefined, decorators: [{
4154
+ type: Inject,
4155
+ args: [windowToken]
4156
+ }] }, { type: NotifyDfpStatusService }];
4157
+ } });
4158
+
4159
+ class ReinsuranceCheckService {
4160
+ constructor(window) {
4161
+ this.window = window;
4162
+ this.timers = {};
4163
+ }
4164
+ addTimer(timer) {
4165
+ if (!timer) {
4166
+ return;
4167
+ }
4168
+ this.removeTimer(timer.id);
4169
+ this.timers[timer.id] = timer;
4170
+ const timerInStorage = this.timers[timer.id];
4171
+ this.window.setTimeout(() => {
4172
+ timerInStorage.callback();
4173
+ this.timers[timer.id] = null;
4174
+ }, timerInStorage.timeoutMs);
4175
+ }
4176
+ removeTimer(id) {
4177
+ const timerInStorage = this.timers[id];
4178
+ if (!timerInStorage) {
4179
+ return;
4180
+ }
4181
+ this.window.clearTimeout(timerInStorage.timeoutRef);
4182
+ this.timers[id] = null;
4183
+ }
4184
+ }
4185
+ ReinsuranceCheckService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ReinsuranceCheckService, deps: [{ token: windowToken }], target: i0.ɵɵFactoryTarget.Injectable });
4186
+ ReinsuranceCheckService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ReinsuranceCheckService, providedIn: 'root' });
4187
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ReinsuranceCheckService, decorators: [{
4188
+ type: Injectable,
4189
+ args: [{
4190
+ providedIn: 'root',
4191
+ }]
4192
+ }], ctorParameters: function () {
4193
+ return [{ type: undefined, decorators: [{
4194
+ type: Inject,
4195
+ args: [windowToken]
4196
+ }] }];
4197
+ } });
4198
+
4199
+ class ThreeDs20Service {
4200
+ get statusUpdates$() {
4201
+ return this.statusUpdates.asObservable();
4202
+ }
4203
+ constructor(statusThreeDsService, notifyDfpStatusService, webSocketFactory, dfpCollectService, reinsuranceCheckService) {
4204
+ this.statusThreeDsService = statusThreeDsService;
4205
+ this.notifyDfpStatusService = notifyDfpStatusService;
4206
+ this.webSocketFactory = webSocketFactory;
4207
+ this.dfpCollectService = dfpCollectService;
4208
+ this.reinsuranceCheckService = reinsuranceCheckService;
4209
+ this.webSocketClient = null;
4210
+ this.statusUpdates = new Subject();
4211
+ this.statusRequestSubscription = null;
4212
+ this.notifyDfpTimerId = 'notify-dfp';
4213
+ this.notifyDfpTimeoutMs = 10000;
4214
+ this.statusThreeDsTimerId = 'status-three-ds';
4215
+ this.statusThreeDsTimeoutMs = 180000;
4216
+ }
4217
+ checkThreeDs20(threeDsForm) {
4218
+ var _a, _b;
4219
+ return __awaiter(this, void 0, void 0, function* () {
4220
+ if (!threeDsForm) {
4221
+ return;
4222
+ }
4223
+ this.reinsuranceCheckService.addTimer({
4224
+ id: this.notifyDfpTimerId,
4225
+ timeoutMs: this.notifyDfpTimeoutMs,
4226
+ callback: () => {
4227
+ this.notifyDfpStatusService.request(threeDsForm.threeDSTrXid, false);
4228
+ },
4229
+ });
4230
+ this.webSocketClient = this.webSocketFactory.createWebSocketClient(threeDsForm.webSocketChannelUrl, threeDsForm.webSocketClientType);
4231
+ yield this.webSocketClient.open(threeDsForm.webSocketChannelUrl, threeDsForm.webSocketClientType);
4232
+ (_a = this.webSocketSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
4233
+ this.webSocketSubscription = this.webSocketClient.messages$.subscribe((message) => {
4234
+ if (message !== ThreeDsStatusWebSocketTypes.status3DS_changed) {
4235
+ return;
4236
+ }
4237
+ this.statusThreeDsService.request(threeDsForm);
4238
+ });
4239
+ (_b = this.webSocketReconnectionSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
4240
+ this.webSocketReconnectionSubscription =
4241
+ this.webSocketClient.subscribeOnSuccessfulReconnection(() => {
4242
+ this.statusThreeDsService.request(threeDsForm);
4243
+ });
4244
+ this.handleThreeDsUpdates(threeDsForm);
4245
+ this.statusThreeDsService.request(threeDsForm);
4246
+ this.reinsuranceCheckService.addTimer({
4247
+ id: this.statusThreeDsTimerId,
4248
+ timeoutMs: this.statusThreeDsTimeoutMs,
4249
+ callback: () => {
4250
+ this.statusThreeDsService.request(threeDsForm);
4251
+ },
4252
+ });
4253
+ });
4254
+ }
4255
+ handleThreeDsUpdates(threeDsForm) {
4256
+ var _a;
4257
+ (_a = this.statusRequestSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
4258
+ this.statusRequestSubscription =
4259
+ this.statusThreeDsService.response$.subscribe((threeDsStatus) => {
4260
+ if (!threeDsStatus) {
4261
+ return;
4262
+ }
4263
+ if (threeDsStatus.status === ThreeDsStatusTypes.completed) {
4264
+ this.stopReinsuranceMethods();
4265
+ this.statusUpdates.next({
4266
+ type: 'complete',
4267
+ data: {
4268
+ statusUrl: threeDsForm.statusUrl,
4269
+ },
4270
+ });
4271
+ return;
4272
+ }
4273
+ if (threeDsStatus.status === ThreeDsStatusTypes.challenge &&
4274
+ threeDsStatus.checkoutForm) {
4275
+ this.stopReinsuranceMethods();
4276
+ this.statusUpdates.next({
4277
+ type: 'challenge',
4278
+ data: threeDsStatus.checkoutForm,
4279
+ });
4280
+ }
4281
+ if (threeDsStatus.status === ThreeDsStatusTypes.collectDfp) {
4282
+ this.dfpCollectService.collectDfpStatus(threeDsForm);
4283
+ }
4284
+ });
4285
+ }
4286
+ stopReinsuranceMethods() {
4287
+ var _a, _b;
4288
+ this.reinsuranceCheckService.removeTimer(this.notifyDfpTimerId);
4289
+ this.reinsuranceCheckService.removeTimer(this.statusThreeDsTimerId);
4290
+ (_a = this.webSocketClient) === null || _a === void 0 ? void 0 : _a.close();
4291
+ (_b = this.statusRequestSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
4292
+ }
4293
+ }
4294
+ ThreeDs20Service.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ThreeDs20Service, deps: [{ token: StatusThreeDsService }, { token: NotifyDfpStatusService }, { token: WebSocketFactory }, { token: DfpCollectService }, { token: ReinsuranceCheckService }], target: i0.ɵɵFactoryTarget.Injectable });
4295
+ ThreeDs20Service.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ThreeDs20Service, providedIn: 'root' });
4296
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ThreeDs20Service, decorators: [{
4297
+ type: Injectable,
4298
+ args: [{
4299
+ providedIn: 'root',
4300
+ }]
4301
+ }], ctorParameters: function () { return [{ type: StatusThreeDsService }, { type: NotifyDfpStatusService }, { type: WebSocketFactory }, { type: DfpCollectService }, { type: ReinsuranceCheckService }]; } });
4302
+
4303
+ class ThreeDsService {
4304
+ constructor(threeDs20Service, nextActionService) {
4305
+ this.threeDs20Service = threeDs20Service;
4306
+ this.nextActionService = nextActionService;
4307
+ this.statusSubscription = null;
4308
+ }
4309
+ checkThreeDs(params) {
4310
+ var _a;
4311
+ /*
4312
+ At this moment we support only 3ds 2.0 version.
4313
+ 3ds 1.0 currently working by our redirect logic (Redirect NextAction).
4314
+ If in future we will get new version of 3ds, we should add 3ds determination logic to this service
4315
+ */
4316
+ void this.threeDs20Service.checkThreeDs20(params.parameters.threeDSForm);
4317
+ (_a = this.statusSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
4318
+ this.statusSubscription = this.threeDs20Service.statusUpdates$.subscribe((statusUpdate) => {
4319
+ if (statusUpdate.type === 'complete') {
4320
+ return this.nextActionService.emitFlowUpdates(new CheckStatusAction(params));
4321
+ }
4322
+ this.nextActionService.emitFlowUpdates(new ThreeDsAction(statusUpdate));
4323
+ });
4324
+ }
4325
+ stopChecking() {
4326
+ var _a;
4327
+ (_a = this.statusSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
4328
+ }
4329
+ }
4330
+ ThreeDsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ThreeDsService, deps: [{ token: ThreeDs20Service }, { token: NextActionService }], target: i0.ɵɵFactoryTarget.Injectable });
4331
+ ThreeDsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ThreeDsService, providedIn: 'root' });
4332
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ThreeDsService, decorators: [{
4333
+ type: Injectable,
4334
+ args: [{
4335
+ providedIn: 'root',
4336
+ }]
4337
+ }], ctorParameters: function () { return [{ type: ThreeDs20Service }, { type: NextActionService }]; } });
4338
+
3533
4339
  class PaymentService {
3534
4340
  get formFieldsStatus$() {
3535
4341
  return this.formFieldsStatusSubject.asObservable().pipe(filter$1(Boolean));
3536
4342
  }
3537
- constructor(initializeService, submitService, syncService, formService, statusService, financeDetailsService, creditCardStateService, nextActionService, controlConfigService) {
4343
+ constructor(initializeService, submitService, syncService, formService, statusService, financeDetailsService, creditCardStateService, nextActionService, controlConfigService, threeDsService) {
3538
4344
  this.initializeService = initializeService;
3539
4345
  this.submitService = submitService;
3540
4346
  this.syncService = syncService;
@@ -3544,6 +4350,7 @@ class PaymentService {
3544
4350
  this.creditCardStateService = creditCardStateService;
3545
4351
  this.nextActionService = nextActionService;
3546
4352
  this.controlConfigService = controlConfigService;
4353
+ this.threeDsService = threeDsService;
3547
4354
  this.form = null;
3548
4355
  this.data = null;
3549
4356
  this.financeDetails = null;
@@ -3583,6 +4390,13 @@ class PaymentService {
3583
4390
  const submitResponse = yield this.submitService.request(this.fields, this.form);
3584
4391
  this.data = submitResponse;
3585
4392
  this.emitFinanceDetails(submitResponse.summary);
4393
+ // Handle 3ds flow
4394
+ if (submitResponse.currentCommand === XpsCommand.create) {
4395
+ this.runThreeDs();
4396
+ return;
4397
+ }
4398
+ this.fields = this.getFields();
4399
+ this.form = this.formService.createForm(this.fields);
3586
4400
  return this.nextActionService.getNextAction(submitResponse);
3587
4401
  });
3588
4402
  }
@@ -3603,7 +4417,10 @@ class PaymentService {
3603
4417
  });
3604
4418
  }
3605
4419
  runThreeDs() {
3606
- throw new Error('Method not implemented.');
4420
+ if (!isSubmitResponse(this.data)) {
4421
+ throw new Error('Should submit form first');
4422
+ }
4423
+ this.threeDsService.checkThreeDs(this.data);
3607
4424
  }
3608
4425
  getFinanceDetails() {
3609
4426
  return this.financeDetails;
@@ -3658,6 +4475,7 @@ class PaymentService {
3658
4475
  this.fields = [];
3659
4476
  this.formDestroy$.next();
3660
4477
  this.destroy$.next();
4478
+ this.threeDsService.stopChecking();
3661
4479
  }
3662
4480
  emitFinanceDetails(summary) {
3663
4481
  this.financeDetailsService.emit(summary);
@@ -3705,14 +4523,14 @@ class PaymentService {
3705
4523
  .subscribe(() => this.emitFormFieldsStatus(form));
3706
4524
  }
3707
4525
  }
3708
- PaymentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, deps: [{ token: InitializeService }, { token: SubmitService }, { token: SyncService }, { token: FormService }, { token: StatusService }, { token: FinanceDetailsService }, { token: CreditCardStateService }, { token: NextActionService }, { token: ControlConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
4526
+ PaymentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, deps: [{ token: InitializeService }, { token: SubmitService }, { token: SyncService }, { token: FormService }, { token: StatusService }, { token: FinanceDetailsService }, { token: CreditCardStateService }, { token: NextActionService }, { token: ControlConfigService }, { token: ThreeDsService }], target: i0.ɵɵFactoryTarget.Injectable });
3709
4527
  PaymentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, providedIn: 'root' });
3710
4528
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, decorators: [{
3711
4529
  type: Injectable,
3712
4530
  args: [{
3713
4531
  providedIn: 'root',
3714
4532
  }]
3715
- }], ctorParameters: function () { return [{ type: InitializeService }, { type: SubmitService }, { type: SyncService }, { type: FormService }, { type: StatusService }, { type: FinanceDetailsService }, { type: CreditCardStateService }, { type: NextActionService }, { type: ControlConfigService }]; } });
4533
+ }], ctorParameters: function () { return [{ type: InitializeService }, { type: SubmitService }, { type: SyncService }, { type: FormService }, { type: StatusService }, { type: FinanceDetailsService }, { type: CreditCardStateService }, { type: NextActionService }, { type: ControlConfigService }, { type: ThreeDsService }]; } });
3716
4534
 
3717
4535
  class RefundPolicyService {
3718
4536
  constructor(settingsService) {
@@ -3845,7 +4663,7 @@ class CoreLibraryService {
3845
4663
  init(configuration) {
3846
4664
  return __awaiter(this, void 0, void 0, function* () {
3847
4665
  yield this.settingsService.init(configuration);
3848
- yield this.deviceFingerPrintService.init();
4666
+ this.deviceFingerPrintService.init();
3849
4667
  });
3850
4668
  }
3851
4669
  getStatus(url) {
@@ -3980,6 +4798,15 @@ FormModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15
3980
4798
  ZipConverter,
3981
4799
  EmailConverter,
3982
4800
  CardNumberConverter,
4801
+ CardExpirationConverter,
4802
+ CvvConverter,
4803
+ CardholderNameConverter,
4804
+ CpfNumberConverter,
4805
+ CpfNameConverter,
4806
+ BirthDateConverter,
4807
+ StreetNumberConverter,
4808
+ TextConverter,
4809
+ PhoneConverter,
3983
4810
  { provide: convertersMapToken, useValue: convertersMap },
3984
4811
  ], imports: [ReactiveFormsModule, ValidatorsModule] });
3985
4812
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: FormModule, decorators: [{
@@ -3992,6 +4819,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
3992
4819
  ZipConverter,
3993
4820
  EmailConverter,
3994
4821
  CardNumberConverter,
4822
+ CardExpirationConverter,
4823
+ CvvConverter,
4824
+ CardholderNameConverter,
4825
+ CpfNumberConverter,
4826
+ CpfNameConverter,
4827
+ BirthDateConverter,
4828
+ StreetNumberConverter,
4829
+ TextConverter,
4830
+ PhoneConverter,
3995
4831
  { provide: convertersMapToken, useValue: convertersMap },
3996
4832
  ],
3997
4833
  }]
@@ -4021,6 +4857,9 @@ CoreLibraryModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", versi
4021
4857
  checkStatusRequestFactoryProvider,
4022
4858
  checkStatusResponseFactoryProvider,
4023
4859
  financeDetailsResponseFactoryProvider,
4860
+ statusThreeDsRequestFactoryProvider,
4861
+ statusThreeDsResponseFactoryProvider,
4862
+ notifyDfpStatusRequestFactoryProvider,
4024
4863
  {
4025
4864
  provide: nextActionsToken,
4026
4865
  useValue: nextActions,
@@ -4052,6 +4891,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
4052
4891
  checkStatusRequestFactoryProvider,
4053
4892
  checkStatusResponseFactoryProvider,
4054
4893
  financeDetailsResponseFactoryProvider,
4894
+ statusThreeDsRequestFactoryProvider,
4895
+ statusThreeDsResponseFactoryProvider,
4896
+ notifyDfpStatusRequestFactoryProvider,
4055
4897
  {
4056
4898
  provide: nextActionsToken,
4057
4899
  useValue: nextActions,