@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.
- package/esm2020/lib/core/device-finger-print/device-finger-print.service.mjs +26 -126
- package/esm2020/lib/core/device-finger-print/hash.type.mjs +1 -1
- package/esm2020/lib/core/encrypt-credit-card/encrypt-credit-card.service.mjs +72 -0
- package/esm2020/lib/core/encrypt-credit-card/encrypted-card.interface.mjs +2 -0
- package/esm2020/lib/core/encrypt-credit-card/open-card.interface.mjs +2 -0
- package/esm2020/lib/core/exceptions-handling/errors/encrypt-card-error.mjs +9 -0
- package/esm2020/lib/core/payment/actions/check-status/check-status.action.class.mjs +2 -3
- package/esm2020/lib/core/payment/actions/next-action.interface.mjs +1 -1
- package/esm2020/lib/core/payment/actions/next-actions.mjs +3 -1
- package/esm2020/lib/core/payment/actions/three-ds/three-ds.action.class.mjs +7 -0
- package/esm2020/lib/core/payment/actions/three-ds/three-ds.action.token.mjs +11 -0
- package/esm2020/lib/core/payment/actions/three-ds/three-ds.action.type.mjs +2 -0
- package/esm2020/lib/core/payment/credit-card-payment-methods-id.variable.mjs +15 -0
- package/esm2020/lib/core/payment/form/controls/phone-control.config.mjs +8 -0
- package/esm2020/lib/core/payment/form/converters/birth-date.converter.mjs +38 -0
- package/esm2020/lib/core/payment/form/converters/card-expiration.converter.mjs +36 -0
- package/esm2020/lib/core/payment/form/converters/cardholder-name.converter.mjs +25 -0
- package/esm2020/lib/core/payment/form/converters/converters-map.mjs +21 -1
- package/esm2020/lib/core/payment/form/converters/cpf-name-regex.variable.mjs +2 -0
- package/esm2020/lib/core/payment/form/converters/cpf-name.converter.mjs +34 -0
- package/esm2020/lib/core/payment/form/converters/cpf-number.converter.mjs +31 -0
- package/esm2020/lib/core/payment/form/converters/cvv.converter.mjs +50 -0
- package/esm2020/lib/core/payment/form/converters/phone.converter.mjs +37 -0
- package/esm2020/lib/core/payment/form/converters/street-number/street-number-from-state.interface.mjs +2 -0
- package/esm2020/lib/core/payment/form/converters/street-number/street-number.converter.mjs +28 -0
- package/esm2020/lib/core/payment/form/converters/text.converter.mjs +19 -0
- package/esm2020/lib/core/payment/form/form.module.mjs +28 -1
- package/esm2020/lib/core/payment/form/validators/birth-date.validator.mjs +37 -0
- package/esm2020/lib/core/payment/form/validators/max-length-validator.mjs +6 -0
- package/esm2020/lib/core/payment/form/validators/min-length-validator.mjs +6 -0
- package/esm2020/lib/core/payment/form/validators/phone-validator.mjs +6 -0
- package/esm2020/lib/core/payment/initialize/initialize-request-params.interface.mjs +1 -1
- package/esm2020/lib/core/payment/initialize/initialize.service.mjs +28 -19
- package/esm2020/lib/core/payment/initialize/response/initialize-response.class.mjs +43 -0
- package/esm2020/lib/core/payment/initialize/response/initialize-response.token.mjs +8 -0
- package/esm2020/lib/core/payment/payment.interface.mjs +1 -1
- package/esm2020/lib/core/payment/payment.service.mjs +19 -5
- package/esm2020/lib/core/payment/status/check-status/check-status.service.mjs +8 -13
- package/esm2020/lib/core/payment/status/check-status/response/check-status-response.class.mjs +1 -1
- package/esm2020/lib/core/payment/submit/submit.service.mjs +13 -16
- package/esm2020/lib/core/payment/sync/field-async-validation.interface.mjs +1 -1
- package/esm2020/lib/core/payment/sync/field-sync-state.interface.mjs +1 -1
- package/esm2020/lib/core/payment/sync/request/sync-request.class.mjs +31 -0
- package/esm2020/lib/core/payment/sync/request/sync-request.token.mjs +8 -0
- package/esm2020/lib/core/payment/sync/response/sync-response.class.mjs +17 -0
- package/esm2020/lib/core/payment/sync/response/sync-response.token.mjs +8 -0
- package/esm2020/lib/core/payment/sync/sync.service.mjs +15 -15
- package/esm2020/lib/core/payment/three-ds/api/notify-dfp-status/notify-dfp-status.service.mjs +49 -0
- package/esm2020/lib/core/payment/three-ds/api/notify-dfp-status/request/notify-dfp-status-request.class.mjs +8 -0
- package/esm2020/lib/core/payment/three-ds/api/notify-dfp-status/request/notify-dfp-status-request.token.mjs +8 -0
- package/esm2020/lib/core/payment/three-ds/api/status-three-ds/request/status-three-ds-request.class.mjs +7 -0
- package/esm2020/lib/core/payment/three-ds/api/status-three-ds/request/status-three-ds-request.token.mjs +8 -0
- package/esm2020/lib/core/payment/three-ds/api/status-three-ds/response/status-three-ds-response.class.mjs +7 -0
- package/esm2020/lib/core/payment/three-ds/api/status-three-ds/response/status-three-ds-response.token.mjs +8 -0
- package/esm2020/lib/core/payment/three-ds/api/status-three-ds/status-three-ds-response.interface.mjs +2 -0
- package/esm2020/lib/core/payment/three-ds/api/status-three-ds/status-three-ds.service.mjs +60 -0
- package/esm2020/lib/core/payment/three-ds/api/status-three-ds/status-types.enum.mjs +7 -0
- package/esm2020/lib/core/payment/three-ds/api/status-three-ds/three-ds-checkout-form.interface.mjs +2 -0
- package/esm2020/lib/core/payment/three-ds/dfp-collect/dfp-collect.service.mjs +105 -0
- package/esm2020/lib/core/payment/three-ds/reinsurance-check/reinsurance-check.service.mjs +41 -0
- package/esm2020/lib/core/payment/three-ds/reinsurance-check/timer.interface.mjs +2 -0
- package/esm2020/lib/core/payment/three-ds/three-ds-20/status-update.interface.mjs +2 -0
- package/esm2020/lib/core/payment/three-ds/three-ds-20/three-ds20.service.mjs +109 -0
- package/esm2020/lib/core/payment/three-ds/three-ds-form.interface.mjs +2 -0
- package/esm2020/lib/core/payment/three-ds/three-ds-status-websocket-types.enum.mjs +5 -0
- package/esm2020/lib/core/payment/three-ds/three-ds.service.mjs +40 -0
- package/esm2020/lib/core/payment/xps-api/xps-api.service.mjs +79 -0
- package/esm2020/lib/core/payment/xps-request-params.interface.mjs +2 -0
- package/esm2020/lib/core/payment/xps-request.interface.mjs +2 -0
- package/esm2020/lib/core/payment/xps-response.error.mjs +7 -0
- package/esm2020/lib/core/payment/xps-response.interface.mjs +1 -1
- package/esm2020/lib/core-library.module.mjs +13 -4
- package/esm2020/lib/core-library.service.mjs +2 -2
- package/fesm2015/xsolla-payment-client-core.mjs +1899 -1057
- package/fesm2015/xsolla-payment-client-core.mjs.map +1 -1
- package/fesm2020/xsolla-payment-client-core.mjs +1852 -1017
- package/fesm2020/xsolla-payment-client-core.mjs.map +1 -1
- package/lib/core/device-finger-print/device-finger-print.service.d.ts +3 -31
- package/lib/core/device-finger-print/hash.type.d.ts +1 -1
- package/lib/core/encrypt-credit-card/encrypt-credit-card.service.d.ts +16 -0
- package/lib/core/encrypt-credit-card/encrypted-card.interface.d.ts +6 -0
- package/lib/core/encrypt-credit-card/open-card.interface.d.ts +6 -0
- package/lib/core/exceptions-handling/errors/encrypt-card-error.d.ts +5 -0
- package/lib/core/payment/actions/next-action.interface.d.ts +2 -1
- package/lib/core/payment/actions/three-ds/three-ds.action.class.d.ts +8 -0
- package/lib/core/payment/actions/three-ds/three-ds.action.token.d.ts +4 -0
- package/lib/core/payment/actions/three-ds/three-ds.action.type.d.ts +5 -0
- package/lib/core/payment/credit-card-payment-methods-id.variable.d.ts +6 -0
- package/lib/core/payment/form/controls/phone-control.config.d.ts +6 -0
- package/lib/core/payment/form/converters/birth-date.converter.d.ts +13 -0
- package/lib/core/payment/form/converters/card-expiration.converter.d.ts +16 -0
- package/lib/core/payment/form/converters/cardholder-name.converter.d.ts +13 -0
- package/lib/core/payment/form/converters/cpf-name-regex.variable.d.ts +1 -0
- package/lib/core/payment/form/converters/cpf-name.converter.d.ts +13 -0
- package/lib/core/payment/form/converters/cpf-number.converter.d.ts +11 -0
- package/lib/core/payment/form/converters/cvv.converter.d.ts +18 -0
- package/lib/core/payment/form/converters/phone.converter.d.ts +13 -0
- package/lib/core/payment/form/converters/street-number/street-number-from-state.interface.d.ts +3 -0
- package/lib/core/payment/form/converters/street-number/street-number.converter.d.ts +14 -0
- package/lib/core/payment/form/converters/text.converter.d.ts +11 -0
- package/lib/core/payment/form/validators/birth-date.validator.d.ts +2 -0
- package/lib/core/payment/form/validators/max-length-validator.d.ts +2 -0
- package/lib/core/payment/form/validators/min-length-validator.d.ts +2 -0
- package/lib/core/payment/form/validators/phone-validator.d.ts +2 -0
- package/lib/core/payment/initialize/initialize-request-params.interface.d.ts +1 -0
- package/lib/core/payment/initialize/initialize.service.d.ts +8 -6
- package/lib/core/payment/initialize/{initialize-response.class.d.ts → response/initialize-response.class.d.ts} +2 -2
- package/lib/core/payment/payment.interface.d.ts +2 -2
- package/lib/core/payment/payment.service.d.ts +4 -2
- package/lib/core/payment/status/check-status/check-status.service.d.ts +3 -4
- package/lib/core/payment/submit/submit.service.d.ts +5 -4
- package/lib/core/payment/sync/field-async-validation.interface.d.ts +1 -1
- package/lib/core/payment/sync/field-sync-state.interface.d.ts +1 -1
- package/lib/core/payment/sync/{sync-request.class.d.ts → request/sync-request.class.d.ts} +3 -3
- package/lib/core/payment/sync/{sync-response.class.d.ts → response/sync-response.class.d.ts} +2 -2
- package/lib/core/payment/sync/sync.service.d.ts +8 -7
- package/lib/core/payment/three-ds/api/notify-dfp-status/notify-dfp-status.service.d.ts +14 -0
- package/lib/core/payment/three-ds/api/notify-dfp-status/request/notify-dfp-status-request.class.d.ts +10 -0
- package/lib/core/payment/three-ds/api/notify-dfp-status/request/notify-dfp-status-request.token.d.ts +6 -0
- package/lib/core/payment/three-ds/api/status-three-ds/request/status-three-ds-request.class.d.ts +5 -0
- package/lib/core/payment/three-ds/api/status-three-ds/request/status-three-ds-request.token.d.ts +6 -0
- package/lib/core/payment/three-ds/api/status-three-ds/response/status-three-ds-response.class.d.ts +7 -0
- package/lib/core/payment/three-ds/api/status-three-ds/response/status-three-ds-response.token.d.ts +6 -0
- package/lib/core/payment/three-ds/api/status-three-ds/status-three-ds-response.interface.d.ts +7 -0
- package/lib/core/payment/three-ds/api/status-three-ds/status-three-ds.service.d.ts +21 -0
- package/lib/core/payment/three-ds/api/status-three-ds/status-types.enum.d.ts +5 -0
- package/lib/core/payment/three-ds/api/status-three-ds/three-ds-checkout-form.interface.d.ts +7 -0
- package/lib/core/payment/three-ds/dfp-collect/dfp-collect.service.d.ts +20 -0
- package/lib/core/payment/three-ds/reinsurance-check/reinsurance-check.service.d.ts +12 -0
- package/lib/core/payment/three-ds/reinsurance-check/timer.interface.d.ts +9 -0
- package/lib/core/payment/three-ds/three-ds-20/status-update.interface.d.ts +12 -0
- package/lib/core/payment/three-ds/three-ds-20/three-ds20.service.d.ts +32 -0
- package/lib/core/payment/three-ds/three-ds-form.interface.d.ts +11 -0
- package/lib/core/payment/three-ds/three-ds-status-websocket-types.enum.d.ts +3 -0
- package/lib/core/payment/three-ds/three-ds.service.d.ts +14 -0
- package/lib/core/payment/xps-api/xps-api.service.d.ts +20 -0
- package/lib/core/payment/xps-request-params.interface.d.ts +3 -0
- package/lib/core/payment/xps-request.interface.d.ts +10 -0
- package/lib/core/payment/xps-response.error.d.ts +4 -0
- package/lib/core/payment/xps-response.interface.d.ts +2 -10
- package/package.json +2 -3
- package/xsolla-payment-client-core-0.1.5-2.tgz +0 -0
- package/esm2020/lib/core/device-finger-print/device-finger-print-components.interface.mjs +0 -2
- package/esm2020/lib/core/device-finger-print/fingerprint-js.interface.mjs +0 -2
- package/esm2020/lib/core/exceptions-handling/errors/default-terminal-error.class.mjs +0 -8
- package/esm2020/lib/core/payment/initialize/initialize-response.class.mjs +0 -43
- package/esm2020/lib/core/payment/initialize/initialize-response.token.mjs +0 -8
- package/esm2020/lib/core/payment/sync/sync-request.class.mjs +0 -31
- package/esm2020/lib/core/payment/sync/sync-request.token.mjs +0 -8
- package/esm2020/lib/core/payment/sync/sync-response.class.mjs +0 -17
- package/esm2020/lib/core/payment/sync/sync-response.token.mjs +0 -8
- package/esm2020/lib/core/payment/xps-request.abstract.mjs +0 -8
- package/lib/core/device-finger-print/device-finger-print-components.interface.d.ts +0 -4
- package/lib/core/device-finger-print/fingerprint-js.interface.d.ts +0 -6
- package/lib/core/exceptions-handling/errors/default-terminal-error.class.d.ts +0 -4
- package/lib/core/payment/xps-request.abstract.d.ts +0 -6
- package/xsolla-payment-client-core-0.1.4.tgz +0 -0
- /package/lib/core/payment/initialize/{initialize-response.token.d.ts → response/initialize-response.token.d.ts} +0 -0
- /package/lib/core/payment/sync/{sync-request.token.d.ts → request/sync-request.token.d.ts} +0 -0
- /package/lib/core/payment/sync/{sync-response.token.d.ts → response/sync-response.token.d.ts} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { InjectionToken, Injectable, Inject, isDevMode, NgModule } from '@angular/core';
|
|
3
|
-
import { firstValueFrom, lastValueFrom, map, Subject,
|
|
3
|
+
import { firstValueFrom, lastValueFrom, map, Subject, BehaviorSubject, filter as filter$1, takeUntil, skip, throwError } from 'rxjs';
|
|
4
4
|
import * as i1 from '@angular/common/http';
|
|
5
5
|
import { HttpParams, HttpHeaders, HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
6
|
+
import JSEncrypt from 'jsencrypt';
|
|
6
7
|
import { UntypedFormGroup, Validators, UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
|
|
7
8
|
import { filter, map as map$1, catchError } from 'rxjs/operators';
|
|
8
9
|
import * as i1$1 from '@angular/router';
|
|
@@ -580,6 +581,15 @@ var InputEventName;
|
|
|
580
581
|
InputEventName["focus"] = "focus";
|
|
581
582
|
})(InputEventName || (InputEventName = {}));
|
|
582
583
|
|
|
584
|
+
class ShowErrorsAction {
|
|
585
|
+
constructor(errors) {
|
|
586
|
+
this.type = 'show_errors';
|
|
587
|
+
this.data = {
|
|
588
|
+
errors,
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
583
593
|
class InitializeResponse {
|
|
584
594
|
constructor(response) {
|
|
585
595
|
this.paymentForm = null;
|
|
@@ -629,14 +639,90 @@ const initializeResponseFactoryProvider = {
|
|
|
629
639
|
useValue: (...args) => new InitializeResponse(...args),
|
|
630
640
|
};
|
|
631
641
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
642
|
+
const masterCardAndVisaPaymentMethodId = 26;
|
|
643
|
+
const maestroPaymentMethodId = 490;
|
|
644
|
+
const creditCardPaymentMethodId = 1380;
|
|
645
|
+
const americanExpressMethodId = 714;
|
|
646
|
+
const specialCards = [
|
|
647
|
+
maestroPaymentMethodId,
|
|
648
|
+
masterCardAndVisaPaymentMethodId,
|
|
649
|
+
americanExpressMethodId,
|
|
650
|
+
];
|
|
651
|
+
const cardsWith3ds = [
|
|
652
|
+
masterCardAndVisaPaymentMethodId,
|
|
653
|
+
maestroPaymentMethodId,
|
|
654
|
+
creditCardPaymentMethodId,
|
|
655
|
+
];
|
|
656
|
+
|
|
657
|
+
class XpsApiService {
|
|
658
|
+
constructor(window, secureApiClient, settingsService, countryService) {
|
|
659
|
+
this.window = window;
|
|
660
|
+
this.secureApiClient = secureApiClient;
|
|
661
|
+
this.settingsService = settingsService;
|
|
662
|
+
this.countryService = countryService;
|
|
663
|
+
this.directPaymentApiRoute = 'directpayment';
|
|
664
|
+
}
|
|
665
|
+
async directPaymentRequest(parameters) {
|
|
666
|
+
const pid = parameters.pid?.toString() ??
|
|
667
|
+
parameters.xps_fix_pid ??
|
|
668
|
+
'';
|
|
669
|
+
const paymentWithSavedMethod = parameters.paymentWithSavedMethod ??
|
|
670
|
+
parameters.xps_paymentWithSavedMethod ??
|
|
671
|
+
'';
|
|
672
|
+
const requestParams = {
|
|
673
|
+
...this.collectAnalyticsParameters(pid, paymentWithSavedMethod),
|
|
674
|
+
...this.collectUserSessionId(),
|
|
675
|
+
country: this.countryService.getCountry(),
|
|
676
|
+
...parameters,
|
|
637
677
|
};
|
|
678
|
+
return lastValueFrom(this.secureApiClient.post(this.directPaymentApiRoute, new URLSearchParams({ ...requestParams }), {
|
|
679
|
+
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
|
|
680
|
+
responseType: 'json',
|
|
681
|
+
}));
|
|
682
|
+
}
|
|
683
|
+
collectAnalyticsParameters(paymentMethodId, paymentWithSavedMethod) {
|
|
684
|
+
const parameters = {};
|
|
685
|
+
parameters.paymentWithSavedMethod = paymentWithSavedMethod
|
|
686
|
+
? paymentWithSavedMethod
|
|
687
|
+
: "0" /* XpsBoolean.false */;
|
|
688
|
+
if (!paymentMethodId) {
|
|
689
|
+
return parameters;
|
|
690
|
+
}
|
|
691
|
+
/* If payment method with 3DSecure */
|
|
692
|
+
if (cardsWith3ds.includes(Number(paymentMethodId))) {
|
|
693
|
+
parameters.container3DS = JSON.stringify({
|
|
694
|
+
browserjavaenabled: this.window.navigator.javaEnabled(),
|
|
695
|
+
browserlanguage: this.window.navigator.language,
|
|
696
|
+
browsercolordepth: this.window.screen.colorDepth,
|
|
697
|
+
browserscreenheight: this.window.screen.availHeight,
|
|
698
|
+
browserscreenwidth: this.window.screen.availWidth,
|
|
699
|
+
browsertz: new Date().getTimezoneOffset(),
|
|
700
|
+
browserappname: this.window.navigator.appName,
|
|
701
|
+
browserlocaltime: new Date().toString(),
|
|
702
|
+
browserplatform: this.window.navigator.platform || '',
|
|
703
|
+
browsercookiesenabled: this.window.navigator.cookieEnabled,
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
return parameters;
|
|
707
|
+
}
|
|
708
|
+
collectUserSessionId() {
|
|
709
|
+
const parameters = {};
|
|
710
|
+
parameters.xps_idUserSession = this.settingsService.user.session_id ?? '';
|
|
711
|
+
parameters.user_session_id = this.settingsService.user.session_id ?? '';
|
|
712
|
+
return parameters;
|
|
638
713
|
}
|
|
639
714
|
}
|
|
715
|
+
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 });
|
|
716
|
+
XpsApiService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: XpsApiService, providedIn: 'root' });
|
|
717
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: XpsApiService, decorators: [{
|
|
718
|
+
type: Injectable,
|
|
719
|
+
args: [{
|
|
720
|
+
providedIn: 'root',
|
|
721
|
+
}]
|
|
722
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
723
|
+
type: Inject,
|
|
724
|
+
args: [windowToken]
|
|
725
|
+
}] }, { type: SecureApiClient }, { type: SettingsService }, { type: CountryService }]; } });
|
|
640
726
|
|
|
641
727
|
class ShowFieldsAction {
|
|
642
728
|
constructor(submitResponse) {
|
|
@@ -669,9 +755,8 @@ const showFieldsActionFactoryProvider = {
|
|
|
669
755
|
class CheckStatusAction {
|
|
670
756
|
constructor(submitResponse) {
|
|
671
757
|
this.type = 'check_status';
|
|
672
|
-
const status = submitResponse.parameters.status;
|
|
673
758
|
this.data = {
|
|
674
|
-
invoice:
|
|
759
|
+
invoice: parseInt(submitResponse.parameters.form.fix_invoice?.value),
|
|
675
760
|
signature: submitResponse.parameters.form.signature?.value,
|
|
676
761
|
locale: submitResponse.parameters.form.locale?.value,
|
|
677
762
|
testPs: submitResponse.parameters.form.testPs?.value,
|
|
@@ -759,6 +844,22 @@ const showErrorsActionFactoryProvider = {
|
|
|
759
844
|
},
|
|
760
845
|
};
|
|
761
846
|
|
|
847
|
+
class ThreeDsAction {
|
|
848
|
+
constructor(statusUpdate) {
|
|
849
|
+
this.type = '3DS';
|
|
850
|
+
this.data = statusUpdate;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
const threeDsActionFactoryToken = new InjectionToken('ThreeDsAction');
|
|
855
|
+
const threeDsActionFactoryProvider = {
|
|
856
|
+
provide: threeDsActionFactoryToken,
|
|
857
|
+
useValue: {
|
|
858
|
+
factory: (...args) => new ThreeDsAction(...args),
|
|
859
|
+
isSuitable: () => false,
|
|
860
|
+
},
|
|
861
|
+
};
|
|
862
|
+
|
|
762
863
|
const nextActionsToken = new InjectionToken('Action');
|
|
763
864
|
const nextActions = [
|
|
764
865
|
showFieldsActionFactoryProvider,
|
|
@@ -768,6 +869,7 @@ const nextActions = [
|
|
|
768
869
|
const flowUpdateNextActions = [
|
|
769
870
|
statusUpdatedActionFactoryProvider,
|
|
770
871
|
showErrorsActionFactoryProvider,
|
|
872
|
+
threeDsActionFactoryProvider,
|
|
771
873
|
];
|
|
772
874
|
|
|
773
875
|
class NextActionService {
|
|
@@ -825,1048 +927,1042 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
825
927
|
args: [nextActionsToken]
|
|
826
928
|
}] }, { type: i0.Injector }]; } });
|
|
827
929
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
const requestParams = {
|
|
841
|
-
access_token: this.settingsService.token,
|
|
842
|
-
pid: String(config.paymentMethodId),
|
|
843
|
-
refer: this.ps4ReferId,
|
|
844
|
-
country: this.countryService.getCountry(),
|
|
845
|
-
returnUrl: config.returnUrl,
|
|
846
|
-
};
|
|
847
|
-
return lastValueFrom(this.secureApi
|
|
848
|
-
.post(this.apiRoute, new URLSearchParams({ ...requestParams }), {
|
|
849
|
-
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
|
|
850
|
-
responseType: 'json',
|
|
851
|
-
})
|
|
852
|
-
.pipe(map((response) => this.responseFactory(response)), tap((response) => {
|
|
853
|
-
if (response.paymentForm?.errors?.length) {
|
|
854
|
-
this.nextActionService.emitFlowUpdates(new ShowErrorsAction(response.paymentForm.errors));
|
|
855
|
-
}
|
|
856
|
-
}))).catch((error) => {
|
|
857
|
-
throw new ResponseError(error.message);
|
|
858
|
-
});
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
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 });
|
|
862
|
-
InitializeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, providedIn: 'root' });
|
|
863
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, decorators: [{
|
|
864
|
-
type: Injectable,
|
|
865
|
-
args: [{
|
|
866
|
-
providedIn: 'root',
|
|
867
|
-
}]
|
|
868
|
-
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
869
|
-
type: Inject,
|
|
870
|
-
args: [initializeResponseFactoryToken]
|
|
871
|
-
}] }, { type: SecureApiClient }, { type: SettingsService }, { type: CountryService }, { type: NextActionService }]; } });
|
|
930
|
+
var ErrorTags;
|
|
931
|
+
(function (ErrorTags) {
|
|
932
|
+
ErrorTags["APP"] = "appError";
|
|
933
|
+
ErrorTags["HTTP"] = "httpError";
|
|
934
|
+
ErrorTags["JS"] = "jsError";
|
|
935
|
+
ErrorTags["WS"] = "webSocket";
|
|
936
|
+
ErrorTags["ENCRYPT"] = "encrypt";
|
|
937
|
+
ErrorTags["APPLEPAY"] = "applepay";
|
|
938
|
+
ErrorTags["HEADLESS_UI"] = "headlessUi";
|
|
939
|
+
ErrorTags["GOOGLEPAY"] = "googlepay";
|
|
940
|
+
ErrorTags["PAYTM"] = "paytm";
|
|
941
|
+
})(ErrorTags || (ErrorTags = {}));
|
|
872
942
|
|
|
873
|
-
class
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
943
|
+
class TaggedError extends Error {
|
|
944
|
+
constructor(message, tags) {
|
|
945
|
+
super(message);
|
|
946
|
+
this.tags = [];
|
|
947
|
+
this.parentTag = ErrorTags.HEADLESS_UI;
|
|
948
|
+
this.tags = this.childTag
|
|
949
|
+
? [this.parentTag, this.childTag]
|
|
950
|
+
: [this.parentTag];
|
|
951
|
+
if (tags) {
|
|
952
|
+
const newTags = tags.filter((t, i, arr) => !this.tags.includes(t) && arr.indexOf(t) == i);
|
|
953
|
+
this.tags = [...this.tags, ...newTags];
|
|
877
954
|
}
|
|
878
955
|
}
|
|
879
956
|
}
|
|
880
957
|
|
|
881
|
-
class
|
|
882
|
-
constructor() {
|
|
883
|
-
|
|
958
|
+
class EncryptCreditCardError extends TaggedError {
|
|
959
|
+
constructor(message, tags) {
|
|
960
|
+
tags = tags ? [...tags, ErrorTags.ENCRYPT] : [ErrorTags.ENCRYPT];
|
|
961
|
+
super(message, tags);
|
|
884
962
|
}
|
|
885
963
|
}
|
|
886
964
|
|
|
887
|
-
|
|
888
|
-
constructor(parameters) {
|
|
889
|
-
super();
|
|
890
|
-
const { token, fields, form, dfpHash } = parameters;
|
|
891
|
-
if (token === null) {
|
|
892
|
-
throw new TokenError();
|
|
893
|
-
}
|
|
894
|
-
this.access_token = token;
|
|
895
|
-
if (dfpHash) {
|
|
896
|
-
this.xps_dfp_hash = dfpHash;
|
|
897
|
-
}
|
|
898
|
-
this.addXpsParameters(this.getFieldsValues(fields, form));
|
|
899
|
-
}
|
|
900
|
-
getFieldsValues(fields, form) {
|
|
901
|
-
return fields.reduce((xpsParams, field) => {
|
|
902
|
-
const formControl = form.get(field.name);
|
|
903
|
-
xpsParams[field.name] = formControl ? formControl.value : field?.value;
|
|
904
|
-
return xpsParams;
|
|
905
|
-
}, {});
|
|
906
|
-
}
|
|
907
|
-
}
|
|
965
|
+
const fourBlockMask = '9999 9999 9999 9999';
|
|
908
966
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
967
|
+
var CreditCardTypes;
|
|
968
|
+
(function (CreditCardTypes) {
|
|
969
|
+
CreditCardTypes["DEFAULT"] = "0";
|
|
970
|
+
CreditCardTypes["VISA"] = "1";
|
|
971
|
+
CreditCardTypes["MASTERCARD"] = "2";
|
|
972
|
+
CreditCardTypes["MAESTRO"] = "3";
|
|
973
|
+
CreditCardTypes["AMERICAN_EXPRESS"] = "4";
|
|
974
|
+
CreditCardTypes["DINERS_CLUBS"] = "5";
|
|
975
|
+
CreditCardTypes["DISCOVER"] = "6";
|
|
976
|
+
CreditCardTypes["JCB"] = "9";
|
|
977
|
+
CreditCardTypes["DANKORT"] = "11";
|
|
978
|
+
CreditCardTypes["HIPERCARD"] = "12";
|
|
979
|
+
CreditCardTypes["ELO"] = "13";
|
|
980
|
+
CreditCardTypes["AURA"] = "14";
|
|
981
|
+
CreditCardTypes["NARANJA"] = "15";
|
|
982
|
+
CreditCardTypes["MIR"] = "16";
|
|
983
|
+
CreditCardTypes["CHINA_UNION_PAY"] = "17";
|
|
984
|
+
CreditCardTypes["POSTEPAY"] = "18";
|
|
985
|
+
})(CreditCardTypes || (CreditCardTypes = {}));
|
|
986
|
+
|
|
987
|
+
const visa = {
|
|
988
|
+
id: CreditCardTypes.VISA,
|
|
989
|
+
minLength: 13,
|
|
990
|
+
maxLength: 16,
|
|
991
|
+
iconName: 'visa',
|
|
992
|
+
mask: fourBlockMask,
|
|
993
|
+
checkNumber(number) {
|
|
994
|
+
return number.startsWith('4');
|
|
995
|
+
},
|
|
913
996
|
};
|
|
914
997
|
|
|
915
|
-
const
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
998
|
+
const mastercard = {
|
|
999
|
+
id: CreditCardTypes.MASTERCARD,
|
|
1000
|
+
minLength: 16,
|
|
1001
|
+
maxLength: 16,
|
|
1002
|
+
iconName: 'mastercard',
|
|
1003
|
+
mask: fourBlockMask,
|
|
1004
|
+
checkNumber(number) {
|
|
1005
|
+
const subLength = 6;
|
|
1006
|
+
const cardNumberSub = number.substring(0, subLength);
|
|
1007
|
+
return (new RegExp(/^5[1-5]/).test(number) ||
|
|
1008
|
+
(cardNumberSub >= '222100' && cardNumberSub <= '272099'));
|
|
1009
|
+
},
|
|
919
1010
|
};
|
|
920
1011
|
|
|
921
|
-
|
|
922
|
-
constructor(message, code) {
|
|
923
|
-
super(message);
|
|
924
|
-
this.code = code;
|
|
925
|
-
}
|
|
926
|
-
}
|
|
1012
|
+
const defaultMask = '9999 9999 9999 9999 999';
|
|
927
1013
|
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
1014
|
+
const maestro = {
|
|
1015
|
+
id: CreditCardTypes.MAESTRO,
|
|
1016
|
+
minLength: 12,
|
|
1017
|
+
maxLength: 19,
|
|
1018
|
+
iconName: 'maestro',
|
|
1019
|
+
mask: defaultMask,
|
|
1020
|
+
checkNumber(number) {
|
|
1021
|
+
return new RegExp(/^(5018)|^(5020)|^(5038)|^(5893)|^(6304)|^(6759)|^(6761)|^(6762)|^(6763)|^(0604)|^(6706)|^(6771)|^(6709)/).test(number);
|
|
1022
|
+
},
|
|
1023
|
+
maxCvvLength: 3,
|
|
1024
|
+
};
|
|
934
1025
|
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
}
|
|
947
|
-
this.fingerprintJs = await this.loadFingerprintJs();
|
|
948
|
-
this.hash = await this.buildHash();
|
|
949
|
-
this.antifraudFingerprintLibrary =
|
|
950
|
-
await this.loadAntifraudFingerprintLibrary();
|
|
951
|
-
}
|
|
952
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
953
|
-
async getHash() {
|
|
954
|
-
return this.hash;
|
|
955
|
-
}
|
|
956
|
-
async loadFingerprintJs() {
|
|
957
|
-
const { default: library, murmurX64Hash128: getHash } = await import('@fingerprintjs/fingerprintjs');
|
|
958
|
-
return { library, getHash };
|
|
959
|
-
}
|
|
960
|
-
async loadAntifraudFingerprintLibrary() {
|
|
961
|
-
const library = await import('@xsolla/antifraud-fingerprint');
|
|
962
|
-
return library.default;
|
|
963
|
-
}
|
|
964
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
965
|
-
async makeAntifraudFingerprint() {
|
|
966
|
-
if (!this.settingsService.token) {
|
|
967
|
-
return null;
|
|
968
|
-
}
|
|
969
|
-
const antifraudFingerprint = this.antifraudFingerprintLibrary;
|
|
970
|
-
try {
|
|
971
|
-
return new antifraudFingerprint({
|
|
972
|
-
api: {
|
|
973
|
-
url: this.fingerprintApiUrl,
|
|
974
|
-
token: this.settingsService.token,
|
|
975
|
-
timeout: 3000,
|
|
976
|
-
},
|
|
977
|
-
retry: {
|
|
978
|
-
num: 1,
|
|
979
|
-
timeout: 500,
|
|
980
|
-
},
|
|
981
|
-
});
|
|
982
|
-
}
|
|
983
|
-
catch (error) {
|
|
984
|
-
return null;
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
/**
|
|
988
|
-
*Загружаем библиотеку, генерируем данные,
|
|
989
|
-
*хешируем с помощью BASE64 и отправляем на бэкенд,
|
|
990
|
-
*в ответ получаем dfp_hash.
|
|
991
|
-
**/
|
|
992
|
-
async buildHash() {
|
|
993
|
-
const fingerPrintData = await this.generate();
|
|
994
|
-
const hash = await this.send(fingerPrintData).catch(() => {
|
|
995
|
-
return null;
|
|
996
|
-
});
|
|
997
|
-
return JSON.stringify(hash);
|
|
998
|
-
}
|
|
999
|
-
/**
|
|
1000
|
-
*Новая версия библиотеки содержит не все компоненты, некоторые приходится имплементировать самостоятельно
|
|
1001
|
-
**/
|
|
1002
|
-
getHasLiedResolution() {
|
|
1003
|
-
const { screen } = this.window;
|
|
1004
|
-
return (screen.width < screen.availWidth || screen.height < screen.availHeight);
|
|
1005
|
-
}
|
|
1006
|
-
/**
|
|
1007
|
-
*Бэкенд заточен под конкретные поля, которые необходимо смапить.
|
|
1008
|
-
**/
|
|
1009
|
-
getComponents(components) {
|
|
1010
|
-
return {
|
|
1011
|
-
user_agent: navigator.userAgent,
|
|
1012
|
-
language: components.languages.value?.shift()?.shift() ?? '',
|
|
1013
|
-
color_depth: components.colorDepth.value,
|
|
1014
|
-
device_memory: components.deviceMemory.value,
|
|
1015
|
-
hardware_concurrency: components.hardwareConcurrency.value,
|
|
1016
|
-
resolution: components.screenResolution.value,
|
|
1017
|
-
available_resolution: components.screenResolution.value,
|
|
1018
|
-
timezone_offset: new Date().getTimezoneOffset(),
|
|
1019
|
-
session_storage: components.sessionStorage.value ? 1 : 0,
|
|
1020
|
-
local_storage: components.localStorage.value ? 1 : 0,
|
|
1021
|
-
indexed_db: components.indexedDB.value ? 1 : 0,
|
|
1022
|
-
open_database: components.openDatabase.value ? 1 : 0,
|
|
1023
|
-
navigator_platform: components.platform.value,
|
|
1024
|
-
regular_plugins: components.plugins.value?.map((plugin) => plugin.name) ?? [],
|
|
1025
|
-
canvas: components.canvas.value?.text,
|
|
1026
|
-
webgl: components.canvas.value?.text,
|
|
1027
|
-
webgl_vendor: components.vendor.value,
|
|
1028
|
-
has_lied_resolution: this.getHasLiedResolution(),
|
|
1029
|
-
touch_support: Object.values(components.touchSupport.value ?? {}),
|
|
1030
|
-
js_fonts: components.fonts.value,
|
|
1031
|
-
};
|
|
1032
|
-
}
|
|
1033
|
-
/**
|
|
1034
|
-
* Получаем данные dfp с помощью FingerprintJS, мапим необходимые поля, добавляем хэш
|
|
1035
|
-
**/
|
|
1036
|
-
async generate() {
|
|
1037
|
-
const { library, getHash } = this.fingerprintJs;
|
|
1038
|
-
const fingerprint = await library.load();
|
|
1039
|
-
const commonFingerPrintData = await fingerprint.get();
|
|
1040
|
-
const fingerPrintData = this.getComponents(commonFingerPrintData.components);
|
|
1041
|
-
fingerPrintData.hash = getHash(JSON.stringify(fingerPrintData));
|
|
1042
|
-
return fingerPrintData;
|
|
1043
|
-
}
|
|
1044
|
-
/**
|
|
1045
|
-
* Отправка dfp на сервер, в ответ получаем dfp_hash
|
|
1046
|
-
**/
|
|
1047
|
-
async send(fingerPrintData) {
|
|
1048
|
-
const token = this.settingsService.token;
|
|
1049
|
-
if (token === null) {
|
|
1050
|
-
throw new DefaultTerminalError();
|
|
1051
|
-
}
|
|
1052
|
-
const requestBody = {
|
|
1053
|
-
access_token: token,
|
|
1054
|
-
'dfp[200]': '',
|
|
1055
|
-
};
|
|
1056
|
-
requestBody['dfp[200]'] = btoa(encodeURIComponent(JSON.stringify(fingerPrintData)));
|
|
1057
|
-
return lastValueFrom(this.secureApi.post(this.apiRoute, new URLSearchParams(requestBody), {
|
|
1058
|
-
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
|
|
1059
|
-
responseType: 'json',
|
|
1060
|
-
}))
|
|
1061
|
-
.then((response) => {
|
|
1062
|
-
return response.dfp_hash;
|
|
1063
|
-
})
|
|
1064
|
-
.then(async (hash) => {
|
|
1065
|
-
const fingerprint = await this.makeAntifraudFingerprint();
|
|
1066
|
-
if (!fingerprint) {
|
|
1067
|
-
return null;
|
|
1068
|
-
}
|
|
1069
|
-
await fingerprint
|
|
1070
|
-
?.dispatch(hash['200'])
|
|
1071
|
-
.catch((err) => console.log(err));
|
|
1072
|
-
const afsHash = await fingerprint.hash();
|
|
1073
|
-
return { '301': afsHash, ...hash };
|
|
1074
|
-
})
|
|
1075
|
-
.catch((error) => {
|
|
1076
|
-
const response = error.getHttpErrorData().response;
|
|
1077
|
-
throw new TerminalError(response.data?.errors[0]?.message ?? '', response.data?.errors[0]?.support_code ?? '');
|
|
1078
|
-
});
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
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 });
|
|
1082
|
-
DeviceFingerPrintService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, providedIn: 'root' });
|
|
1083
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, decorators: [{
|
|
1084
|
-
type: Injectable,
|
|
1085
|
-
args: [{
|
|
1086
|
-
providedIn: 'root',
|
|
1087
|
-
}]
|
|
1088
|
-
}], ctorParameters: function () { return [{ type: SecureApiClient }, { type: SettingsService }, { type: undefined, decorators: [{
|
|
1089
|
-
type: Inject,
|
|
1090
|
-
args: [windowToken]
|
|
1091
|
-
}] }]; } });
|
|
1026
|
+
const americanExpress = {
|
|
1027
|
+
id: CreditCardTypes.AMERICAN_EXPRESS,
|
|
1028
|
+
minLength: 15,
|
|
1029
|
+
maxLength: 15,
|
|
1030
|
+
iconName: 'american-express',
|
|
1031
|
+
mask: '9999 999999 99999',
|
|
1032
|
+
checkNumber(number) {
|
|
1033
|
+
return new RegExp(/^(34)|^(37)/).test(number);
|
|
1034
|
+
},
|
|
1035
|
+
maxCvvLength: 4,
|
|
1036
|
+
};
|
|
1092
1037
|
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
// In this way two promises become unequal, that can broke XPS API requests logic.
|
|
1105
|
-
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
1106
|
-
request(fields, form) {
|
|
1107
|
-
const responsePromise = this.deviceFingerPrintService
|
|
1108
|
-
.getHash()
|
|
1109
|
-
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
1110
|
-
.then((dfpHash) => {
|
|
1111
|
-
const requestParams = this.requestFactory({
|
|
1112
|
-
token: this.settingsService.token,
|
|
1113
|
-
fields,
|
|
1114
|
-
form,
|
|
1115
|
-
dfpHash,
|
|
1116
|
-
});
|
|
1117
|
-
return lastValueFrom(this.secureApi.post(this.directPaymentApiRoute, new URLSearchParams({ ...requestParams }), {
|
|
1118
|
-
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
|
|
1119
|
-
responseType: 'json',
|
|
1120
|
-
}))
|
|
1121
|
-
.then((response) => this.responseFactory(response))
|
|
1122
|
-
.catch((error) => {
|
|
1123
|
-
throw new ResponseError(error.message);
|
|
1124
|
-
});
|
|
1125
|
-
});
|
|
1126
|
-
return responsePromise;
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
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 });
|
|
1130
|
-
SubmitService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, providedIn: 'root' });
|
|
1131
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, decorators: [{
|
|
1132
|
-
type: Injectable,
|
|
1133
|
-
args: [{ providedIn: 'root' }]
|
|
1134
|
-
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
1135
|
-
type: Inject,
|
|
1136
|
-
args: [submitRequestFactoryToken]
|
|
1137
|
-
}] }, { type: undefined, decorators: [{
|
|
1138
|
-
type: Inject,
|
|
1139
|
-
args: [submitResponseFactoryToken]
|
|
1140
|
-
}] }, { type: SettingsService }, { type: DeviceFingerPrintService }, { type: SecureApiClient }]; } });
|
|
1038
|
+
const dinersClubs = {
|
|
1039
|
+
id: CreditCardTypes.DINERS_CLUBS,
|
|
1040
|
+
minLength: 14,
|
|
1041
|
+
maxLength: 14,
|
|
1042
|
+
iconName: 'dinersclub',
|
|
1043
|
+
mask: '9999 9999 9999 99',
|
|
1044
|
+
checkNumber(number) {
|
|
1045
|
+
const regex = /^(36[0-9]|3(?:0[0-59]|[68][0-9])[0-9])/;
|
|
1046
|
+
return regex.test(number);
|
|
1047
|
+
},
|
|
1048
|
+
};
|
|
1141
1049
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
}
|
|
1050
|
+
const discover = {
|
|
1051
|
+
id: CreditCardTypes.DISCOVER,
|
|
1052
|
+
minLength: 16,
|
|
1053
|
+
maxLength: 19,
|
|
1054
|
+
iconName: 'discover',
|
|
1055
|
+
mask: defaultMask,
|
|
1056
|
+
checkNumber(number) {
|
|
1057
|
+
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);
|
|
1058
|
+
},
|
|
1059
|
+
};
|
|
1151
1060
|
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1061
|
+
const jcb = {
|
|
1062
|
+
id: CreditCardTypes.JCB,
|
|
1063
|
+
minLength: 15,
|
|
1064
|
+
maxLength: 16,
|
|
1065
|
+
iconName: 'jcb',
|
|
1066
|
+
mask: fourBlockMask,
|
|
1067
|
+
checkNumber(number) {
|
|
1068
|
+
return new RegExp(/^35(2[89]|[3-8][0-9])/).test(number);
|
|
1069
|
+
},
|
|
1070
|
+
};
|
|
1159
1071
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
getFieldsValues(changedField, fields, form) {
|
|
1173
|
-
const fieldsMap = this.getFieldsMap(fields);
|
|
1174
|
-
return changedField?.javascript?.change.params.reduce((xpsParams, fieldName) => {
|
|
1175
|
-
const formControl = form.get(fieldName);
|
|
1176
|
-
const field = fieldsMap.get(fieldName);
|
|
1177
|
-
if (formControl || field) {
|
|
1178
|
-
xpsParams[fieldName] = formControl?.value ?? field?.value;
|
|
1179
|
-
}
|
|
1180
|
-
return xpsParams;
|
|
1181
|
-
}, {});
|
|
1182
|
-
}
|
|
1183
|
-
getFieldsMap(fields) {
|
|
1184
|
-
const map = new Map();
|
|
1185
|
-
fields.forEach((field) => map.set(field.name, field));
|
|
1186
|
-
return map;
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1072
|
+
const dankort = {
|
|
1073
|
+
id: CreditCardTypes.DANKORT,
|
|
1074
|
+
minLength: 16,
|
|
1075
|
+
maxLength: 16,
|
|
1076
|
+
iconName: 'dankort',
|
|
1077
|
+
mask: fourBlockMask,
|
|
1078
|
+
checkNumber(number) {
|
|
1079
|
+
const subLength = 4;
|
|
1080
|
+
const cardNumberSub = number.substring(0, subLength);
|
|
1081
|
+
return cardNumberSub === '5019';
|
|
1082
|
+
},
|
|
1083
|
+
};
|
|
1189
1084
|
|
|
1190
|
-
const
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1085
|
+
const hipercard = {
|
|
1086
|
+
id: CreditCardTypes.HIPERCARD,
|
|
1087
|
+
minLength: 13,
|
|
1088
|
+
maxLength: 19,
|
|
1089
|
+
iconName: 'hipercard',
|
|
1090
|
+
mask: defaultMask,
|
|
1091
|
+
checkNumber(number) {
|
|
1092
|
+
return new RegExp(/^((606282|637095|637568)[0-9]|38[0-9]{14,17})/).test(number);
|
|
1093
|
+
},
|
|
1194
1094
|
};
|
|
1195
1095
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
};
|
|
1207
|
-
}
|
|
1208
|
-
this.fields = Object.keys(response.form).map((key) => response.form[key]);
|
|
1209
|
-
this.parameters = response;
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1096
|
+
const elo = {
|
|
1097
|
+
id: CreditCardTypes.ELO,
|
|
1098
|
+
minLength: 16,
|
|
1099
|
+
maxLength: 19,
|
|
1100
|
+
iconName: 'elo',
|
|
1101
|
+
mask: defaultMask,
|
|
1102
|
+
checkNumber(number) {
|
|
1103
|
+
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);
|
|
1104
|
+
},
|
|
1105
|
+
};
|
|
1212
1106
|
|
|
1213
|
-
const
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1107
|
+
const aura = {
|
|
1108
|
+
id: CreditCardTypes.AURA,
|
|
1109
|
+
minLength: 16,
|
|
1110
|
+
maxLength: 19,
|
|
1111
|
+
iconName: 'aura',
|
|
1112
|
+
mask: defaultMask,
|
|
1113
|
+
checkNumber(number) {
|
|
1114
|
+
const subLength = 8;
|
|
1115
|
+
const cardNumberSub = number.substring(0, subLength);
|
|
1116
|
+
return ['50786000', '50786018', '50786019'].includes(cardNumberSub);
|
|
1117
|
+
},
|
|
1217
1118
|
};
|
|
1218
1119
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1120
|
+
const naranja = {
|
|
1121
|
+
id: CreditCardTypes.NARANJA,
|
|
1122
|
+
minLength: 12,
|
|
1123
|
+
maxLength: 19,
|
|
1124
|
+
iconName: 'naranja',
|
|
1125
|
+
mask: defaultMask,
|
|
1126
|
+
checkNumber(number) {
|
|
1127
|
+
const subLength = 6;
|
|
1128
|
+
const cardNumberSub = number.substring(0, subLength);
|
|
1129
|
+
return cardNumberSub === '589562';
|
|
1130
|
+
},
|
|
1131
|
+
};
|
|
1132
|
+
|
|
1133
|
+
const mir = {
|
|
1134
|
+
id: CreditCardTypes.MIR,
|
|
1135
|
+
minLength: 16,
|
|
1136
|
+
maxLength: 16,
|
|
1137
|
+
iconName: 'mir',
|
|
1138
|
+
mask: defaultMask,
|
|
1139
|
+
checkNumber(number) {
|
|
1140
|
+
const subLength = 4;
|
|
1141
|
+
const cardNumberSub = number.substring(0, subLength);
|
|
1142
|
+
return cardNumberSub >= '2200' && cardNumberSub <= '2204';
|
|
1143
|
+
},
|
|
1144
|
+
};
|
|
1145
|
+
|
|
1146
|
+
const chinaUnionPay = {
|
|
1147
|
+
id: CreditCardTypes.CHINA_UNION_PAY,
|
|
1148
|
+
minLength: 16,
|
|
1149
|
+
maxLength: 19,
|
|
1150
|
+
iconName: 'unionpay',
|
|
1151
|
+
mask: '999 9999 9999 99999999',
|
|
1152
|
+
checkNumber(number) {
|
|
1153
|
+
return number.startsWith('62');
|
|
1154
|
+
},
|
|
1155
|
+
};
|
|
1156
|
+
|
|
1157
|
+
const defaultCard = {
|
|
1158
|
+
id: CreditCardTypes.DEFAULT,
|
|
1159
|
+
minLength: 12,
|
|
1160
|
+
maxLength: 19,
|
|
1161
|
+
iconName: null,
|
|
1162
|
+
mask: defaultMask,
|
|
1163
|
+
checkNumber() {
|
|
1164
|
+
return false;
|
|
1165
|
+
},
|
|
1166
|
+
};
|
|
1167
|
+
|
|
1168
|
+
const postePay = {
|
|
1169
|
+
id: CreditCardTypes.POSTEPAY,
|
|
1170
|
+
minLength: 12,
|
|
1171
|
+
maxLength: 19,
|
|
1172
|
+
iconName: 'poste_pay',
|
|
1173
|
+
mask: '9999 9999 9999 9999 999',
|
|
1174
|
+
checkNumber(number) {
|
|
1175
|
+
const regex = /^(5018)|^(5020)|^(5038)|^(5893)|^(6304)|^(6759)|^(6761)|^(6762)|^(6763)|^(0604)|^(6706)|^(6771)|^(6709)/;
|
|
1176
|
+
return regex.test(number);
|
|
1177
|
+
},
|
|
1178
|
+
};
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* order does matter
|
|
1182
|
+
* settings with more specific pattern should be placed above
|
|
1183
|
+
* Example:
|
|
1184
|
+
* - 12*
|
|
1185
|
+
* - 12
|
|
1186
|
+
* - 1
|
|
1187
|
+
* "12*" pattern should be checked first, otherwise pattern "1" will be taken
|
|
1188
|
+
* before "12*" checked
|
|
1189
|
+
*/
|
|
1190
|
+
const orderedCardSettings = [
|
|
1191
|
+
aura,
|
|
1192
|
+
naranja,
|
|
1193
|
+
maestro,
|
|
1194
|
+
postePay,
|
|
1195
|
+
elo,
|
|
1196
|
+
discover,
|
|
1197
|
+
dankort,
|
|
1198
|
+
hipercard,
|
|
1199
|
+
mir,
|
|
1200
|
+
jcb,
|
|
1201
|
+
dinersClubs,
|
|
1202
|
+
americanExpress,
|
|
1203
|
+
mastercard,
|
|
1204
|
+
chinaUnionPay,
|
|
1205
|
+
visa,
|
|
1206
|
+
defaultCard,
|
|
1207
|
+
];
|
|
1208
|
+
|
|
1209
|
+
const creditCardsMap = {
|
|
1210
|
+
[CreditCardTypes.DEFAULT]: defaultCard,
|
|
1211
|
+
[CreditCardTypes.VISA]: visa,
|
|
1212
|
+
[CreditCardTypes.MASTERCARD]: mastercard,
|
|
1213
|
+
[CreditCardTypes.MAESTRO]: maestro,
|
|
1214
|
+
[CreditCardTypes.AMERICAN_EXPRESS]: americanExpress,
|
|
1215
|
+
[CreditCardTypes.DINERS_CLUBS]: dinersClubs,
|
|
1216
|
+
[CreditCardTypes.DISCOVER]: discover,
|
|
1217
|
+
[CreditCardTypes.JCB]: jcb,
|
|
1218
|
+
[CreditCardTypes.DANKORT]: dankort,
|
|
1219
|
+
[CreditCardTypes.HIPERCARD]: hipercard,
|
|
1220
|
+
[CreditCardTypes.ELO]: elo,
|
|
1221
|
+
[CreditCardTypes.AURA]: aura,
|
|
1222
|
+
[CreditCardTypes.NARANJA]: naranja,
|
|
1223
|
+
[CreditCardTypes.MIR]: mir,
|
|
1224
|
+
[CreditCardTypes.CHINA_UNION_PAY]: chinaUnionPay,
|
|
1225
|
+
[CreditCardTypes.POSTEPAY]: postePay,
|
|
1226
|
+
};
|
|
1227
|
+
|
|
1228
|
+
class CreditCardService {
|
|
1229
|
+
getBinNumber(cardNumber) {
|
|
1230
|
+
const binNumberLength = 6;
|
|
1231
|
+
return cardNumber.replace(/\s+/g, '').substring(0, binNumberLength);
|
|
1272
1232
|
}
|
|
1273
|
-
|
|
1274
|
-
const
|
|
1275
|
-
return
|
|
1233
|
+
getAccountSuffix(cardNumber) {
|
|
1234
|
+
const accountSuffixLength = 4;
|
|
1235
|
+
return cardNumber
|
|
1236
|
+
.replace(/\s+/g, '')
|
|
1237
|
+
.substring(cardNumber.length - accountSuffixLength);
|
|
1276
1238
|
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
form: this.form,
|
|
1239
|
+
getTypeByNumber(cardNumber) {
|
|
1240
|
+
cardNumber = cardNumber.replace(/\s+/g, '');
|
|
1241
|
+
const cardSettings = orderedCardSettings.find((settings) => {
|
|
1242
|
+
const isNumberMatched = settings.checkNumber(cardNumber);
|
|
1243
|
+
return isNumberMatched ? settings.id : false;
|
|
1283
1244
|
});
|
|
1284
|
-
return
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1245
|
+
return cardSettings ? cardSettings.id : defaultCard.id;
|
|
1246
|
+
}
|
|
1247
|
+
getCreditCardSettings(cardType) {
|
|
1248
|
+
const creditCard = creditCardsMap[cardType];
|
|
1249
|
+
if (!creditCard) {
|
|
1250
|
+
return defaultCard;
|
|
1251
|
+
}
|
|
1252
|
+
return creditCard;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
CreditCardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1256
|
+
CreditCardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, providedIn: 'root' });
|
|
1257
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, decorators: [{
|
|
1258
|
+
type: Injectable,
|
|
1259
|
+
args: [{
|
|
1260
|
+
providedIn: 'root',
|
|
1261
|
+
}]
|
|
1262
|
+
}] });
|
|
1263
|
+
|
|
1264
|
+
class EncryptCreditCardService {
|
|
1265
|
+
constructor(creditCardService) {
|
|
1266
|
+
this.creditCardService = creditCardService;
|
|
1267
|
+
this.secureFieldNames = [
|
|
1268
|
+
'xps_card_number',
|
|
1269
|
+
'xps_cvv',
|
|
1270
|
+
'xps_extra_cvv',
|
|
1271
|
+
'xps_card_year',
|
|
1272
|
+
'xps_card_month',
|
|
1273
|
+
];
|
|
1274
|
+
this.jsEncrypt = new JSEncrypt();
|
|
1275
|
+
}
|
|
1276
|
+
setPublicKey(publicKey) {
|
|
1277
|
+
this.jsEncrypt.setPublicKey(publicKey);
|
|
1278
|
+
}
|
|
1279
|
+
encryptCreditCard(request) {
|
|
1280
|
+
if (request.xps_card_number) {
|
|
1281
|
+
const openCard = this.createOpenCard(request);
|
|
1282
|
+
request.xps_open_card = JSON.stringify(openCard);
|
|
1283
|
+
}
|
|
1284
|
+
const encryptedCard = this.createEncryptedCard(request);
|
|
1285
|
+
if (!request.xps_encrypted_card && JSON.stringify(encryptedCard) !== '{}') {
|
|
1286
|
+
request.xps_encrypted_card = this.encrypt(JSON.stringify(encryptedCard));
|
|
1287
|
+
}
|
|
1288
|
+
this.secureFieldNames.forEach((secureFieldName) => {
|
|
1289
|
+
delete request[secureFieldName];
|
|
1293
1290
|
});
|
|
1291
|
+
return request;
|
|
1294
1292
|
}
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1293
|
+
encrypt(value) {
|
|
1294
|
+
if (!this.jsEncrypt?.getPublicKey()) {
|
|
1295
|
+
throw new EncryptCreditCardError('Empty public key');
|
|
1296
|
+
}
|
|
1297
|
+
const encryptedValue = this.jsEncrypt.encrypt(value);
|
|
1298
|
+
if (!encryptedValue) {
|
|
1299
|
+
throw new EncryptCreditCardError('Encryption returns false instead of encrypted string');
|
|
1300
|
+
}
|
|
1301
|
+
return encryptedValue;
|
|
1302
|
+
}
|
|
1303
|
+
createEncryptedCard(request) {
|
|
1304
|
+
const encryptedCard = {
|
|
1305
|
+
card_number: request.xps_card_number,
|
|
1306
|
+
card_year: request.xps_card_year,
|
|
1307
|
+
card_month: request.xps_card_month,
|
|
1308
|
+
cvv: request.xps_cvv,
|
|
1309
|
+
};
|
|
1310
|
+
if (request.xps_extra_cvv) {
|
|
1311
|
+
encryptedCard.cvv = request.xps_extra_cvv;
|
|
1312
|
+
}
|
|
1313
|
+
return encryptedCard;
|
|
1299
1314
|
}
|
|
1300
|
-
|
|
1301
|
-
return
|
|
1315
|
+
createOpenCard(request) {
|
|
1316
|
+
return {
|
|
1317
|
+
card_bin: this.creditCardService.getBinNumber(request.xps_card_number),
|
|
1318
|
+
card_suffix: this.creditCardService.getAccountSuffix(request.xps_card_number),
|
|
1319
|
+
card_year: request.xps_card_year,
|
|
1320
|
+
card_month: request.xps_card_month,
|
|
1321
|
+
};
|
|
1302
1322
|
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1323
|
+
}
|
|
1324
|
+
EncryptCreditCardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EncryptCreditCardService, deps: [{ token: CreditCardService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1325
|
+
EncryptCreditCardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EncryptCreditCardService, providedIn: 'root' });
|
|
1326
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EncryptCreditCardService, decorators: [{
|
|
1327
|
+
type: Injectable,
|
|
1328
|
+
args: [{ providedIn: 'root' }]
|
|
1329
|
+
}], ctorParameters: function () { return [{ type: CreditCardService }]; } });
|
|
1330
|
+
|
|
1331
|
+
class InitializeService {
|
|
1332
|
+
constructor(responseFactory, xpsApiService, settingsService, countryService, nextActionService, encryptCreditCardService) {
|
|
1333
|
+
this.responseFactory = responseFactory;
|
|
1334
|
+
this.xpsApiService = xpsApiService;
|
|
1335
|
+
this.settingsService = settingsService;
|
|
1336
|
+
this.countryService = countryService;
|
|
1337
|
+
this.nextActionService = nextActionService;
|
|
1338
|
+
this.encryptCreditCardService = encryptCreditCardService;
|
|
1339
|
+
// TODO PAYMENTS-15743: replace with new refer id for headless core
|
|
1340
|
+
this.ps4ReferId = '22';
|
|
1341
|
+
}
|
|
1342
|
+
async request(config) {
|
|
1343
|
+
const requestParams = {
|
|
1344
|
+
access_token: this.settingsService.token,
|
|
1345
|
+
pid: String(config.paymentMethodId),
|
|
1346
|
+
refer: this.ps4ReferId,
|
|
1347
|
+
country: this.countryService.getCountry(),
|
|
1348
|
+
returnUrl: config.returnUrl,
|
|
1349
|
+
};
|
|
1350
|
+
return this.xpsApiService
|
|
1351
|
+
.directPaymentRequest(requestParams)
|
|
1352
|
+
.then((response) => {
|
|
1353
|
+
const initializeResponse = this.responseFactory(response);
|
|
1354
|
+
if (initializeResponse.paymentForm?.errors?.length) {
|
|
1355
|
+
this.nextActionService.emitFlowUpdates(new ShowErrorsAction(initializeResponse.paymentForm.errors));
|
|
1356
|
+
}
|
|
1357
|
+
if (initializeResponse.paymentForm) {
|
|
1358
|
+
this.setCreditCardEncryptKey(initializeResponse.paymentForm);
|
|
1359
|
+
}
|
|
1360
|
+
return initializeResponse;
|
|
1361
|
+
})
|
|
1362
|
+
.catch((error) => {
|
|
1363
|
+
throw new ResponseError(error.message);
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
setCreditCardEncryptKey(paymentForm) {
|
|
1367
|
+
const publicKeyField = paymentForm.fields.find((field) => field.name === 'public_key');
|
|
1368
|
+
if (!publicKeyField) {
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
1371
|
+
this.encryptCreditCardService.setPublicKey(atob(publicKeyField.value));
|
|
1305
1372
|
}
|
|
1306
1373
|
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type:
|
|
1374
|
+
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 });
|
|
1375
|
+
InitializeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, providedIn: 'root' });
|
|
1376
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, decorators: [{
|
|
1310
1377
|
type: Injectable,
|
|
1311
1378
|
args: [{
|
|
1312
1379
|
providedIn: 'root',
|
|
1313
1380
|
}]
|
|
1314
1381
|
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
1315
1382
|
type: Inject,
|
|
1316
|
-
args: [
|
|
1317
|
-
}] }, { type:
|
|
1318
|
-
type: Inject,
|
|
1319
|
-
args: [syncResponseFactoryToken]
|
|
1320
|
-
}] }, { type: SecureApiClient }, { type: NextActionService }, { type: SettingsService }]; } });
|
|
1383
|
+
args: [initializeResponseFactoryToken]
|
|
1384
|
+
}] }, { type: XpsApiService }, { type: SettingsService }, { type: CountryService }, { type: NextActionService }, { type: EncryptCreditCardService }]; } });
|
|
1321
1385
|
|
|
1322
|
-
class
|
|
1323
|
-
|
|
1324
|
-
|
|
1386
|
+
class XpsApiPartRequest {
|
|
1387
|
+
addXpsParameters(parameters) {
|
|
1388
|
+
for (const key in parameters) {
|
|
1389
|
+
this[`xps_${key}`] = parameters[key];
|
|
1390
|
+
}
|
|
1325
1391
|
}
|
|
1326
1392
|
}
|
|
1327
1393
|
|
|
1328
|
-
class
|
|
1394
|
+
class TokenError extends AppError {
|
|
1329
1395
|
constructor() {
|
|
1330
|
-
super(
|
|
1331
|
-
this.controlType = 'text';
|
|
1396
|
+
super('XPS API needs token.');
|
|
1332
1397
|
}
|
|
1333
1398
|
}
|
|
1334
1399
|
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1400
|
+
class SubmitRequest extends XpsApiPartRequest {
|
|
1401
|
+
constructor(parameters) {
|
|
1402
|
+
super();
|
|
1403
|
+
const { token, fields, form, dfpHash } = parameters;
|
|
1404
|
+
if (token === null) {
|
|
1405
|
+
throw new TokenError();
|
|
1340
1406
|
}
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1407
|
+
this.access_token = token;
|
|
1408
|
+
if (dfpHash) {
|
|
1409
|
+
this.xps_dfp_hash = dfpHash;
|
|
1410
|
+
}
|
|
1411
|
+
this.addXpsParameters(this.getFieldsValues(fields, form));
|
|
1412
|
+
}
|
|
1413
|
+
getFieldsValues(fields, form) {
|
|
1414
|
+
return fields.reduce((xpsParams, field) => {
|
|
1415
|
+
const formControl = form.get(field.name);
|
|
1416
|
+
xpsParams[field.name] = formControl ? formControl.value : field?.value;
|
|
1417
|
+
return xpsParams;
|
|
1418
|
+
}, {});
|
|
1419
|
+
}
|
|
1348
1420
|
}
|
|
1349
1421
|
|
|
1350
|
-
const
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1422
|
+
const submitRequestFactoryToken = new InjectionToken('SubmitRequest');
|
|
1423
|
+
const submitRequestFactoryProvider = {
|
|
1424
|
+
provide: submitRequestFactoryToken,
|
|
1425
|
+
useValue: (...args) => new SubmitRequest(...args),
|
|
1426
|
+
};
|
|
1354
1427
|
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1428
|
+
const submitResponseFactoryToken = new InjectionToken('SubmitResponse');
|
|
1429
|
+
const submitResponseFactoryProvider = {
|
|
1430
|
+
provide: submitResponseFactoryToken,
|
|
1431
|
+
useValue: (...args) => new SubmitResponse(...args),
|
|
1432
|
+
};
|
|
1358
1433
|
|
|
1359
|
-
class
|
|
1360
|
-
constructor(
|
|
1361
|
-
this.
|
|
1434
|
+
class DeviceFingerPrintService {
|
|
1435
|
+
constructor(settingsService) {
|
|
1436
|
+
this.settingsService = settingsService;
|
|
1362
1437
|
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
config.disabled = true;
|
|
1438
|
+
init() {
|
|
1439
|
+
if (!this.settingsService.isInitialized) {
|
|
1440
|
+
return;
|
|
1367
1441
|
}
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
convertToFormControl(field) {
|
|
1371
|
-
return new UntypedFormControl(this.getValue(field), this.getValidators(field), this.getAsyncValidators(field));
|
|
1442
|
+
this.antifraudFingerprintLibrary = this.loadAntifraudFingerprintLibrary();
|
|
1443
|
+
this.hash = this.buildHash();
|
|
1372
1444
|
}
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
if (field.isMandatory === "1" /* XpsBoolean.true */) {
|
|
1376
|
-
validators.push(convertedRequiredValidator());
|
|
1377
|
-
}
|
|
1378
|
-
if (field.regex) {
|
|
1379
|
-
const match = /^\/(.*)\/([gim]*)$/.exec(field.regex);
|
|
1380
|
-
if (match) {
|
|
1381
|
-
const pattern = new RegExp(match[1], match[2]);
|
|
1382
|
-
const errorMessage = field.validation_error_msg
|
|
1383
|
-
? field.validation_error_msg
|
|
1384
|
-
: 'Enter valid data';
|
|
1385
|
-
validators.push(convert(Validators.pattern(pattern), errorMessage));
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
return validators;
|
|
1445
|
+
async getHash() {
|
|
1446
|
+
return this.hash;
|
|
1389
1447
|
}
|
|
1390
|
-
|
|
1391
|
-
|
|
1448
|
+
async loadAntifraudFingerprintLibrary() {
|
|
1449
|
+
const library = await import('@xsolla/antifraud-fingerprint');
|
|
1450
|
+
return library.AntifraudFingerprint;
|
|
1392
1451
|
}
|
|
1393
|
-
|
|
1394
|
-
const
|
|
1395
|
-
|
|
1396
|
-
return config;
|
|
1452
|
+
async buildHash() {
|
|
1453
|
+
const hash = await this.generate();
|
|
1454
|
+
return JSON.stringify(hash);
|
|
1397
1455
|
}
|
|
1398
|
-
|
|
1399
|
-
|
|
1456
|
+
async generate() {
|
|
1457
|
+
const fingerprint = await this.makeAntifraudFingerprint();
|
|
1458
|
+
if (!fingerprint) {
|
|
1459
|
+
return null;
|
|
1460
|
+
}
|
|
1461
|
+
await fingerprint.dispatch().catch((err) => console.log(err));
|
|
1462
|
+
const afsHash = await fingerprint.hash();
|
|
1463
|
+
return { '301': afsHash };
|
|
1400
1464
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1465
|
+
async makeAntifraudFingerprint() {
|
|
1466
|
+
if (!this.settingsService.token) {
|
|
1467
|
+
return null;
|
|
1468
|
+
}
|
|
1469
|
+
const antifraudFingerprint = await this
|
|
1470
|
+
.antifraudFingerprintLibrary;
|
|
1471
|
+
try {
|
|
1472
|
+
return new antifraudFingerprint({
|
|
1473
|
+
api: {
|
|
1474
|
+
url: 'https://afs.xsolla.com/dfp/api/v1/',
|
|
1475
|
+
token: this.settingsService.token,
|
|
1476
|
+
timeout: 3000,
|
|
1477
|
+
},
|
|
1478
|
+
retry: {
|
|
1479
|
+
num: 1,
|
|
1480
|
+
timeout: 500,
|
|
1481
|
+
},
|
|
1482
|
+
});
|
|
1483
|
+
}
|
|
1484
|
+
catch (error) {
|
|
1485
|
+
return null;
|
|
1486
|
+
}
|
|
1403
1487
|
}
|
|
1404
|
-
|
|
1405
|
-
|
|
1488
|
+
}
|
|
1489
|
+
DeviceFingerPrintService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, deps: [{ token: SettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1490
|
+
DeviceFingerPrintService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, providedIn: 'root' });
|
|
1491
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, decorators: [{
|
|
1492
|
+
type: Injectable,
|
|
1493
|
+
args: [{
|
|
1494
|
+
providedIn: 'root',
|
|
1495
|
+
}]
|
|
1496
|
+
}], ctorParameters: function () { return [{ type: SettingsService }]; } });
|
|
1497
|
+
|
|
1498
|
+
class SubmitService {
|
|
1499
|
+
constructor(requestFactory, responseFactory, settingsService, deviceFingerPrintService, xpsApiService, encryptCreditCardService) {
|
|
1500
|
+
this.requestFactory = requestFactory;
|
|
1501
|
+
this.responseFactory = responseFactory;
|
|
1502
|
+
this.settingsService = settingsService;
|
|
1503
|
+
this.deviceFingerPrintService = deviceFingerPrintService;
|
|
1504
|
+
this.xpsApiService = xpsApiService;
|
|
1505
|
+
this.encryptCreditCardService = encryptCreditCardService;
|
|
1406
1506
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1507
|
+
// NB: Never add 'async' statement for this method!
|
|
1508
|
+
// 'Async' statement wraps current promise into another.
|
|
1509
|
+
// In this way two promises become unequal, that can broke XPS API requests logic.
|
|
1510
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
1511
|
+
request(fields, form) {
|
|
1512
|
+
return (this.deviceFingerPrintService
|
|
1513
|
+
.getHash()
|
|
1514
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
1515
|
+
.then((dfpHash) => {
|
|
1516
|
+
const requestParams = this.requestFactory({
|
|
1517
|
+
token: this.settingsService.token,
|
|
1518
|
+
fields,
|
|
1519
|
+
form,
|
|
1520
|
+
dfpHash,
|
|
1521
|
+
});
|
|
1522
|
+
const encryptedRequest = this.encryptCreditCardService.encryptCreditCard(requestParams);
|
|
1523
|
+
return this.xpsApiService
|
|
1524
|
+
.directPaymentRequest(encryptedRequest)
|
|
1525
|
+
.then((response) => this.responseFactory(response))
|
|
1526
|
+
.catch((error) => {
|
|
1527
|
+
throw new ResponseError(error.message);
|
|
1528
|
+
});
|
|
1529
|
+
}));
|
|
1409
1530
|
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1531
|
+
}
|
|
1532
|
+
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 });
|
|
1533
|
+
SubmitService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, providedIn: 'root' });
|
|
1534
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, decorators: [{
|
|
1535
|
+
type: Injectable,
|
|
1536
|
+
args: [{ providedIn: 'root' }]
|
|
1537
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
1538
|
+
type: Inject,
|
|
1539
|
+
args: [submitRequestFactoryToken]
|
|
1540
|
+
}] }, { type: undefined, decorators: [{
|
|
1541
|
+
type: Inject,
|
|
1542
|
+
args: [submitResponseFactoryToken]
|
|
1543
|
+
}] }, { type: SettingsService }, { type: DeviceFingerPrintService }, { type: XpsApiService }, { type: EncryptCreditCardService }]; } });
|
|
1544
|
+
|
|
1545
|
+
class EmitDataService {
|
|
1546
|
+
constructor() {
|
|
1547
|
+
this.dataSubject = new Subject();
|
|
1548
|
+
this.data$ = this.dataSubject.asObservable();
|
|
1420
1549
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
Object.keys(commonControlConfig).forEach((sourceKey) => {
|
|
1424
|
-
if (!(sourceKey in target)) {
|
|
1425
|
-
target[sourceKey] = commonControlConfig[sourceKey];
|
|
1426
|
-
}
|
|
1427
|
-
});
|
|
1550
|
+
emit(data) {
|
|
1551
|
+
this.dataSubject.next(data);
|
|
1428
1552
|
}
|
|
1429
1553
|
}
|
|
1430
1554
|
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1555
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
1556
|
+
class SyncRequest extends XpsApiPartRequest {
|
|
1557
|
+
constructor(parameters) {
|
|
1558
|
+
super();
|
|
1559
|
+
this.xps_fix_command = 'calculate';
|
|
1560
|
+
this.access_token = parameters.token;
|
|
1561
|
+
const fieldsValues = this.getFieldsValues(parameters.changedField, parameters.fields, parameters.form);
|
|
1562
|
+
this.addXpsParameters({
|
|
1563
|
+
...fieldsValues,
|
|
1564
|
+
change_element: parameters.changedField.name,
|
|
1565
|
+
});
|
|
1437
1566
|
}
|
|
1438
|
-
|
|
1439
|
-
const
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1567
|
+
getFieldsValues(changedField, fields, form) {
|
|
1568
|
+
const fieldsMap = this.getFieldsMap(fields);
|
|
1569
|
+
return changedField?.javascript?.change.params.reduce((xpsParams, fieldName) => {
|
|
1570
|
+
const formControl = form.get(fieldName);
|
|
1571
|
+
const field = fieldsMap.get(fieldName);
|
|
1572
|
+
if (formControl || field) {
|
|
1573
|
+
xpsParams[fieldName] = formControl?.value ?? field?.value;
|
|
1574
|
+
}
|
|
1575
|
+
return xpsParams;
|
|
1576
|
+
}, {});
|
|
1443
1577
|
}
|
|
1444
|
-
|
|
1445
|
-
|
|
1578
|
+
getFieldsMap(fields) {
|
|
1579
|
+
const map = new Map();
|
|
1580
|
+
fields.forEach((field) => map.set(field.name, field));
|
|
1581
|
+
return map;
|
|
1446
1582
|
}
|
|
1447
1583
|
}
|
|
1448
|
-
EmailConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1449
|
-
EmailConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter });
|
|
1450
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter, decorators: [{
|
|
1451
|
-
type: Injectable
|
|
1452
|
-
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
1453
1584
|
|
|
1454
|
-
const
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1585
|
+
const syncRequestFactoryToken = new InjectionToken('SyncRequest');
|
|
1586
|
+
const syncRequestFactoryProvider = {
|
|
1587
|
+
provide: syncRequestFactoryToken,
|
|
1588
|
+
useValue: (...args) => new SyncRequest(...args),
|
|
1458
1589
|
};
|
|
1459
1590
|
|
|
1460
|
-
class
|
|
1461
|
-
constructor(
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1591
|
+
class SyncResponse {
|
|
1592
|
+
constructor(changedField, response) {
|
|
1593
|
+
this.error = null;
|
|
1594
|
+
const fieldError = response?.errors?.find((error) => error.element_name === changedField.name);
|
|
1595
|
+
if (fieldError) {
|
|
1596
|
+
this.error = {
|
|
1597
|
+
asyncError: {
|
|
1598
|
+
code: fieldError.code,
|
|
1599
|
+
message: fieldError.message,
|
|
1600
|
+
},
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1603
|
+
this.fields = Object.keys(response.form).map((key) => response.form[key]);
|
|
1604
|
+
this.parameters = response;
|
|
1470
1605
|
}
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
const syncResponseFactoryToken = new InjectionToken('SyncResponse');
|
|
1609
|
+
const syncResponseFactoryProvider = {
|
|
1610
|
+
provide: syncResponseFactoryToken,
|
|
1611
|
+
useValue: (...args) => new SyncResponse(...args),
|
|
1612
|
+
};
|
|
1613
|
+
|
|
1614
|
+
class SyncService extends EmitDataService {
|
|
1615
|
+
constructor(requestFactory, responseFactory, xpsApiService, nextActionService, settingsService, encryptCreditCardService) {
|
|
1616
|
+
super();
|
|
1617
|
+
this.requestFactory = requestFactory;
|
|
1618
|
+
this.responseFactory = responseFactory;
|
|
1619
|
+
this.xpsApiService = xpsApiService;
|
|
1620
|
+
this.nextActionService = nextActionService;
|
|
1621
|
+
this.settingsService = settingsService;
|
|
1622
|
+
this.encryptCreditCardService = encryptCreditCardService;
|
|
1623
|
+
this.prevFieldSyncStates = {};
|
|
1624
|
+
this.form = new UntypedFormGroup({});
|
|
1625
|
+
this.fields = [];
|
|
1626
|
+
this.fieldAsyncValidation = new Subject();
|
|
1484
1627
|
}
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1628
|
+
get fieldAsyncValidation$() {
|
|
1629
|
+
return this.fieldAsyncValidation.asObservable();
|
|
1630
|
+
}
|
|
1631
|
+
setup(form, fields) {
|
|
1632
|
+
this.reset();
|
|
1633
|
+
this.form = form;
|
|
1634
|
+
this.fields = fields;
|
|
1635
|
+
}
|
|
1636
|
+
reset() {
|
|
1637
|
+
this.prevFieldSyncStates = {};
|
|
1638
|
+
this.form = new UntypedFormGroup({});
|
|
1639
|
+
this.fields = [];
|
|
1640
|
+
}
|
|
1641
|
+
async validate(field) {
|
|
1642
|
+
if (!this.isReadyField(field)) {
|
|
1643
|
+
return Promise.resolve(null);
|
|
1498
1644
|
}
|
|
1499
|
-
|
|
1500
|
-
|
|
1645
|
+
const control = this.form.get(field.name);
|
|
1646
|
+
const value = control?.value;
|
|
1647
|
+
const prevFieldState = this.getPrevFieldSyncState(field);
|
|
1648
|
+
const isInitialValue = value === field.value && !prevFieldState;
|
|
1649
|
+
if (isInitialValue) {
|
|
1650
|
+
return Promise.resolve(null);
|
|
1501
1651
|
}
|
|
1502
|
-
|
|
1652
|
+
if (prevFieldState && value === prevFieldState.value) {
|
|
1653
|
+
return Promise.resolve(prevFieldState.result).then((response) => {
|
|
1654
|
+
return response?.error ?? null;
|
|
1655
|
+
});
|
|
1656
|
+
}
|
|
1657
|
+
const requestPromise = this.request(field);
|
|
1658
|
+
this.setPrevFieldSyncState(field, value, requestPromise);
|
|
1659
|
+
return requestPromise.then((response) => {
|
|
1660
|
+
this.fieldAsyncValidation.next({
|
|
1661
|
+
value,
|
|
1662
|
+
field,
|
|
1663
|
+
response,
|
|
1664
|
+
});
|
|
1665
|
+
return response.error ?? null;
|
|
1666
|
+
});
|
|
1503
1667
|
}
|
|
1504
|
-
|
|
1505
|
-
|
|
1668
|
+
getSyncValidationErrors(field) {
|
|
1669
|
+
const control = this.form.get(field.name);
|
|
1670
|
+
return control?.errors ?? null;
|
|
1506
1671
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1672
|
+
async request(field) {
|
|
1673
|
+
const requestParams = this.requestFactory({
|
|
1674
|
+
token: this.settingsService.token,
|
|
1675
|
+
changedField: field,
|
|
1676
|
+
fields: this.fields,
|
|
1677
|
+
form: this.form,
|
|
1678
|
+
});
|
|
1679
|
+
const encryptedRequest = this.encryptCreditCardService.encryptCreditCard(requestParams);
|
|
1680
|
+
return this.xpsApiService
|
|
1681
|
+
.directPaymentRequest(encryptedRequest)
|
|
1682
|
+
.then((response) => {
|
|
1683
|
+
if (response.errors?.length) {
|
|
1684
|
+
this.nextActionService.emitFlowUpdates(new ShowErrorsAction(response.errors));
|
|
1685
|
+
}
|
|
1686
|
+
this.emit(response);
|
|
1687
|
+
return this.responseFactory(field, response);
|
|
1688
|
+
});
|
|
1509
1689
|
}
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
type: Injectable
|
|
1515
|
-
}], ctorParameters: function () { return [{ type: SyncService }, { type: CountryService }]; } });
|
|
1516
|
-
|
|
1517
|
-
function isEmptyInputValue(value) {
|
|
1518
|
-
return value == null || value.length === 0;
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
|
-
function isString(value) {
|
|
1522
|
-
return typeof value === 'string';
|
|
1523
|
-
}
|
|
1524
|
-
|
|
1525
|
-
/**
|
|
1526
|
-
* Checks number match Luhn algorithm.
|
|
1527
|
-
* Based on http://en.wikipedia.org/wiki/Luhn.
|
|
1528
|
-
*/
|
|
1529
|
-
const luhnFormulaValidator = ({ value }) => {
|
|
1530
|
-
if (isEmptyInputValue(value) || !isString(value)) {
|
|
1531
|
-
return null;
|
|
1690
|
+
isReadyField(field) {
|
|
1691
|
+
const isSyncEnabled = !!field.javascript?.change;
|
|
1692
|
+
const isExistsInForm = !!this.form?.get(field.name);
|
|
1693
|
+
return isSyncEnabled && isExistsInForm;
|
|
1532
1694
|
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
message: `Enter a valid card number`,
|
|
1536
|
-
},
|
|
1537
|
-
};
|
|
1538
|
-
if (/[^0-9 -]+/.test(value)) {
|
|
1539
|
-
// accept only spaces, digits and dashes
|
|
1540
|
-
return error;
|
|
1695
|
+
getPrevFieldSyncState(field) {
|
|
1696
|
+
return this.prevFieldSyncStates[field.name];
|
|
1541
1697
|
}
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
let isEven = false;
|
|
1545
|
-
const modBase = 10;
|
|
1546
|
-
const digitRadix = 10;
|
|
1547
|
-
const maxNumber = 9;
|
|
1548
|
-
const digits = value.replace(/\D/g, '');
|
|
1549
|
-
// Checks if number match Luhn algorithm
|
|
1550
|
-
// based on http://en.wikipedia.org/wiki/Luhn
|
|
1551
|
-
for (let index = digits.length - 1; index >= 0; index--) {
|
|
1552
|
-
const char = digits.charAt(index);
|
|
1553
|
-
digit = parseInt(char, digitRadix);
|
|
1554
|
-
if (isEven && (digit *= 2) > maxNumber) {
|
|
1555
|
-
digit -= maxNumber;
|
|
1556
|
-
}
|
|
1557
|
-
resultSum += digit;
|
|
1558
|
-
isEven = !isEven;
|
|
1698
|
+
setPrevFieldSyncState(field, value, result) {
|
|
1699
|
+
this.prevFieldSyncStates[field.name] = { value, result };
|
|
1559
1700
|
}
|
|
1560
|
-
|
|
1561
|
-
};
|
|
1701
|
+
}
|
|
1702
|
+
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 });
|
|
1703
|
+
SyncService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, providedIn: 'root' });
|
|
1704
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, decorators: [{
|
|
1705
|
+
type: Injectable,
|
|
1706
|
+
args: [{
|
|
1707
|
+
providedIn: 'root',
|
|
1708
|
+
}]
|
|
1709
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
1710
|
+
type: Inject,
|
|
1711
|
+
args: [syncRequestFactoryToken]
|
|
1712
|
+
}] }, { type: undefined, decorators: [{
|
|
1713
|
+
type: Inject,
|
|
1714
|
+
args: [syncResponseFactoryToken]
|
|
1715
|
+
}] }, { type: XpsApiService }, { type: NextActionService }, { type: SettingsService }, { type: EncryptCreditCardService }]; } });
|
|
1562
1716
|
|
|
1563
|
-
class
|
|
1717
|
+
class ControlConfig {
|
|
1564
1718
|
constructor() {
|
|
1565
|
-
|
|
1566
|
-
this.controlType = 'card-number';
|
|
1567
|
-
this.availableCardTypes = [];
|
|
1568
|
-
this.customError = '';
|
|
1719
|
+
this.shouldHideUserInput = false;
|
|
1569
1720
|
}
|
|
1570
1721
|
}
|
|
1571
1722
|
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
CreditCardTypes["MASTERCARD"] = "2";
|
|
1579
|
-
CreditCardTypes["MAESTRO"] = "3";
|
|
1580
|
-
CreditCardTypes["AMERICAN_EXPRESS"] = "4";
|
|
1581
|
-
CreditCardTypes["DINERS_CLUBS"] = "5";
|
|
1582
|
-
CreditCardTypes["DISCOVER"] = "6";
|
|
1583
|
-
CreditCardTypes["JCB"] = "9";
|
|
1584
|
-
CreditCardTypes["DANKORT"] = "11";
|
|
1585
|
-
CreditCardTypes["HIPERCARD"] = "12";
|
|
1586
|
-
CreditCardTypes["ELO"] = "13";
|
|
1587
|
-
CreditCardTypes["AURA"] = "14";
|
|
1588
|
-
CreditCardTypes["NARANJA"] = "15";
|
|
1589
|
-
CreditCardTypes["MIR"] = "16";
|
|
1590
|
-
CreditCardTypes["CHINA_UNION_PAY"] = "17";
|
|
1591
|
-
CreditCardTypes["POSTEPAY"] = "18";
|
|
1592
|
-
})(CreditCardTypes || (CreditCardTypes = {}));
|
|
1723
|
+
class TextControlConfig extends ControlConfig {
|
|
1724
|
+
constructor() {
|
|
1725
|
+
super(...arguments);
|
|
1726
|
+
this.controlType = 'text';
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1593
1729
|
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1730
|
+
function convert(validator, message) {
|
|
1731
|
+
return (control) => {
|
|
1732
|
+
const errors = validator(control);
|
|
1733
|
+
if (!errors) {
|
|
1734
|
+
return errors;
|
|
1735
|
+
}
|
|
1736
|
+
const firstErrorKey = Object.keys(errors)[0];
|
|
1737
|
+
const firstError = errors[firstErrorKey];
|
|
1738
|
+
const error = typeof firstError === 'object' && firstError !== null ? firstError : {};
|
|
1739
|
+
error.message = message;
|
|
1740
|
+
errors[firstErrorKey] = error;
|
|
1741
|
+
return errors;
|
|
1742
|
+
};
|
|
1743
|
+
}
|
|
1604
1744
|
|
|
1605
|
-
const
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
iconName: 'mastercard',
|
|
1610
|
-
mask: fourBlockMask,
|
|
1611
|
-
checkNumber(number) {
|
|
1612
|
-
const subLength = 6;
|
|
1613
|
-
const cardNumberSub = number.substring(0, subLength);
|
|
1614
|
-
return (new RegExp(/^5[1-5]/).test(number) ||
|
|
1615
|
-
(cardNumberSub >= '222100' && cardNumberSub <= '272099'));
|
|
1616
|
-
},
|
|
1617
|
-
};
|
|
1745
|
+
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
|
|
1746
|
+
function convertedEmailValidator() {
|
|
1747
|
+
return convert(Validators.pattern(emailRegexp), 'Enter a valid email');
|
|
1748
|
+
}
|
|
1618
1749
|
|
|
1619
|
-
|
|
1750
|
+
function convertedRequiredValidator() {
|
|
1751
|
+
return convert(Validators.required, 'Required');
|
|
1752
|
+
}
|
|
1620
1753
|
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
}
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
return
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
return
|
|
1665
|
-
}
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
minLength: 15,
|
|
1671
|
-
maxLength: 16,
|
|
1672
|
-
iconName: 'jcb',
|
|
1673
|
-
mask: fourBlockMask,
|
|
1674
|
-
checkNumber(number) {
|
|
1675
|
-
return new RegExp(/^35(2[89]|[3-8][0-9])/).test(number);
|
|
1676
|
-
},
|
|
1677
|
-
};
|
|
1678
|
-
|
|
1679
|
-
const dankort = {
|
|
1680
|
-
id: CreditCardTypes.DANKORT,
|
|
1681
|
-
minLength: 16,
|
|
1682
|
-
maxLength: 16,
|
|
1683
|
-
iconName: 'dankort',
|
|
1684
|
-
mask: fourBlockMask,
|
|
1685
|
-
checkNumber(number) {
|
|
1686
|
-
const subLength = 4;
|
|
1687
|
-
const cardNumberSub = number.substring(0, subLength);
|
|
1688
|
-
return cardNumberSub === '5019';
|
|
1689
|
-
},
|
|
1690
|
-
};
|
|
1691
|
-
|
|
1692
|
-
const hipercard = {
|
|
1693
|
-
id: CreditCardTypes.HIPERCARD,
|
|
1694
|
-
minLength: 13,
|
|
1695
|
-
maxLength: 19,
|
|
1696
|
-
iconName: 'hipercard',
|
|
1697
|
-
mask: defaultMask,
|
|
1698
|
-
checkNumber(number) {
|
|
1699
|
-
return new RegExp(/^((606282|637095|637568)[0-9]|38[0-9]{14,17})/).test(number);
|
|
1700
|
-
},
|
|
1701
|
-
};
|
|
1702
|
-
|
|
1703
|
-
const elo = {
|
|
1704
|
-
id: CreditCardTypes.ELO,
|
|
1705
|
-
minLength: 16,
|
|
1706
|
-
maxLength: 19,
|
|
1707
|
-
iconName: 'elo',
|
|
1708
|
-
mask: defaultMask,
|
|
1709
|
-
checkNumber(number) {
|
|
1710
|
-
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);
|
|
1711
|
-
},
|
|
1712
|
-
};
|
|
1713
|
-
|
|
1714
|
-
const aura = {
|
|
1715
|
-
id: CreditCardTypes.AURA,
|
|
1716
|
-
minLength: 16,
|
|
1717
|
-
maxLength: 19,
|
|
1718
|
-
iconName: 'aura',
|
|
1719
|
-
mask: defaultMask,
|
|
1720
|
-
checkNumber(number) {
|
|
1721
|
-
const subLength = 8;
|
|
1722
|
-
const cardNumberSub = number.substring(0, subLength);
|
|
1723
|
-
return ['50786000', '50786018', '50786019'].includes(cardNumberSub);
|
|
1724
|
-
},
|
|
1725
|
-
};
|
|
1726
|
-
|
|
1727
|
-
const naranja = {
|
|
1728
|
-
id: CreditCardTypes.NARANJA,
|
|
1729
|
-
minLength: 12,
|
|
1730
|
-
maxLength: 19,
|
|
1731
|
-
iconName: 'naranja',
|
|
1732
|
-
mask: defaultMask,
|
|
1733
|
-
checkNumber(number) {
|
|
1734
|
-
const subLength = 6;
|
|
1735
|
-
const cardNumberSub = number.substring(0, subLength);
|
|
1736
|
-
return cardNumberSub === '589562';
|
|
1737
|
-
},
|
|
1738
|
-
};
|
|
1739
|
-
|
|
1740
|
-
const mir = {
|
|
1741
|
-
id: CreditCardTypes.MIR,
|
|
1742
|
-
minLength: 16,
|
|
1743
|
-
maxLength: 16,
|
|
1744
|
-
iconName: 'mir',
|
|
1745
|
-
mask: defaultMask,
|
|
1746
|
-
checkNumber(number) {
|
|
1747
|
-
const subLength = 4;
|
|
1748
|
-
const cardNumberSub = number.substring(0, subLength);
|
|
1749
|
-
return cardNumberSub >= '2200' && cardNumberSub <= '2204';
|
|
1750
|
-
},
|
|
1751
|
-
};
|
|
1752
|
-
|
|
1753
|
-
const chinaUnionPay = {
|
|
1754
|
-
id: CreditCardTypes.CHINA_UNION_PAY,
|
|
1755
|
-
minLength: 16,
|
|
1756
|
-
maxLength: 19,
|
|
1757
|
-
iconName: 'unionpay',
|
|
1758
|
-
mask: '999 9999 9999 99999999',
|
|
1759
|
-
checkNumber(number) {
|
|
1760
|
-
return number.startsWith('62');
|
|
1761
|
-
},
|
|
1762
|
-
};
|
|
1763
|
-
|
|
1764
|
-
const defaultCard = {
|
|
1765
|
-
id: CreditCardTypes.DEFAULT,
|
|
1766
|
-
minLength: 12,
|
|
1767
|
-
maxLength: 19,
|
|
1768
|
-
iconName: null,
|
|
1769
|
-
mask: defaultMask,
|
|
1770
|
-
checkNumber() {
|
|
1754
|
+
class Converter {
|
|
1755
|
+
constructor(syncService) {
|
|
1756
|
+
this.syncService = syncService;
|
|
1757
|
+
}
|
|
1758
|
+
convertToConfig(field, formState) {
|
|
1759
|
+
const config = this.createControlConfig(field, formState);
|
|
1760
|
+
if (formState?.disabled) {
|
|
1761
|
+
config.disabled = true;
|
|
1762
|
+
}
|
|
1763
|
+
return config;
|
|
1764
|
+
}
|
|
1765
|
+
convertToFormControl(field) {
|
|
1766
|
+
return new UntypedFormControl(this.getValue(field), this.getValidators(field), this.getAsyncValidators(field));
|
|
1767
|
+
}
|
|
1768
|
+
getValidators(field) {
|
|
1769
|
+
const validators = [];
|
|
1770
|
+
if (field.isMandatory === "1" /* XpsBoolean.true */) {
|
|
1771
|
+
validators.push(convertedRequiredValidator());
|
|
1772
|
+
}
|
|
1773
|
+
if (field.regex) {
|
|
1774
|
+
const match = /^\/(.*)\/([gim]*)$/.exec(field.regex);
|
|
1775
|
+
if (match) {
|
|
1776
|
+
const pattern = new RegExp(match[1], match[2]);
|
|
1777
|
+
const errorMessage = field.validation_error_msg
|
|
1778
|
+
? field.validation_error_msg
|
|
1779
|
+
: 'Enter valid data';
|
|
1780
|
+
validators.push(convert(Validators.pattern(pattern), errorMessage));
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
return validators;
|
|
1784
|
+
}
|
|
1785
|
+
getAsyncValidators(field) {
|
|
1786
|
+
return async () => this.syncService.validate(field);
|
|
1787
|
+
}
|
|
1788
|
+
createDefaultControlConfig(controlConfigClass, field) {
|
|
1789
|
+
const config = new controlConfigClass();
|
|
1790
|
+
this.copyCommonOptions(config, field);
|
|
1791
|
+
return config;
|
|
1792
|
+
}
|
|
1793
|
+
getValue(field) {
|
|
1794
|
+
return field.value;
|
|
1795
|
+
}
|
|
1796
|
+
getDataType() {
|
|
1797
|
+
return 'text';
|
|
1798
|
+
}
|
|
1799
|
+
getAutocomplete() {
|
|
1800
|
+
return 'off';
|
|
1801
|
+
}
|
|
1802
|
+
shouldHideUserInput() {
|
|
1771
1803
|
return false;
|
|
1772
|
-
}
|
|
1773
|
-
|
|
1804
|
+
}
|
|
1805
|
+
getCommonControlConfig(field) {
|
|
1806
|
+
return {
|
|
1807
|
+
name: field.name,
|
|
1808
|
+
title: field.title,
|
|
1809
|
+
labelHint: field.label_hint,
|
|
1810
|
+
dataType: this.getDataType(),
|
|
1811
|
+
readonly: field.isReadonly === "1" /* XpsBoolean.true */,
|
|
1812
|
+
placeholder: field.example,
|
|
1813
|
+
autocomplete: this.getAutocomplete(),
|
|
1814
|
+
};
|
|
1815
|
+
}
|
|
1816
|
+
copyCommonOptions(target, field) {
|
|
1817
|
+
const commonControlConfig = this.getCommonControlConfig(field);
|
|
1818
|
+
Object.keys(commonControlConfig).forEach((sourceKey) => {
|
|
1819
|
+
if (!(sourceKey in target)) {
|
|
1820
|
+
target[sourceKey] = commonControlConfig[sourceKey];
|
|
1821
|
+
}
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1774
1825
|
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1826
|
+
class EmailConverter extends Converter {
|
|
1827
|
+
constructor(syncService) {
|
|
1828
|
+
super(syncService);
|
|
1829
|
+
}
|
|
1830
|
+
getValidators(field) {
|
|
1831
|
+
return super.getValidators(field).concat([convertedEmailValidator()]);
|
|
1832
|
+
}
|
|
1833
|
+
createControlConfig(field) {
|
|
1834
|
+
const config = this.createDefaultControlConfig(TextControlConfig, field);
|
|
1835
|
+
config.autocomplete = 'email';
|
|
1836
|
+
config.icon = 'mail';
|
|
1837
|
+
return config;
|
|
1838
|
+
}
|
|
1839
|
+
getDataType() {
|
|
1840
|
+
return 'email';
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
EmailConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1844
|
+
EmailConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter });
|
|
1845
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter, decorators: [{
|
|
1846
|
+
type: Injectable
|
|
1847
|
+
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
1848
|
+
|
|
1849
|
+
const restrictedValueValidator = (restrictedValue) => {
|
|
1850
|
+
return ({ value }) => {
|
|
1851
|
+
return value !== restrictedValue ? null : { valueAllowed: false };
|
|
1852
|
+
};
|
|
1785
1853
|
};
|
|
1786
1854
|
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1855
|
+
class ZipConverter extends Converter {
|
|
1856
|
+
constructor(syncService, countryService) {
|
|
1857
|
+
super(syncService);
|
|
1858
|
+
this.countryService = countryService;
|
|
1859
|
+
this.minLength = 3;
|
|
1860
|
+
this.maxLength = 10;
|
|
1861
|
+
this.usCountryLength = 5;
|
|
1862
|
+
}
|
|
1863
|
+
get isUsCountry() {
|
|
1864
|
+
return this.countryService.getCountry() === 'US';
|
|
1865
|
+
}
|
|
1866
|
+
getValidators(field) {
|
|
1867
|
+
const minLength = this.isUsCountry ? this.usCountryLength : this.minLength;
|
|
1868
|
+
const maxLength = this.isUsCountry ? this.usCountryLength : this.maxLength;
|
|
1869
|
+
const validators = super
|
|
1870
|
+
.getValidators(field)
|
|
1871
|
+
.concat([
|
|
1872
|
+
convert(Validators.minLength(minLength), `Enter at least ${minLength} characters`),
|
|
1873
|
+
convert(Validators.maxLength(maxLength), `Enter no more than ${maxLength} characters`),
|
|
1874
|
+
]);
|
|
1875
|
+
if (this.isUsCountry) {
|
|
1876
|
+
validators.push(convert(restrictedValueValidator('00000'), 'Enter a valid ZIP code'));
|
|
1877
|
+
}
|
|
1878
|
+
return validators;
|
|
1879
|
+
}
|
|
1880
|
+
createControlConfig(field) {
|
|
1881
|
+
const config = this.createDefaultControlConfig(TextControlConfig, field);
|
|
1882
|
+
config.icon = 'location';
|
|
1883
|
+
if (this.isUsCountry) {
|
|
1884
|
+
config.maskConfig = {
|
|
1885
|
+
guide: false,
|
|
1886
|
+
unmaskModelValue: true,
|
|
1887
|
+
showMask: true,
|
|
1888
|
+
};
|
|
1889
|
+
config.inputMode = 'numeric';
|
|
1890
|
+
if (masksFunctionsMap['zip']) {
|
|
1891
|
+
config.maskConfig.mask = masksFunctionsMap['zip'];
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
else {
|
|
1895
|
+
config.maxLength = this.maxLength;
|
|
1896
|
+
}
|
|
1897
|
+
return config;
|
|
1898
|
+
}
|
|
1899
|
+
getAutocomplete() {
|
|
1900
|
+
return 'postal-code';
|
|
1901
|
+
}
|
|
1902
|
+
getDataType() {
|
|
1903
|
+
return 'text';
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
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 });
|
|
1907
|
+
ZipConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ZipConverter });
|
|
1908
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ZipConverter, decorators: [{
|
|
1909
|
+
type: Injectable
|
|
1910
|
+
}], ctorParameters: function () { return [{ type: SyncService }, { type: CountryService }]; } });
|
|
1815
1911
|
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
[CreditCardTypes.MASTERCARD]: mastercard,
|
|
1820
|
-
[CreditCardTypes.MAESTRO]: maestro,
|
|
1821
|
-
[CreditCardTypes.AMERICAN_EXPRESS]: americanExpress,
|
|
1822
|
-
[CreditCardTypes.DINERS_CLUBS]: dinersClubs,
|
|
1823
|
-
[CreditCardTypes.DISCOVER]: discover,
|
|
1824
|
-
[CreditCardTypes.JCB]: jcb,
|
|
1825
|
-
[CreditCardTypes.DANKORT]: dankort,
|
|
1826
|
-
[CreditCardTypes.HIPERCARD]: hipercard,
|
|
1827
|
-
[CreditCardTypes.ELO]: elo,
|
|
1828
|
-
[CreditCardTypes.AURA]: aura,
|
|
1829
|
-
[CreditCardTypes.NARANJA]: naranja,
|
|
1830
|
-
[CreditCardTypes.MIR]: mir,
|
|
1831
|
-
[CreditCardTypes.CHINA_UNION_PAY]: chinaUnionPay,
|
|
1832
|
-
[CreditCardTypes.POSTEPAY]: postePay,
|
|
1833
|
-
};
|
|
1912
|
+
function isEmptyInputValue(value) {
|
|
1913
|
+
return value == null || value.length === 0;
|
|
1914
|
+
}
|
|
1834
1915
|
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1916
|
+
function isString(value) {
|
|
1917
|
+
return typeof value === 'string';
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
/**
|
|
1921
|
+
* Checks number match Luhn algorithm.
|
|
1922
|
+
* Based on http://en.wikipedia.org/wiki/Luhn.
|
|
1923
|
+
*/
|
|
1924
|
+
const luhnFormulaValidator = ({ value }) => {
|
|
1925
|
+
if (isEmptyInputValue(value) || !isString(value)) {
|
|
1926
|
+
return null;
|
|
1845
1927
|
}
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1928
|
+
const error = {
|
|
1929
|
+
rewritableError: {
|
|
1930
|
+
message: `Enter a valid card number`,
|
|
1931
|
+
},
|
|
1932
|
+
};
|
|
1933
|
+
if (/[^0-9 -]+/.test(value)) {
|
|
1934
|
+
// accept only spaces, digits and dashes
|
|
1935
|
+
return error;
|
|
1853
1936
|
}
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1937
|
+
let resultSum = 0;
|
|
1938
|
+
let digit = 0;
|
|
1939
|
+
let isEven = false;
|
|
1940
|
+
const modBase = 10;
|
|
1941
|
+
const digitRadix = 10;
|
|
1942
|
+
const maxNumber = 9;
|
|
1943
|
+
const digits = value.replace(/\D/g, '');
|
|
1944
|
+
// Checks if number match Luhn algorithm
|
|
1945
|
+
// based on http://en.wikipedia.org/wiki/Luhn
|
|
1946
|
+
for (let index = digits.length - 1; index >= 0; index--) {
|
|
1947
|
+
const char = digits.charAt(index);
|
|
1948
|
+
digit = parseInt(char, digitRadix);
|
|
1949
|
+
if (isEven && (digit *= 2) > maxNumber) {
|
|
1950
|
+
digit -= maxNumber;
|
|
1858
1951
|
}
|
|
1859
|
-
|
|
1952
|
+
resultSum += digit;
|
|
1953
|
+
isEven = !isEven;
|
|
1954
|
+
}
|
|
1955
|
+
return resultSum % modBase === 0 ? null : error;
|
|
1956
|
+
};
|
|
1957
|
+
|
|
1958
|
+
class CardNumberConfig extends ControlConfig {
|
|
1959
|
+
constructor() {
|
|
1960
|
+
super(...arguments);
|
|
1961
|
+
this.controlType = 'card-number';
|
|
1962
|
+
this.availableCardTypes = [];
|
|
1963
|
+
this.customError = '';
|
|
1860
1964
|
}
|
|
1861
1965
|
}
|
|
1862
|
-
CreditCardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1863
|
-
CreditCardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, providedIn: 'root' });
|
|
1864
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardService, decorators: [{
|
|
1865
|
-
type: Injectable,
|
|
1866
|
-
args: [{
|
|
1867
|
-
providedIn: 'root',
|
|
1868
|
-
}]
|
|
1869
|
-
}] });
|
|
1870
1966
|
|
|
1871
1967
|
class CreditCardMinLengthValidator {
|
|
1872
1968
|
constructor(creditService) {
|
|
@@ -1889,55 +1985,363 @@ class CreditCardMinLengthValidator {
|
|
|
1889
1985
|
};
|
|
1890
1986
|
}
|
|
1891
1987
|
}
|
|
1892
|
-
CreditCardMinLengthValidator.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator, deps: [{ token: CreditCardService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1893
|
-
CreditCardMinLengthValidator.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator });
|
|
1894
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator, decorators: [{
|
|
1988
|
+
CreditCardMinLengthValidator.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator, deps: [{ token: CreditCardService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1989
|
+
CreditCardMinLengthValidator.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator });
|
|
1990
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CreditCardMinLengthValidator, decorators: [{
|
|
1991
|
+
type: Injectable
|
|
1992
|
+
}], ctorParameters: function () { return [{ type: CreditCardService }]; } });
|
|
1993
|
+
|
|
1994
|
+
class CardNumberConverter extends Converter {
|
|
1995
|
+
constructor(syncService, maxLengthValidator, minLengthValidator) {
|
|
1996
|
+
super(syncService);
|
|
1997
|
+
this.maxLengthValidator = maxLengthValidator;
|
|
1998
|
+
this.minLengthValidator = minLengthValidator;
|
|
1999
|
+
}
|
|
2000
|
+
getValidators(field) {
|
|
2001
|
+
return super
|
|
2002
|
+
.getValidators(field)
|
|
2003
|
+
.concat([
|
|
2004
|
+
luhnFormulaValidator,
|
|
2005
|
+
this.minLengthValidator.validate,
|
|
2006
|
+
this.maxLengthValidator.validate,
|
|
2007
|
+
]);
|
|
2008
|
+
}
|
|
2009
|
+
createControlConfig(field, formState) {
|
|
2010
|
+
const config = this.createDefaultControlConfig(CardNumberConfig, field);
|
|
2011
|
+
config.placeholder = config.title;
|
|
2012
|
+
config.availableCardTypes =
|
|
2013
|
+
formState?.availableCardTypes ?? [];
|
|
2014
|
+
config.activeCardType = formState?.activeCardType;
|
|
2015
|
+
config.customError = formState?.customError;
|
|
2016
|
+
config.disabled = formState?.disabled ?? false;
|
|
2017
|
+
return config;
|
|
2018
|
+
}
|
|
2019
|
+
getAutocomplete() {
|
|
2020
|
+
return 'cc-number';
|
|
2021
|
+
}
|
|
2022
|
+
getDataType() {
|
|
2023
|
+
return 'text';
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
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 });
|
|
2027
|
+
CardNumberConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardNumberConverter });
|
|
2028
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardNumberConverter, decorators: [{
|
|
2029
|
+
type: Injectable
|
|
2030
|
+
}], ctorParameters: function () { return [{ type: SyncService }, { type: CreditCardMinLengthValidator }, { type: CreditCardMinLengthValidator }]; } });
|
|
2031
|
+
|
|
2032
|
+
class CardExpirationConverter extends Converter {
|
|
2033
|
+
constructor(syncService) {
|
|
2034
|
+
super(syncService);
|
|
2035
|
+
}
|
|
2036
|
+
getValidators() {
|
|
2037
|
+
return [];
|
|
2038
|
+
}
|
|
2039
|
+
createControlConfig(field, formState) {
|
|
2040
|
+
const config = this.createDefaultControlConfig(TextControlConfig, field);
|
|
2041
|
+
config.maskConfig = {
|
|
2042
|
+
mask: '99',
|
|
2043
|
+
guide: false,
|
|
2044
|
+
};
|
|
2045
|
+
config.inputMode = 'numeric';
|
|
2046
|
+
config.title = 'date';
|
|
2047
|
+
config.disabled = formState?.disabled ?? false;
|
|
2048
|
+
return config;
|
|
2049
|
+
}
|
|
2050
|
+
getAutocomplete() {
|
|
2051
|
+
return 'cc-exp';
|
|
2052
|
+
}
|
|
2053
|
+
getDataType() {
|
|
2054
|
+
return 'text';
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
CardExpirationConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardExpirationConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2058
|
+
CardExpirationConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardExpirationConverter });
|
|
2059
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardExpirationConverter, decorators: [{
|
|
2060
|
+
type: Injectable
|
|
2061
|
+
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
2062
|
+
|
|
2063
|
+
class CvvConverter extends Converter {
|
|
2064
|
+
constructor(syncService) {
|
|
2065
|
+
super(syncService);
|
|
2066
|
+
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
2067
|
+
this.maxFieldLength = 4;
|
|
2068
|
+
}
|
|
2069
|
+
getValidators() {
|
|
2070
|
+
return [];
|
|
2071
|
+
}
|
|
2072
|
+
createControlConfig(field, formState) {
|
|
2073
|
+
const config = this.createDefaultControlConfig(TextControlConfig, field);
|
|
2074
|
+
config.maskConfig = {
|
|
2075
|
+
mask: () => new Array(this.maxFieldLength).fill('9').join(''),
|
|
2076
|
+
unmaskModelValue: false,
|
|
2077
|
+
guide: false,
|
|
2078
|
+
};
|
|
2079
|
+
config.tooltip = {
|
|
2080
|
+
text: 'The code is on the back of your card',
|
|
2081
|
+
image: 'cvv',
|
|
2082
|
+
parentField: FieldNames.cvv,
|
|
2083
|
+
position: 'input',
|
|
2084
|
+
analyticsAction: 'show-cvv-tooltip',
|
|
2085
|
+
};
|
|
2086
|
+
config.inputMode = 'numeric';
|
|
2087
|
+
config.shouldHideUserInput = this.shouldHideUserInput();
|
|
2088
|
+
config.disabled = formState?.disabled ?? false;
|
|
2089
|
+
return config;
|
|
2090
|
+
}
|
|
2091
|
+
getAutocomplete() {
|
|
2092
|
+
return 'cc-csc';
|
|
2093
|
+
}
|
|
2094
|
+
getDataType() {
|
|
2095
|
+
return 'password';
|
|
2096
|
+
}
|
|
2097
|
+
shouldHideUserInput() {
|
|
2098
|
+
return true;
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
CvvConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CvvConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2102
|
+
CvvConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CvvConverter });
|
|
2103
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CvvConverter, decorators: [{
|
|
2104
|
+
type: Injectable
|
|
2105
|
+
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
2106
|
+
|
|
2107
|
+
const birthdateValidator = ({ value }) => {
|
|
2108
|
+
if (isEmptyInputValue(value) || typeof value !== 'string') {
|
|
2109
|
+
return null;
|
|
2110
|
+
}
|
|
2111
|
+
const error = {
|
|
2112
|
+
invalidBirthDate: {
|
|
2113
|
+
message: `Enter a valid birth date`,
|
|
2114
|
+
},
|
|
2115
|
+
};
|
|
2116
|
+
const dateArr = value.split('/');
|
|
2117
|
+
const datePartsCount = 3;
|
|
2118
|
+
const dayIndex = 0;
|
|
2119
|
+
const monthIndex = 1;
|
|
2120
|
+
const yearIndex = 2;
|
|
2121
|
+
const maxMonths = 12;
|
|
2122
|
+
const maxDays = 31;
|
|
2123
|
+
const minAge = 16;
|
|
2124
|
+
const maxAge = 120;
|
|
2125
|
+
if (dateArr.length < datePartsCount) {
|
|
2126
|
+
return null;
|
|
2127
|
+
}
|
|
2128
|
+
if (+dateArr[monthIndex] > maxMonths || +dateArr[dayIndex] > maxDays) {
|
|
2129
|
+
return error;
|
|
2130
|
+
}
|
|
2131
|
+
const currentDate = new Date(+dateArr[yearIndex], +dateArr[monthIndex], +dateArr[dayIndex]);
|
|
2132
|
+
const nowDate = new Date();
|
|
2133
|
+
if (isNaN(currentDate.getFullYear()) ||
|
|
2134
|
+
nowDate.getFullYear() - currentDate.getFullYear() <= minAge ||
|
|
2135
|
+
nowDate.getFullYear() - currentDate.getFullYear() > maxAge) {
|
|
2136
|
+
return error;
|
|
2137
|
+
}
|
|
2138
|
+
else {
|
|
2139
|
+
return null;
|
|
2140
|
+
}
|
|
2141
|
+
};
|
|
2142
|
+
|
|
2143
|
+
class BirthDateConverter extends Converter {
|
|
2144
|
+
constructor(syncService) {
|
|
2145
|
+
super(syncService);
|
|
2146
|
+
}
|
|
2147
|
+
getValidators(field) {
|
|
2148
|
+
return super
|
|
2149
|
+
.getValidators(field)
|
|
2150
|
+
.concat([
|
|
2151
|
+
convert(Validators.pattern(/^[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{4}$/), `Enter a valid birth date`),
|
|
2152
|
+
birthdateValidator,
|
|
2153
|
+
]);
|
|
2154
|
+
}
|
|
2155
|
+
createControlConfig(field) {
|
|
2156
|
+
const config = this.createDefaultControlConfig(TextControlConfig, field);
|
|
2157
|
+
config.maskConfig = {
|
|
2158
|
+
mask: '99/99/9999',
|
|
2159
|
+
unmaskModelValue: false,
|
|
2160
|
+
guide: false,
|
|
2161
|
+
};
|
|
2162
|
+
config.placeholder = `DD/MM/YYYY`;
|
|
2163
|
+
config.inputMode = 'numeric';
|
|
2164
|
+
return config;
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
BirthDateConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: BirthDateConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2168
|
+
BirthDateConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: BirthDateConverter });
|
|
2169
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: BirthDateConverter, decorators: [{
|
|
2170
|
+
type: Injectable
|
|
2171
|
+
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
2172
|
+
|
|
2173
|
+
class CardholderNameConverter extends Converter {
|
|
2174
|
+
constructor(syncService) {
|
|
2175
|
+
super(syncService);
|
|
2176
|
+
}
|
|
2177
|
+
createControlConfig(field) {
|
|
2178
|
+
return this.createDefaultControlConfig(TextControlConfig, field);
|
|
2179
|
+
}
|
|
2180
|
+
getAutocomplete() {
|
|
2181
|
+
return 'cc-name';
|
|
2182
|
+
}
|
|
2183
|
+
getDataType() {
|
|
2184
|
+
return 'text';
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
CardholderNameConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardholderNameConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2188
|
+
CardholderNameConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardholderNameConverter });
|
|
2189
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CardholderNameConverter, decorators: [{
|
|
2190
|
+
type: Injectable
|
|
2191
|
+
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
2192
|
+
|
|
2193
|
+
const cpfNameRegex = /^[a-zA-ZÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ.'-]{2,50}(?: [a-zA-ZÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ.'-]{2,50}){1,8}$/i; // tslint:disable-line
|
|
2194
|
+
|
|
2195
|
+
class CpfNameConverter extends Converter {
|
|
2196
|
+
constructor(syncService) {
|
|
2197
|
+
super(syncService);
|
|
2198
|
+
}
|
|
2199
|
+
getValidators(field) {
|
|
2200
|
+
return super
|
|
2201
|
+
.getValidators(field)
|
|
2202
|
+
.concat([
|
|
2203
|
+
convert(Validators.pattern(cpfNameRegex), `Enter a valid name`),
|
|
2204
|
+
]);
|
|
2205
|
+
}
|
|
2206
|
+
createControlConfig(field) {
|
|
2207
|
+
const config = this.createDefaultControlConfig(TextControlConfig, field);
|
|
2208
|
+
config.tooltip = {
|
|
2209
|
+
text: `Where to find your name`,
|
|
2210
|
+
image: 'cpf-name',
|
|
2211
|
+
};
|
|
2212
|
+
return config;
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
CpfNameConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNameConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2216
|
+
CpfNameConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNameConverter });
|
|
2217
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNameConverter, decorators: [{
|
|
2218
|
+
type: Injectable
|
|
2219
|
+
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
2220
|
+
|
|
2221
|
+
class CpfNumberConverter extends Converter {
|
|
2222
|
+
constructor(syncService) {
|
|
2223
|
+
super(syncService);
|
|
2224
|
+
}
|
|
2225
|
+
createControlConfig(field) {
|
|
2226
|
+
const config = this.createDefaultControlConfig(TextControlConfig, field);
|
|
2227
|
+
config.maskConfig = {
|
|
2228
|
+
mask: '999.999.999-99',
|
|
2229
|
+
unmaskModelValue: true,
|
|
2230
|
+
guide: false,
|
|
2231
|
+
};
|
|
2232
|
+
config.inputMode = 'numeric';
|
|
2233
|
+
config.placeholder = '000.000.000-00';
|
|
2234
|
+
config.tooltip = {
|
|
2235
|
+
text: `Where to find your registration number`,
|
|
2236
|
+
image: 'cpf-number',
|
|
2237
|
+
};
|
|
2238
|
+
return config;
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
CpfNumberConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNumberConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2242
|
+
CpfNumberConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNumberConverter });
|
|
2243
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CpfNumberConverter, decorators: [{
|
|
2244
|
+
type: Injectable
|
|
2245
|
+
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
2246
|
+
|
|
2247
|
+
class StreetNumberConverter extends Converter {
|
|
2248
|
+
constructor(syncService) {
|
|
2249
|
+
super(syncService);
|
|
2250
|
+
}
|
|
2251
|
+
getValidators(field, formState) {
|
|
2252
|
+
const validators = super.getValidators(field);
|
|
2253
|
+
if (formState?.country === 'BL') {
|
|
2254
|
+
validators.push(convert(restrictedValueValidator('0'), `Enter a valid building number`));
|
|
2255
|
+
}
|
|
2256
|
+
return validators;
|
|
2257
|
+
}
|
|
2258
|
+
createControlConfig(field) {
|
|
2259
|
+
return this.createDefaultControlConfig(TextControlConfig, field);
|
|
2260
|
+
}
|
|
2261
|
+
}
|
|
2262
|
+
StreetNumberConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: StreetNumberConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2263
|
+
StreetNumberConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: StreetNumberConverter });
|
|
2264
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: StreetNumberConverter, decorators: [{
|
|
2265
|
+
type: Injectable
|
|
2266
|
+
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
2267
|
+
|
|
2268
|
+
class TextConverter extends Converter {
|
|
2269
|
+
constructor(syncService) {
|
|
2270
|
+
super(syncService);
|
|
2271
|
+
}
|
|
2272
|
+
createControlConfig(field) {
|
|
2273
|
+
return this.createDefaultControlConfig(TextControlConfig, field);
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
TextConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: TextConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2277
|
+
TextConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: TextConverter });
|
|
2278
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: TextConverter, decorators: [{
|
|
1895
2279
|
type: Injectable
|
|
1896
|
-
}], ctorParameters: function () { return [{ type:
|
|
2280
|
+
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
1897
2281
|
|
|
1898
|
-
|
|
1899
|
-
|
|
2282
|
+
function phoneValidator() {
|
|
2283
|
+
return convert(Validators.pattern(/^\d*$/), 'Enter a valid phone');
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
function minLengthValidator(minLength) {
|
|
2287
|
+
return convert(Validators.minLength(minLength), `Enter at least ${minLength} characters`);
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
function maxLengthValidator(maxLength) {
|
|
2291
|
+
return convert(Validators.maxLength(maxLength), `Enter no more than ${maxLength} characters`);
|
|
2292
|
+
}
|
|
2293
|
+
|
|
2294
|
+
class PhoneControlConfig extends ControlConfig {
|
|
2295
|
+
constructor() {
|
|
2296
|
+
super(...arguments);
|
|
2297
|
+
this.controlType = 'phone';
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
class PhoneConverter extends Converter {
|
|
2302
|
+
constructor(syncService) {
|
|
1900
2303
|
super(syncService);
|
|
1901
|
-
this.maxLengthValidator = maxLengthValidator;
|
|
1902
|
-
this.minLengthValidator = minLengthValidator;
|
|
1903
2304
|
}
|
|
1904
2305
|
getValidators(field) {
|
|
2306
|
+
const minLength = 10;
|
|
2307
|
+
const maxLength = 15;
|
|
1905
2308
|
return super
|
|
1906
2309
|
.getValidators(field)
|
|
1907
2310
|
.concat([
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
2311
|
+
convertedRequiredValidator(),
|
|
2312
|
+
phoneValidator(),
|
|
2313
|
+
minLengthValidator(minLength),
|
|
2314
|
+
maxLengthValidator(maxLength),
|
|
1911
2315
|
]);
|
|
1912
2316
|
}
|
|
1913
|
-
createControlConfig(field
|
|
1914
|
-
const config = this.createDefaultControlConfig(
|
|
1915
|
-
config.
|
|
1916
|
-
config.availableCardTypes =
|
|
1917
|
-
formState?.availableCardTypes ?? [];
|
|
1918
|
-
config.activeCardType = formState?.activeCardType;
|
|
1919
|
-
config.customError = formState?.customError;
|
|
1920
|
-
config.disabled = formState?.disabled ?? false;
|
|
2317
|
+
createControlConfig(field) {
|
|
2318
|
+
const config = this.createDefaultControlConfig(PhoneControlConfig, field);
|
|
2319
|
+
config.inputMode = 'numeric';
|
|
1921
2320
|
return config;
|
|
1922
2321
|
}
|
|
1923
|
-
getAutocomplete() {
|
|
1924
|
-
return 'cc-number';
|
|
1925
|
-
}
|
|
1926
|
-
getDataType() {
|
|
1927
|
-
return 'text';
|
|
1928
|
-
}
|
|
1929
2322
|
}
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type:
|
|
2323
|
+
PhoneConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PhoneConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2324
|
+
PhoneConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PhoneConverter });
|
|
2325
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PhoneConverter, decorators: [{
|
|
1933
2326
|
type: Injectable
|
|
1934
|
-
}], ctorParameters: function () { return [{ type: SyncService }
|
|
2327
|
+
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
1935
2328
|
|
|
1936
2329
|
const convertersMapToken = new InjectionToken('ConvertersTokensMap');
|
|
1937
2330
|
const convertersMap = {
|
|
1938
2331
|
zip: ZipConverter,
|
|
1939
2332
|
email: EmailConverter,
|
|
1940
2333
|
card_number: CardNumberConverter,
|
|
2334
|
+
card_month: CardExpirationConverter,
|
|
2335
|
+
card_year: CardExpirationConverter,
|
|
2336
|
+
cvv: CvvConverter,
|
|
2337
|
+
extra_cvv: CvvConverter,
|
|
2338
|
+
cardholdername: CardholderNameConverter,
|
|
2339
|
+
cpf_number: CpfNumberConverter,
|
|
2340
|
+
cpf_name: CpfNameConverter,
|
|
2341
|
+
birth_date: BirthDateConverter,
|
|
2342
|
+
street_number: StreetNumberConverter,
|
|
2343
|
+
text: TextConverter,
|
|
2344
|
+
phone: PhoneConverter,
|
|
1941
2345
|
};
|
|
1942
2346
|
|
|
1943
2347
|
class ControlConfigService {
|
|
@@ -2099,6 +2503,13 @@ const statusSearchParamsMap = new Map([
|
|
|
2099
2503
|
],
|
|
2100
2504
|
]);
|
|
2101
2505
|
|
|
2506
|
+
class TerminalError extends AppError {
|
|
2507
|
+
constructor(message, code) {
|
|
2508
|
+
super(message);
|
|
2509
|
+
this.code = code;
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2102
2513
|
class XpsApiPart {
|
|
2103
2514
|
constructor() {
|
|
2104
2515
|
this.response = new BehaviorSubject(null);
|
|
@@ -2354,23 +2765,20 @@ const checkStatusResponseFactoryProvider = {
|
|
|
2354
2765
|
};
|
|
2355
2766
|
|
|
2356
2767
|
class CheckStatusService extends XpsApiPart {
|
|
2357
|
-
constructor(
|
|
2768
|
+
constructor(xpsApiService, settingsService, requestFactory, responseFactory) {
|
|
2358
2769
|
super();
|
|
2359
|
-
this.
|
|
2770
|
+
this.xpsApiService = xpsApiService;
|
|
2360
2771
|
this.settingsService = settingsService;
|
|
2361
2772
|
this.requestFactory = requestFactory;
|
|
2362
2773
|
this.responseFactory = responseFactory;
|
|
2363
|
-
this.apiRoute = 'directpayment';
|
|
2364
2774
|
}
|
|
2365
2775
|
setRequestParams(invoice) {
|
|
2366
2776
|
this.invoice = invoice;
|
|
2367
2777
|
}
|
|
2368
2778
|
request() {
|
|
2369
2779
|
const requestParams = this.requestFactory(this.settingsService.token, this.invoice);
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
responseType: 'json',
|
|
2373
|
-
}))
|
|
2780
|
+
this.xpsApiService
|
|
2781
|
+
.directPaymentRequest(requestParams)
|
|
2374
2782
|
.then((response) => {
|
|
2375
2783
|
const checkStatusResponse = this.responseFactory({
|
|
2376
2784
|
status: response.status,
|
|
@@ -2384,14 +2792,14 @@ class CheckStatusService extends XpsApiPart {
|
|
|
2384
2792
|
});
|
|
2385
2793
|
}
|
|
2386
2794
|
}
|
|
2387
|
-
CheckStatusService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CheckStatusService, deps: [{ token:
|
|
2795
|
+
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 });
|
|
2388
2796
|
CheckStatusService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CheckStatusService, providedIn: 'root' });
|
|
2389
2797
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CheckStatusService, decorators: [{
|
|
2390
2798
|
type: Injectable,
|
|
2391
2799
|
args: [{
|
|
2392
2800
|
providedIn: 'root',
|
|
2393
2801
|
}]
|
|
2394
|
-
}], ctorParameters: function () { return [{ type:
|
|
2802
|
+
}], ctorParameters: function () { return [{ type: XpsApiService }, { type: SettingsService }, { type: undefined, decorators: [{
|
|
2395
2803
|
type: Inject,
|
|
2396
2804
|
args: [checkStatusRequestFactoryToken]
|
|
2397
2805
|
}] }, { type: undefined, decorators: [{
|
|
@@ -2522,34 +2930,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
2522
2930
|
}]
|
|
2523
2931
|
}] });
|
|
2524
2932
|
|
|
2525
|
-
var ErrorTags;
|
|
2526
|
-
(function (ErrorTags) {
|
|
2527
|
-
ErrorTags["APP"] = "appError";
|
|
2528
|
-
ErrorTags["HTTP"] = "httpError";
|
|
2529
|
-
ErrorTags["JS"] = "jsError";
|
|
2530
|
-
ErrorTags["WS"] = "webSocket";
|
|
2531
|
-
ErrorTags["ENCRYPT"] = "encrypt";
|
|
2532
|
-
ErrorTags["APPLEPAY"] = "applepay";
|
|
2533
|
-
ErrorTags["HEADLESS_UI"] = "headlessUi";
|
|
2534
|
-
ErrorTags["GOOGLEPAY"] = "googlepay";
|
|
2535
|
-
ErrorTags["PAYTM"] = "paytm";
|
|
2536
|
-
})(ErrorTags || (ErrorTags = {}));
|
|
2537
|
-
|
|
2538
|
-
class TaggedError extends Error {
|
|
2539
|
-
constructor(message, tags) {
|
|
2540
|
-
super(message);
|
|
2541
|
-
this.tags = [];
|
|
2542
|
-
this.parentTag = ErrorTags.HEADLESS_UI;
|
|
2543
|
-
this.tags = this.childTag
|
|
2544
|
-
? [this.parentTag, this.childTag]
|
|
2545
|
-
: [this.parentTag];
|
|
2546
|
-
if (tags) {
|
|
2547
|
-
const newTags = tags.filter((t, i, arr) => !this.tags.includes(t) && arr.indexOf(t) == i);
|
|
2548
|
-
this.tags = [...this.tags, ...newTags];
|
|
2549
|
-
}
|
|
2550
|
-
}
|
|
2551
|
-
}
|
|
2552
|
-
|
|
2553
2933
|
class WsError extends TaggedError {
|
|
2554
2934
|
constructor(message, channelName, tags) {
|
|
2555
2935
|
tags = tags ? [...tags, ErrorTags.WS] : [ErrorTags.WS];
|
|
@@ -3409,11 +3789,430 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
3409
3789
|
}]
|
|
3410
3790
|
}] });
|
|
3411
3791
|
|
|
3792
|
+
var ThreeDsStatusWebSocketTypes;
|
|
3793
|
+
(function (ThreeDsStatusWebSocketTypes) {
|
|
3794
|
+
ThreeDsStatusWebSocketTypes["status3DS_changed"] = "status3DS_changed";
|
|
3795
|
+
})(ThreeDsStatusWebSocketTypes || (ThreeDsStatusWebSocketTypes = {}));
|
|
3796
|
+
|
|
3797
|
+
var ThreeDsStatusTypes;
|
|
3798
|
+
(function (ThreeDsStatusTypes) {
|
|
3799
|
+
ThreeDsStatusTypes["completed"] = "completed";
|
|
3800
|
+
ThreeDsStatusTypes["challenge"] = "challenge";
|
|
3801
|
+
ThreeDsStatusTypes["collectDfp"] = "collect_dfp";
|
|
3802
|
+
})(ThreeDsStatusTypes || (ThreeDsStatusTypes = {}));
|
|
3803
|
+
|
|
3804
|
+
class XpsResponseError extends AppError {
|
|
3805
|
+
constructor(message) {
|
|
3806
|
+
super('XPS response failed' + (message ? `: "${message}".` : '.'));
|
|
3807
|
+
}
|
|
3808
|
+
}
|
|
3809
|
+
|
|
3810
|
+
class StatusThreeDsRequest {
|
|
3811
|
+
constructor(token, threeDsId) {
|
|
3812
|
+
this.access_token = token;
|
|
3813
|
+
this.threeDSTrXid = threeDsId;
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
|
|
3817
|
+
const statusThreeDsRequestFactoryToken = new InjectionToken('StatusThreeDsRequest');
|
|
3818
|
+
const statusThreeDsRequestFactoryProvider = {
|
|
3819
|
+
provide: statusThreeDsRequestFactoryToken,
|
|
3820
|
+
useValue: (...args) => new StatusThreeDsRequest(...args),
|
|
3821
|
+
};
|
|
3822
|
+
|
|
3823
|
+
class StatusThreeDsResponse {
|
|
3824
|
+
constructor(params) {
|
|
3825
|
+
this.status = params.status;
|
|
3826
|
+
this.checkoutForm = params.checkoutForm;
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
const statusThreeDsResponseFactoryToken = new InjectionToken('StatusThreeDsResponse');
|
|
3831
|
+
const statusThreeDsResponseFactoryProvider = {
|
|
3832
|
+
provide: statusThreeDsResponseFactoryToken,
|
|
3833
|
+
useValue: (...args) => new StatusThreeDsResponse(...args),
|
|
3834
|
+
};
|
|
3835
|
+
|
|
3836
|
+
class StatusThreeDsService {
|
|
3837
|
+
get response$() {
|
|
3838
|
+
return this.response.asObservable();
|
|
3839
|
+
}
|
|
3840
|
+
constructor(secureApi, settingsService, requestFactory, responseFactory) {
|
|
3841
|
+
this.secureApi = secureApi;
|
|
3842
|
+
this.settingsService = settingsService;
|
|
3843
|
+
this.requestFactory = requestFactory;
|
|
3844
|
+
this.responseFactory = responseFactory;
|
|
3845
|
+
this.apiRoute = 'secure3d/check';
|
|
3846
|
+
this.response = new Subject();
|
|
3847
|
+
}
|
|
3848
|
+
request(data) {
|
|
3849
|
+
const token = this.settingsService.token;
|
|
3850
|
+
if (!token) {
|
|
3851
|
+
throw new TokenError();
|
|
3852
|
+
}
|
|
3853
|
+
const requestParams = this.requestFactory(token, data.threeDSTrXid);
|
|
3854
|
+
void lastValueFrom(this.secureApi
|
|
3855
|
+
.post(this.apiRoute, new URLSearchParams({ ...requestParams }), {
|
|
3856
|
+
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
|
|
3857
|
+
responseType: 'json',
|
|
3858
|
+
})
|
|
3859
|
+
.pipe(map$1((response) => {
|
|
3860
|
+
const statusResponse = this.responseFactory({
|
|
3861
|
+
status: response.secure3d.status,
|
|
3862
|
+
checkoutForm: response.secure3d.checkout_form,
|
|
3863
|
+
});
|
|
3864
|
+
this.response.next(statusResponse);
|
|
3865
|
+
}))).catch((error) => {
|
|
3866
|
+
throw new XpsResponseError(error.message);
|
|
3867
|
+
});
|
|
3868
|
+
}
|
|
3869
|
+
}
|
|
3870
|
+
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 });
|
|
3871
|
+
StatusThreeDsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: StatusThreeDsService, providedIn: 'root' });
|
|
3872
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: StatusThreeDsService, decorators: [{
|
|
3873
|
+
type: Injectable,
|
|
3874
|
+
args: [{
|
|
3875
|
+
providedIn: 'root',
|
|
3876
|
+
}]
|
|
3877
|
+
}], ctorParameters: function () { return [{ type: SecureApiClient }, { type: SettingsService }, { type: undefined, decorators: [{
|
|
3878
|
+
type: Inject,
|
|
3879
|
+
args: [statusThreeDsRequestFactoryToken]
|
|
3880
|
+
}] }, { type: undefined, decorators: [{
|
|
3881
|
+
type: Inject,
|
|
3882
|
+
args: [statusThreeDsResponseFactoryToken]
|
|
3883
|
+
}] }]; } });
|
|
3884
|
+
|
|
3885
|
+
class NotifyDfpStatusRequest {
|
|
3886
|
+
constructor(params) {
|
|
3887
|
+
this.access_token = params.token;
|
|
3888
|
+
this.threeDSTrXid = params.threeDsTrXid;
|
|
3889
|
+
this.secure3dCompind = params.isCompind ? 'Y' : 'N';
|
|
3890
|
+
}
|
|
3891
|
+
}
|
|
3892
|
+
|
|
3893
|
+
const notifyDfpStatusRequestFactoryToken = new InjectionToken('NotifyDfpStatusRequest');
|
|
3894
|
+
const notifyDfpStatusRequestFactoryProvider = {
|
|
3895
|
+
provide: notifyDfpStatusRequestFactoryToken,
|
|
3896
|
+
useValue: (...args) => new NotifyDfpStatusRequest(...args),
|
|
3897
|
+
};
|
|
3898
|
+
|
|
3899
|
+
class NotifyDfpStatusService {
|
|
3900
|
+
constructor(secureApi, settingsService, requestFactory) {
|
|
3901
|
+
this.secureApi = secureApi;
|
|
3902
|
+
this.settingsService = settingsService;
|
|
3903
|
+
this.requestFactory = requestFactory;
|
|
3904
|
+
this.apiRouteComplete = 'secure3d/notify';
|
|
3905
|
+
}
|
|
3906
|
+
/*
|
|
3907
|
+
* isCompind is a flag of dfp expired state
|
|
3908
|
+
*/
|
|
3909
|
+
request(threeDsId, isCompind) {
|
|
3910
|
+
const token = this.settingsService.token;
|
|
3911
|
+
if (!token) {
|
|
3912
|
+
throw new TokenError();
|
|
3913
|
+
}
|
|
3914
|
+
const requestParams = this.requestFactory({
|
|
3915
|
+
token: token,
|
|
3916
|
+
threeDsTrXid: threeDsId,
|
|
3917
|
+
isCompind,
|
|
3918
|
+
});
|
|
3919
|
+
lastValueFrom(this.secureApi.post(this.apiRouteComplete, new URLSearchParams({ ...requestParams }), {
|
|
3920
|
+
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
|
|
3921
|
+
responseType: 'json',
|
|
3922
|
+
})).catch((error) => {
|
|
3923
|
+
throw new XpsResponseError(error.message);
|
|
3924
|
+
});
|
|
3925
|
+
}
|
|
3926
|
+
}
|
|
3927
|
+
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 });
|
|
3928
|
+
NotifyDfpStatusService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NotifyDfpStatusService, providedIn: 'root' });
|
|
3929
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NotifyDfpStatusService, decorators: [{
|
|
3930
|
+
type: Injectable,
|
|
3931
|
+
args: [{
|
|
3932
|
+
providedIn: 'root',
|
|
3933
|
+
}]
|
|
3934
|
+
}], ctorParameters: function () { return [{ type: SecureApiClient }, { type: SettingsService }, { type: undefined, decorators: [{
|
|
3935
|
+
type: Inject,
|
|
3936
|
+
args: [notifyDfpStatusRequestFactoryToken]
|
|
3937
|
+
}] }]; } });
|
|
3938
|
+
|
|
3939
|
+
class DfpCollectService {
|
|
3940
|
+
constructor(window, notifyDfpStatusService) {
|
|
3941
|
+
this.window = window;
|
|
3942
|
+
this.notifyDfpStatusService = notifyDfpStatusService;
|
|
3943
|
+
this.iframeName = 'iframeDFP';
|
|
3944
|
+
this.formName = 'formDFP';
|
|
3945
|
+
}
|
|
3946
|
+
collectDfpStatus(threeDsForm) {
|
|
3947
|
+
if (threeDsForm.waitCallback) {
|
|
3948
|
+
this.openIframeWithPostRequest(threeDsForm, false);
|
|
3949
|
+
}
|
|
3950
|
+
else {
|
|
3951
|
+
this.openIframeWithPostRequest(threeDsForm, true);
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
/*
|
|
3955
|
+
* This method create invisible iframe with required params and after that it submit form in iframe
|
|
3956
|
+
* */
|
|
3957
|
+
openIframeWithPostRequest(threeDsForm, isNeedNotifyAfterLoad) {
|
|
3958
|
+
const iFrameElement = this.window.document.getElementById(this.iframeName);
|
|
3959
|
+
if (!iFrameElement) {
|
|
3960
|
+
this.createIframe(isNeedNotifyAfterLoad, threeDsForm.threeDSTrXid);
|
|
3961
|
+
this.postFormToIframe(threeDsForm.threeDSMethod, threeDsForm.threeDSMethodData);
|
|
3962
|
+
}
|
|
3963
|
+
}
|
|
3964
|
+
/*
|
|
3965
|
+
* isNeedNotifyAfterLoad is need to send notification of dft to server
|
|
3966
|
+
* */
|
|
3967
|
+
createIframe(isNeedNotifyAfterLoad, threeDsTrXid) {
|
|
3968
|
+
const attributes = {
|
|
3969
|
+
name: this.iframeName,
|
|
3970
|
+
id: this.iframeName,
|
|
3971
|
+
src: 'javascript:false',
|
|
3972
|
+
style: 'display:none',
|
|
3973
|
+
};
|
|
3974
|
+
const iFrame = this.window.document.createElement('iframe');
|
|
3975
|
+
this.setAttributes(iFrame, attributes);
|
|
3976
|
+
this.window.document.body.appendChild(iFrame);
|
|
3977
|
+
if (isNeedNotifyAfterLoad) {
|
|
3978
|
+
this.window.document.getElementById(this.iframeName).onload = () => {
|
|
3979
|
+
this.notifyDfpStatusService.request(threeDsTrXid, true);
|
|
3980
|
+
};
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
/*
|
|
3984
|
+
* This method will submit form in our iframe. Form will be created, if it's don't exist
|
|
3985
|
+
* */
|
|
3986
|
+
postFormToIframe(url, threeDsMethod) {
|
|
3987
|
+
let form = this.window.document.getElementById(this.formName);
|
|
3988
|
+
if (!form) {
|
|
3989
|
+
form = this.createForm();
|
|
3990
|
+
this.window.document.body.appendChild(form);
|
|
3991
|
+
}
|
|
3992
|
+
form.setAttribute('action', url);
|
|
3993
|
+
form.setAttribute('target', this.iframeName);
|
|
3994
|
+
form.appendChild(this.createInput('threeDSMethodData', threeDsMethod));
|
|
3995
|
+
form.submit();
|
|
3996
|
+
}
|
|
3997
|
+
/*
|
|
3998
|
+
* This method will create invisible form with required params
|
|
3999
|
+
*/
|
|
4000
|
+
createForm() {
|
|
4001
|
+
const form = this.window.document.createElement('form');
|
|
4002
|
+
const initAttributes = {
|
|
4003
|
+
name: this.formName,
|
|
4004
|
+
id: this.formName,
|
|
4005
|
+
style: 'display:none',
|
|
4006
|
+
method: 'POST',
|
|
4007
|
+
enctype: 'application/x-www-form-urlencoded',
|
|
4008
|
+
};
|
|
4009
|
+
this.setAttributes(form, initAttributes);
|
|
4010
|
+
return form;
|
|
4011
|
+
}
|
|
4012
|
+
createInput(name, value) {
|
|
4013
|
+
const input = this.window.document.createElement('input');
|
|
4014
|
+
input.type = 'hidden';
|
|
4015
|
+
input.name = name;
|
|
4016
|
+
input.value = value;
|
|
4017
|
+
return input;
|
|
4018
|
+
}
|
|
4019
|
+
/*
|
|
4020
|
+
* This method will set attributes to form/iframe
|
|
4021
|
+
* */
|
|
4022
|
+
setAttributes(element, attributes) {
|
|
4023
|
+
Object.keys(attributes).forEach((name) => {
|
|
4024
|
+
element.setAttribute(name, attributes[name]);
|
|
4025
|
+
});
|
|
4026
|
+
}
|
|
4027
|
+
}
|
|
4028
|
+
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 });
|
|
4029
|
+
DfpCollectService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DfpCollectService, providedIn: 'root' });
|
|
4030
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DfpCollectService, decorators: [{
|
|
4031
|
+
type: Injectable,
|
|
4032
|
+
args: [{
|
|
4033
|
+
providedIn: 'root',
|
|
4034
|
+
}]
|
|
4035
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
4036
|
+
type: Inject,
|
|
4037
|
+
args: [windowToken]
|
|
4038
|
+
}] }, { type: NotifyDfpStatusService }]; } });
|
|
4039
|
+
|
|
4040
|
+
class ReinsuranceCheckService {
|
|
4041
|
+
constructor(window) {
|
|
4042
|
+
this.window = window;
|
|
4043
|
+
this.timers = {};
|
|
4044
|
+
}
|
|
4045
|
+
addTimer(timer) {
|
|
4046
|
+
if (!timer) {
|
|
4047
|
+
return;
|
|
4048
|
+
}
|
|
4049
|
+
this.removeTimer(timer.id);
|
|
4050
|
+
this.timers[timer.id] = timer;
|
|
4051
|
+
const timerInStorage = this.timers[timer.id];
|
|
4052
|
+
this.window.setTimeout(() => {
|
|
4053
|
+
timerInStorage.callback();
|
|
4054
|
+
this.timers[timer.id] = null;
|
|
4055
|
+
}, timerInStorage.timeoutMs);
|
|
4056
|
+
}
|
|
4057
|
+
removeTimer(id) {
|
|
4058
|
+
const timerInStorage = this.timers[id];
|
|
4059
|
+
if (!timerInStorage) {
|
|
4060
|
+
return;
|
|
4061
|
+
}
|
|
4062
|
+
this.window.clearTimeout(timerInStorage.timeoutRef);
|
|
4063
|
+
this.timers[id] = null;
|
|
4064
|
+
}
|
|
4065
|
+
}
|
|
4066
|
+
ReinsuranceCheckService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ReinsuranceCheckService, deps: [{ token: windowToken }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4067
|
+
ReinsuranceCheckService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ReinsuranceCheckService, providedIn: 'root' });
|
|
4068
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ReinsuranceCheckService, decorators: [{
|
|
4069
|
+
type: Injectable,
|
|
4070
|
+
args: [{
|
|
4071
|
+
providedIn: 'root',
|
|
4072
|
+
}]
|
|
4073
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
4074
|
+
type: Inject,
|
|
4075
|
+
args: [windowToken]
|
|
4076
|
+
}] }]; } });
|
|
4077
|
+
|
|
4078
|
+
class ThreeDs20Service {
|
|
4079
|
+
get statusUpdates$() {
|
|
4080
|
+
return this.statusUpdates.asObservable();
|
|
4081
|
+
}
|
|
4082
|
+
constructor(statusThreeDsService, notifyDfpStatusService, webSocketFactory, dfpCollectService, reinsuranceCheckService) {
|
|
4083
|
+
this.statusThreeDsService = statusThreeDsService;
|
|
4084
|
+
this.notifyDfpStatusService = notifyDfpStatusService;
|
|
4085
|
+
this.webSocketFactory = webSocketFactory;
|
|
4086
|
+
this.dfpCollectService = dfpCollectService;
|
|
4087
|
+
this.reinsuranceCheckService = reinsuranceCheckService;
|
|
4088
|
+
this.webSocketClient = null;
|
|
4089
|
+
this.statusUpdates = new Subject();
|
|
4090
|
+
this.statusRequestSubscription = null;
|
|
4091
|
+
this.notifyDfpTimerId = 'notify-dfp';
|
|
4092
|
+
this.notifyDfpTimeoutMs = 10000;
|
|
4093
|
+
this.statusThreeDsTimerId = 'status-three-ds';
|
|
4094
|
+
this.statusThreeDsTimeoutMs = 180000;
|
|
4095
|
+
}
|
|
4096
|
+
async checkThreeDs20(threeDsForm) {
|
|
4097
|
+
if (!threeDsForm) {
|
|
4098
|
+
return;
|
|
4099
|
+
}
|
|
4100
|
+
this.reinsuranceCheckService.addTimer({
|
|
4101
|
+
id: this.notifyDfpTimerId,
|
|
4102
|
+
timeoutMs: this.notifyDfpTimeoutMs,
|
|
4103
|
+
callback: () => {
|
|
4104
|
+
this.notifyDfpStatusService.request(threeDsForm.threeDSTrXid, false);
|
|
4105
|
+
},
|
|
4106
|
+
});
|
|
4107
|
+
this.webSocketClient = this.webSocketFactory.createWebSocketClient(threeDsForm.webSocketChannelUrl, threeDsForm.webSocketClientType);
|
|
4108
|
+
await this.webSocketClient.open(threeDsForm.webSocketChannelUrl, threeDsForm.webSocketClientType);
|
|
4109
|
+
this.webSocketSubscription?.unsubscribe();
|
|
4110
|
+
this.webSocketSubscription = this.webSocketClient.messages$.subscribe((message) => {
|
|
4111
|
+
if (message !== ThreeDsStatusWebSocketTypes.status3DS_changed) {
|
|
4112
|
+
return;
|
|
4113
|
+
}
|
|
4114
|
+
this.statusThreeDsService.request(threeDsForm);
|
|
4115
|
+
});
|
|
4116
|
+
this.webSocketReconnectionSubscription?.unsubscribe();
|
|
4117
|
+
this.webSocketReconnectionSubscription =
|
|
4118
|
+
this.webSocketClient.subscribeOnSuccessfulReconnection(() => {
|
|
4119
|
+
this.statusThreeDsService.request(threeDsForm);
|
|
4120
|
+
});
|
|
4121
|
+
this.handleThreeDsUpdates(threeDsForm);
|
|
4122
|
+
this.statusThreeDsService.request(threeDsForm);
|
|
4123
|
+
this.reinsuranceCheckService.addTimer({
|
|
4124
|
+
id: this.statusThreeDsTimerId,
|
|
4125
|
+
timeoutMs: this.statusThreeDsTimeoutMs,
|
|
4126
|
+
callback: () => {
|
|
4127
|
+
this.statusThreeDsService.request(threeDsForm);
|
|
4128
|
+
},
|
|
4129
|
+
});
|
|
4130
|
+
}
|
|
4131
|
+
handleThreeDsUpdates(threeDsForm) {
|
|
4132
|
+
this.statusRequestSubscription?.unsubscribe();
|
|
4133
|
+
this.statusRequestSubscription =
|
|
4134
|
+
this.statusThreeDsService.response$.subscribe((threeDsStatus) => {
|
|
4135
|
+
if (!threeDsStatus) {
|
|
4136
|
+
return;
|
|
4137
|
+
}
|
|
4138
|
+
if (threeDsStatus.status === ThreeDsStatusTypes.completed) {
|
|
4139
|
+
this.stopReinsuranceMethods();
|
|
4140
|
+
this.statusUpdates.next({
|
|
4141
|
+
type: 'complete',
|
|
4142
|
+
data: {
|
|
4143
|
+
statusUrl: threeDsForm.statusUrl,
|
|
4144
|
+
},
|
|
4145
|
+
});
|
|
4146
|
+
return;
|
|
4147
|
+
}
|
|
4148
|
+
if (threeDsStatus.status === ThreeDsStatusTypes.challenge &&
|
|
4149
|
+
threeDsStatus.checkoutForm) {
|
|
4150
|
+
this.stopReinsuranceMethods();
|
|
4151
|
+
this.statusUpdates.next({
|
|
4152
|
+
type: 'challenge',
|
|
4153
|
+
data: threeDsStatus.checkoutForm,
|
|
4154
|
+
});
|
|
4155
|
+
}
|
|
4156
|
+
if (threeDsStatus.status === ThreeDsStatusTypes.collectDfp) {
|
|
4157
|
+
this.dfpCollectService.collectDfpStatus(threeDsForm);
|
|
4158
|
+
}
|
|
4159
|
+
});
|
|
4160
|
+
}
|
|
4161
|
+
stopReinsuranceMethods() {
|
|
4162
|
+
this.reinsuranceCheckService.removeTimer(this.notifyDfpTimerId);
|
|
4163
|
+
this.reinsuranceCheckService.removeTimer(this.statusThreeDsTimerId);
|
|
4164
|
+
this.webSocketClient?.close();
|
|
4165
|
+
this.statusRequestSubscription?.unsubscribe();
|
|
4166
|
+
}
|
|
4167
|
+
}
|
|
4168
|
+
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 });
|
|
4169
|
+
ThreeDs20Service.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ThreeDs20Service, providedIn: 'root' });
|
|
4170
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ThreeDs20Service, decorators: [{
|
|
4171
|
+
type: Injectable,
|
|
4172
|
+
args: [{
|
|
4173
|
+
providedIn: 'root',
|
|
4174
|
+
}]
|
|
4175
|
+
}], ctorParameters: function () { return [{ type: StatusThreeDsService }, { type: NotifyDfpStatusService }, { type: WebSocketFactory }, { type: DfpCollectService }, { type: ReinsuranceCheckService }]; } });
|
|
4176
|
+
|
|
4177
|
+
class ThreeDsService {
|
|
4178
|
+
constructor(threeDs20Service, nextActionService) {
|
|
4179
|
+
this.threeDs20Service = threeDs20Service;
|
|
4180
|
+
this.nextActionService = nextActionService;
|
|
4181
|
+
this.statusSubscription = null;
|
|
4182
|
+
}
|
|
4183
|
+
checkThreeDs(params) {
|
|
4184
|
+
/*
|
|
4185
|
+
At this moment we support only 3ds 2.0 version.
|
|
4186
|
+
3ds 1.0 currently working by our redirect logic (Redirect NextAction).
|
|
4187
|
+
If in future we will get new version of 3ds, we should add 3ds determination logic to this service
|
|
4188
|
+
*/
|
|
4189
|
+
void this.threeDs20Service.checkThreeDs20(params.parameters.threeDSForm);
|
|
4190
|
+
this.statusSubscription?.unsubscribe();
|
|
4191
|
+
this.statusSubscription = this.threeDs20Service.statusUpdates$.subscribe((statusUpdate) => {
|
|
4192
|
+
if (statusUpdate.type === 'complete') {
|
|
4193
|
+
return this.nextActionService.emitFlowUpdates(new CheckStatusAction(params));
|
|
4194
|
+
}
|
|
4195
|
+
this.nextActionService.emitFlowUpdates(new ThreeDsAction(statusUpdate));
|
|
4196
|
+
});
|
|
4197
|
+
}
|
|
4198
|
+
stopChecking() {
|
|
4199
|
+
this.statusSubscription?.unsubscribe();
|
|
4200
|
+
}
|
|
4201
|
+
}
|
|
4202
|
+
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 });
|
|
4203
|
+
ThreeDsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ThreeDsService, providedIn: 'root' });
|
|
4204
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ThreeDsService, decorators: [{
|
|
4205
|
+
type: Injectable,
|
|
4206
|
+
args: [{
|
|
4207
|
+
providedIn: 'root',
|
|
4208
|
+
}]
|
|
4209
|
+
}], ctorParameters: function () { return [{ type: ThreeDs20Service }, { type: NextActionService }]; } });
|
|
4210
|
+
|
|
3412
4211
|
class PaymentService {
|
|
3413
4212
|
get formFieldsStatus$() {
|
|
3414
4213
|
return this.formFieldsStatusSubject.asObservable().pipe(filter$1(Boolean));
|
|
3415
4214
|
}
|
|
3416
|
-
constructor(initializeService, submitService, syncService, formService, statusService, financeDetailsService, creditCardStateService, nextActionService, controlConfigService) {
|
|
4215
|
+
constructor(initializeService, submitService, syncService, formService, statusService, financeDetailsService, creditCardStateService, nextActionService, controlConfigService, threeDsService) {
|
|
3417
4216
|
this.initializeService = initializeService;
|
|
3418
4217
|
this.submitService = submitService;
|
|
3419
4218
|
this.syncService = syncService;
|
|
@@ -3423,6 +4222,7 @@ class PaymentService {
|
|
|
3423
4222
|
this.creditCardStateService = creditCardStateService;
|
|
3424
4223
|
this.nextActionService = nextActionService;
|
|
3425
4224
|
this.controlConfigService = controlConfigService;
|
|
4225
|
+
this.threeDsService = threeDsService;
|
|
3426
4226
|
this.form = null;
|
|
3427
4227
|
this.data = null;
|
|
3428
4228
|
this.financeDetails = null;
|
|
@@ -3458,6 +4258,13 @@ class PaymentService {
|
|
|
3458
4258
|
const submitResponse = await this.submitService.request(this.fields, this.form);
|
|
3459
4259
|
this.data = submitResponse;
|
|
3460
4260
|
this.emitFinanceDetails(submitResponse.summary);
|
|
4261
|
+
// Handle 3ds flow
|
|
4262
|
+
if (submitResponse.currentCommand === XpsCommand.create) {
|
|
4263
|
+
this.runThreeDs();
|
|
4264
|
+
return;
|
|
4265
|
+
}
|
|
4266
|
+
this.fields = this.getFields();
|
|
4267
|
+
this.form = this.formService.createForm(this.fields);
|
|
3461
4268
|
return this.nextActionService.getNextAction(submitResponse);
|
|
3462
4269
|
}
|
|
3463
4270
|
getFields() {
|
|
@@ -3474,7 +4281,10 @@ class PaymentService {
|
|
|
3474
4281
|
return this.syncService.validate(field);
|
|
3475
4282
|
}
|
|
3476
4283
|
runThreeDs() {
|
|
3477
|
-
|
|
4284
|
+
if (!isSubmitResponse(this.data)) {
|
|
4285
|
+
throw new Error('Should submit form first');
|
|
4286
|
+
}
|
|
4287
|
+
this.threeDsService.checkThreeDs(this.data);
|
|
3478
4288
|
}
|
|
3479
4289
|
getFinanceDetails() {
|
|
3480
4290
|
return this.financeDetails;
|
|
@@ -3525,6 +4335,7 @@ class PaymentService {
|
|
|
3525
4335
|
this.fields = [];
|
|
3526
4336
|
this.formDestroy$.next();
|
|
3527
4337
|
this.destroy$.next();
|
|
4338
|
+
this.threeDsService.stopChecking();
|
|
3528
4339
|
}
|
|
3529
4340
|
emitFinanceDetails(summary) {
|
|
3530
4341
|
this.financeDetailsService.emit(summary);
|
|
@@ -3572,14 +4383,14 @@ class PaymentService {
|
|
|
3572
4383
|
.subscribe(() => this.emitFormFieldsStatus(form));
|
|
3573
4384
|
}
|
|
3574
4385
|
}
|
|
3575
|
-
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 });
|
|
4386
|
+
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 });
|
|
3576
4387
|
PaymentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, providedIn: 'root' });
|
|
3577
4388
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, decorators: [{
|
|
3578
4389
|
type: Injectable,
|
|
3579
4390
|
args: [{
|
|
3580
4391
|
providedIn: 'root',
|
|
3581
4392
|
}]
|
|
3582
|
-
}], ctorParameters: function () { return [{ type: InitializeService }, { type: SubmitService }, { type: SyncService }, { type: FormService }, { type: StatusService }, { type: FinanceDetailsService }, { type: CreditCardStateService }, { type: NextActionService }, { type: ControlConfigService }]; } });
|
|
4393
|
+
}], ctorParameters: function () { return [{ type: InitializeService }, { type: SubmitService }, { type: SyncService }, { type: FormService }, { type: StatusService }, { type: FinanceDetailsService }, { type: CreditCardStateService }, { type: NextActionService }, { type: ControlConfigService }, { type: ThreeDsService }]; } });
|
|
3583
4394
|
|
|
3584
4395
|
class RefundPolicyService {
|
|
3585
4396
|
constructor(settingsService) {
|
|
@@ -3708,7 +4519,7 @@ class CoreLibraryService {
|
|
|
3708
4519
|
}
|
|
3709
4520
|
async init(configuration) {
|
|
3710
4521
|
await this.settingsService.init(configuration);
|
|
3711
|
-
|
|
4522
|
+
this.deviceFingerPrintService.init();
|
|
3712
4523
|
}
|
|
3713
4524
|
async getStatus(url) {
|
|
3714
4525
|
return this.statusService.getStatusWithUrlSearchParams(url);
|
|
@@ -3842,6 +4653,15 @@ FormModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15
|
|
|
3842
4653
|
ZipConverter,
|
|
3843
4654
|
EmailConverter,
|
|
3844
4655
|
CardNumberConverter,
|
|
4656
|
+
CardExpirationConverter,
|
|
4657
|
+
CvvConverter,
|
|
4658
|
+
CardholderNameConverter,
|
|
4659
|
+
CpfNumberConverter,
|
|
4660
|
+
CpfNameConverter,
|
|
4661
|
+
BirthDateConverter,
|
|
4662
|
+
StreetNumberConverter,
|
|
4663
|
+
TextConverter,
|
|
4664
|
+
PhoneConverter,
|
|
3845
4665
|
{ provide: convertersMapToken, useValue: convertersMap },
|
|
3846
4666
|
], imports: [ReactiveFormsModule, ValidatorsModule] });
|
|
3847
4667
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: FormModule, decorators: [{
|
|
@@ -3854,6 +4674,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
3854
4674
|
ZipConverter,
|
|
3855
4675
|
EmailConverter,
|
|
3856
4676
|
CardNumberConverter,
|
|
4677
|
+
CardExpirationConverter,
|
|
4678
|
+
CvvConverter,
|
|
4679
|
+
CardholderNameConverter,
|
|
4680
|
+
CpfNumberConverter,
|
|
4681
|
+
CpfNameConverter,
|
|
4682
|
+
BirthDateConverter,
|
|
4683
|
+
StreetNumberConverter,
|
|
4684
|
+
TextConverter,
|
|
4685
|
+
PhoneConverter,
|
|
3857
4686
|
{ provide: convertersMapToken, useValue: convertersMap },
|
|
3858
4687
|
],
|
|
3859
4688
|
}]
|
|
@@ -3883,6 +4712,9 @@ CoreLibraryModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", versi
|
|
|
3883
4712
|
checkStatusRequestFactoryProvider,
|
|
3884
4713
|
checkStatusResponseFactoryProvider,
|
|
3885
4714
|
financeDetailsResponseFactoryProvider,
|
|
4715
|
+
statusThreeDsRequestFactoryProvider,
|
|
4716
|
+
statusThreeDsResponseFactoryProvider,
|
|
4717
|
+
notifyDfpStatusRequestFactoryProvider,
|
|
3886
4718
|
{
|
|
3887
4719
|
provide: nextActionsToken,
|
|
3888
4720
|
useValue: nextActions,
|
|
@@ -3914,6 +4746,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
3914
4746
|
checkStatusRequestFactoryProvider,
|
|
3915
4747
|
checkStatusResponseFactoryProvider,
|
|
3916
4748
|
financeDetailsResponseFactoryProvider,
|
|
4749
|
+
statusThreeDsRequestFactoryProvider,
|
|
4750
|
+
statusThreeDsResponseFactoryProvider,
|
|
4751
|
+
notifyDfpStatusRequestFactoryProvider,
|
|
3917
4752
|
{
|
|
3918
4753
|
provide: nextActionsToken,
|
|
3919
4754
|
useValue: nextActions,
|