@xsolla/payment-client-core 0.0.14 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/esm2020/lib/core/payment/actions/next-action.interface.mjs +1 -1
  2. package/esm2020/lib/core/payment/actions/next-action.service.mjs +6 -2
  3. package/esm2020/lib/core/payment/actions/next-actions.mjs +6 -2
  4. package/esm2020/lib/core/payment/actions/show-errors/show-errors.action.class.mjs +9 -0
  5. package/esm2020/lib/core/payment/actions/show-errors/show-errors.action.token.mjs +13 -0
  6. package/esm2020/lib/core/payment/actions/show-errors/show-errors.action.type.mjs +2 -0
  7. package/esm2020/lib/core/payment/config/config.service.mjs +4 -1
  8. package/esm2020/lib/core/payment/extended-xps-error.mjs +2 -0
  9. package/esm2020/lib/core/payment/initialize/initialize.service.mjs +13 -6
  10. package/esm2020/lib/core/payment/payment.service.mjs +28 -1
  11. package/esm2020/lib/core/payment/sync/sync.service.mjs +11 -5
  12. package/esm2020/lib/core/url/url.service.mjs +7 -1
  13. package/esm2020/lib/core-library.module.mjs +4 -2
  14. package/fesm2015/xsolla-payment-client-core.mjs +258 -180
  15. package/fesm2015/xsolla-payment-client-core.mjs.map +1 -1
  16. package/fesm2020/xsolla-payment-client-core.mjs +249 -177
  17. package/fesm2020/xsolla-payment-client-core.mjs.map +1 -1
  18. package/lib/core/payment/actions/next-action.interface.d.ts +2 -1
  19. package/lib/core/payment/actions/next-action.service.d.ts +1 -1
  20. package/lib/core/payment/actions/next-actions.d.ts +1 -0
  21. package/lib/core/payment/actions/show-errors/show-errors.action.class.d.ts +8 -0
  22. package/lib/core/payment/actions/show-errors/show-errors.action.token.d.ts +4 -0
  23. package/lib/core/payment/actions/show-errors/show-errors.action.type.d.ts +7 -0
  24. package/lib/core/payment/extended-xps-error.d.ts +4 -0
  25. package/lib/core/payment/initialize/initialize.service.d.ts +3 -1
  26. package/lib/core/payment/payment.service.d.ts +3 -1
  27. package/lib/core/payment/sync/sync.service.d.ts +3 -1
  28. package/package.json +1 -1
  29. package/xsolla-payment-client-core-0.1.0.tgz +0 -0
  30. package/xsolla-payment-client-core-0.0.14.tgz +0 -0
@@ -1,6 +1,6 @@
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, BehaviorSubject, filter as filter$1, takeUntil, skip, throwError } from 'rxjs';
3
+ import { firstValueFrom, lastValueFrom, map, Subject, tap, 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
6
  import { UntypedFormGroup, Validators, UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
@@ -407,6 +407,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
407
407
 
408
408
  class UrlService {
409
409
  addSearchParams(url, params = {}) {
410
+ if (!url) {
411
+ return '';
412
+ }
410
413
  const urlObject = new URL(url);
411
414
  for (const [key, value] of Object.entries(params)) {
412
415
  urlObject.searchParams.set(key, value);
@@ -414,6 +417,9 @@ class UrlService {
414
417
  return urlObject.toString();
415
418
  }
416
419
  getSearchParams(url) {
420
+ if (!url) {
421
+ return {};
422
+ }
417
423
  const urlObject = new URL(url);
418
424
  const searchParams = {};
419
425
  for (const [key, value] of urlObject.searchParams) {
@@ -437,6 +443,9 @@ class PaymentConfigService {
437
443
  this.settingsService = settingsService;
438
444
  }
439
445
  enrich(config) {
446
+ if (!config.returnUrl) {
447
+ throw new Error('URL is not provided in payment config');
448
+ }
440
449
  return {
441
450
  ...config,
442
451
  returnUrl: this.enrichReturnUrl(config.returnUrl),
@@ -564,6 +573,15 @@ const isSubmitResponse = (value) => {
564
573
  return value instanceof SubmitResponse;
565
574
  };
566
575
 
576
+ class ShowErrorsAction {
577
+ constructor(errors) {
578
+ this.type = 'show_errors';
579
+ this.data = {
580
+ errors,
581
+ };
582
+ }
583
+ }
584
+
567
585
  class InitializeResponse {
568
586
  constructor(response) {
569
587
  this.paymentForm = null;
@@ -613,12 +631,199 @@ const initializeResponseFactoryProvider = {
613
631
  useValue: (...args) => new InitializeResponse(...args),
614
632
  };
615
633
 
634
+ class ShowFieldsAction {
635
+ constructor(submitResponse) {
636
+ this.type = 'show_fields';
637
+ this.data = {
638
+ fields: [],
639
+ errors: [],
640
+ messages: [],
641
+ order: {},
642
+ };
643
+ this.data.fields = submitResponse.fields.filter((field) => field?.isVisible === "1" /* XpsBoolean.true */);
644
+ this.data.errors = submitResponse.errors;
645
+ this.data.messages = submitResponse.messages;
646
+ this.data.order = submitResponse.summary;
647
+ }
648
+ }
649
+
650
+ const showFieldsActionFactoryToken = new InjectionToken('ShowFieldsAction');
651
+ const showFieldsActionFactoryProvider = {
652
+ provide: showFieldsActionFactoryToken,
653
+ useValue: {
654
+ factory: (...args) => new ShowFieldsAction(...args),
655
+ isSuitable: (response) => {
656
+ return response.currentCommand === XpsCommand.check;
657
+ },
658
+ },
659
+ };
660
+
661
+ class CheckStatusAction {
662
+ constructor(submitResponse) {
663
+ this.type = 'check_status';
664
+ const status = submitResponse.parameters.status;
665
+ this.data = {
666
+ invoice: status?.invoice,
667
+ signature: submitResponse.parameters.form.signature?.value,
668
+ locale: submitResponse.parameters.form.locale?.value,
669
+ testPs: submitResponse.parameters.form.testPs?.value,
670
+ testXsolla: submitResponse.parameters.form.testXsolla?.value,
671
+ testProject: submitResponse.parameters.form.testProject?.value,
672
+ userReturnStatus: submitResponse.parameters.form.userReturnStatus?.value,
673
+ };
674
+ }
675
+ }
676
+
677
+ const checkStatusActionFactoryToken = new InjectionToken('CheckStatusAction');
678
+ const checkStatusActionFactoryProvider = {
679
+ provide: checkStatusActionFactoryToken,
680
+ useValue: {
681
+ factory: (...args) => new CheckStatusAction(...args),
682
+ isSuitable: (response) => {
683
+ return response.currentCommand === XpsCommand.status;
684
+ },
685
+ },
686
+ };
687
+
688
+ class StatusUpdatedAction {
689
+ constructor(statusResponse) {
690
+ this.type = 'status_updated';
691
+ this.data = {
692
+ statusState: statusResponse.status.statusState,
693
+ invoice: statusResponse.status.invoice,
694
+ isSuccess: statusResponse.status.isSuccess,
695
+ isCanceled: statusResponse.status.isCanceled,
696
+ group: statusResponse.status.group,
697
+ };
698
+ }
699
+ }
700
+
701
+ const statusUpdatedActionFactoryToken = new InjectionToken('StatusUpdatedAction');
702
+ const statusUpdatedActionFactoryProvider = {
703
+ provide: statusUpdatedActionFactoryToken,
704
+ useValue: {
705
+ factory: (...args) => new StatusUpdatedAction(...args),
706
+ isSuitable: () => false,
707
+ },
708
+ };
709
+
710
+ class RedirectAction {
711
+ constructor(submitResponse) {
712
+ this.type = 'redirect';
713
+ this.data = {
714
+ fields: submitResponse.fields,
715
+ errors: submitResponse.errors,
716
+ messages: submitResponse.messages,
717
+ order: submitResponse.summary,
718
+ invoiceId: submitResponse.fixInvoice,
719
+ redirect: this.getRedirect(submitResponse),
720
+ };
721
+ }
722
+ getRedirect(submitResponse) {
723
+ return {
724
+ redirectUrl: submitResponse.parameters.checkout.action,
725
+ data: submitResponse.parameters.checkout.data,
726
+ };
727
+ }
728
+ }
729
+
730
+ const redirectActionFactoryToken = new InjectionToken('RedirectAction');
731
+ const redirectActionFactoryProvider = {
732
+ provide: redirectActionFactoryToken,
733
+ useValue: {
734
+ factory: (...args) => new RedirectAction(...args),
735
+ isSuitable: (response) => {
736
+ return (response.currentCommand === XpsCommand.account ||
737
+ (response.currentCommand === XpsCommand.checkout &&
738
+ Boolean(response.parameters.checkout)));
739
+ },
740
+ },
741
+ };
742
+
743
+ const showErrorsActionFactoryToken = new InjectionToken('ShowErrorsAction');
744
+ const showErrorsActionFactoryProvider = {
745
+ provide: showErrorsActionFactoryToken,
746
+ useValue: {
747
+ factory: (...args) => new ShowErrorsAction(...args),
748
+ isSuitable: (response) => {
749
+ return Boolean(response.errors?.length);
750
+ },
751
+ },
752
+ };
753
+
754
+ const nextActionsToken = new InjectionToken('Action');
755
+ const nextActions = [
756
+ showFieldsActionFactoryProvider,
757
+ checkStatusActionFactoryProvider,
758
+ redirectActionFactoryProvider,
759
+ ];
760
+ const flowUpdateNextActions = [
761
+ statusUpdatedActionFactoryProvider,
762
+ showErrorsActionFactoryProvider,
763
+ ];
764
+
765
+ class NextActionService {
766
+ get flowUpdates$() {
767
+ return this.flowUpdatesSubject.asObservable();
768
+ }
769
+ constructor(nextActionTokens, injector) {
770
+ this.nextActionTokens = nextActionTokens;
771
+ this.injector = injector;
772
+ this.flowUpdatesSubject = new Subject();
773
+ this.nextActionsList = [];
774
+ this.fillNextActionsList();
775
+ }
776
+ getNextAction(submitResponse) {
777
+ if (submitResponse.errors?.length) {
778
+ this.emitFlowUpdates(new ShowErrorsAction(submitResponse.errors));
779
+ }
780
+ if (!submitResponse.currentCommand) {
781
+ return null;
782
+ }
783
+ const nextActionFactory = this.findNextAction(submitResponse);
784
+ if (nextActionFactory) {
785
+ return nextActionFactory(submitResponse);
786
+ }
787
+ throw new Error('Next action is undefined.');
788
+ }
789
+ emitFlowUpdates(action) {
790
+ this.flowUpdatesSubject.next(action);
791
+ }
792
+ fillNextActionsList() {
793
+ this.nextActionTokens.forEach((nextAction) => {
794
+ const item = this.injector.get(nextAction.provide);
795
+ this.nextActionsList.push(item);
796
+ });
797
+ }
798
+ findNextAction(submitResponse) {
799
+ const actionType = this.nextActionsList.find((nextAction) => {
800
+ return nextAction.isSuitable(submitResponse);
801
+ });
802
+ if (!actionType) {
803
+ return;
804
+ }
805
+ return actionType.factory;
806
+ }
807
+ }
808
+ NextActionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NextActionService, deps: [{ token: nextActionsToken }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
809
+ NextActionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NextActionService, providedIn: 'root' });
810
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NextActionService, decorators: [{
811
+ type: Injectable,
812
+ args: [{
813
+ providedIn: 'root',
814
+ }]
815
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
816
+ type: Inject,
817
+ args: [nextActionsToken]
818
+ }] }, { type: i0.Injector }]; } });
819
+
616
820
  class InitializeService {
617
- constructor(responseFactory, secureApi, settingsService, countryService) {
821
+ constructor(responseFactory, secureApi, settingsService, countryService, nextActionService) {
618
822
  this.responseFactory = responseFactory;
619
823
  this.secureApi = secureApi;
620
824
  this.settingsService = settingsService;
621
825
  this.countryService = countryService;
826
+ this.nextActionService = nextActionService;
622
827
  this.apiRoute = 'directpayment';
623
828
  // TODO PAYMENTS-15743: replace with new refer id for headless core
624
829
  this.ps4ReferId = '22';
@@ -636,12 +841,16 @@ class InitializeService {
636
841
  headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
637
842
  responseType: 'json',
638
843
  })
639
- .pipe(map((response) => this.responseFactory(response)))).catch((error) => {
844
+ .pipe(map((response) => this.responseFactory(response)), tap((response) => {
845
+ if (response.paymentForm?.errors?.length) {
846
+ this.nextActionService.emitFlowUpdates(new ShowErrorsAction(response.paymentForm.errors));
847
+ }
848
+ }))).catch((error) => {
640
849
  throw new ResponseError(error.message);
641
850
  });
642
851
  }
643
852
  }
644
- 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 }], target: i0.ɵɵFactoryTarget.Injectable });
853
+ 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 });
645
854
  InitializeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, providedIn: 'root' });
646
855
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, decorators: [{
647
856
  type: Injectable,
@@ -651,7 +860,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
651
860
  }], ctorParameters: function () { return [{ type: undefined, decorators: [{
652
861
  type: Inject,
653
862
  args: [initializeResponseFactoryToken]
654
- }] }, { type: SecureApiClient }, { type: SettingsService }, { type: CountryService }]; } });
863
+ }] }, { type: SecureApiClient }, { type: SettingsService }, { type: CountryService }, { type: NextActionService }]; } });
655
864
 
656
865
  class XpsApiPartRequest {
657
866
  addXpsParameters(parameters) {
@@ -997,11 +1206,12 @@ const syncResponseFactoryProvider = {
997
1206
  };
998
1207
 
999
1208
  class SyncService extends EmitDataService {
1000
- constructor(requestFactory, responseFactory, secureApi, settingsService) {
1209
+ constructor(requestFactory, responseFactory, secureApi, nextActionService, settingsService) {
1001
1210
  super();
1002
1211
  this.requestFactory = requestFactory;
1003
1212
  this.responseFactory = responseFactory;
1004
1213
  this.secureApi = secureApi;
1214
+ this.nextActionService = nextActionService;
1005
1215
  this.settingsService = settingsService;
1006
1216
  this.apiRoute = 'directpayment';
1007
1217
  this.prevFieldSyncStates = {};
@@ -1061,6 +1271,9 @@ class SyncService extends EmitDataService {
1061
1271
  headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
1062
1272
  responseType: 'json',
1063
1273
  })).then((response) => {
1274
+ if (response.errors?.length) {
1275
+ this.nextActionService.emitFlowUpdates(new ShowErrorsAction(response.errors));
1276
+ }
1064
1277
  this.emit(response);
1065
1278
  return this.responseFactory(field, response);
1066
1279
  });
@@ -1077,7 +1290,7 @@ class SyncService extends EmitDataService {
1077
1290
  this.prevFieldSyncStates[field.name] = { value, result };
1078
1291
  }
1079
1292
  }
1080
- SyncService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, deps: [{ token: syncRequestFactoryToken }, { token: syncResponseFactoryToken }, { token: SecureApiClient }, { token: SettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
1293
+ SyncService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, deps: [{ token: syncRequestFactoryToken }, { token: syncResponseFactoryToken }, { token: SecureApiClient }, { token: NextActionService }, { token: SettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
1081
1294
  SyncService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, providedIn: 'root' });
1082
1295
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, decorators: [{
1083
1296
  type: Injectable,
@@ -1090,7 +1303,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
1090
1303
  }] }, { type: undefined, decorators: [{
1091
1304
  type: Inject,
1092
1305
  args: [syncResponseFactoryToken]
1093
- }] }, { type: SecureApiClient }, { type: SettingsService }]; } });
1306
+ }] }, { type: SecureApiClient }, { type: NextActionService }, { type: SettingsService }]; } });
1094
1307
 
1095
1308
  class ControlConfig {
1096
1309
  constructor() {
@@ -1373,19 +1586,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
1373
1586
  type: Injectable
1374
1587
  }], ctorParameters: function () { return [{ type: ControlConfigService }]; } });
1375
1588
 
1376
- class StatusUpdatedAction {
1377
- constructor(statusResponse) {
1378
- this.type = 'status_updated';
1379
- this.data = {
1380
- statusState: statusResponse.status.statusState,
1381
- invoice: statusResponse.status.invoice,
1382
- isSuccess: statusResponse.status.isSuccess,
1383
- isCanceled: statusResponse.status.isCanceled,
1384
- group: statusResponse.status.group,
1385
- };
1386
- }
1387
- }
1388
-
1389
1589
  var StatusSearchParam;
1390
1590
  (function (StatusSearchParam) {
1391
1591
  StatusSearchParam["token"] = "token";
@@ -2439,162 +2639,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
2439
2639
  }]
2440
2640
  }], ctorParameters: function () { return [{ type: StatusRequestService }, { type: CheckStatusService }, { type: WebsocketStatusService }]; } });
2441
2641
 
2442
- class ShowFieldsAction {
2443
- constructor(submitResponse) {
2444
- this.type = 'show_fields';
2445
- this.data = {
2446
- fields: [],
2447
- errors: [],
2448
- messages: [],
2449
- order: {},
2450
- };
2451
- this.data.fields = submitResponse.fields.filter((field) => field?.isVisible === "1" /* XpsBoolean.true */);
2452
- this.data.errors = submitResponse.errors;
2453
- this.data.messages = submitResponse.messages;
2454
- this.data.order = submitResponse.summary;
2455
- }
2456
- }
2457
-
2458
- const showFieldsActionFactoryToken = new InjectionToken('ShowFieldsAction');
2459
- const showFieldsActionFactoryProvider = {
2460
- provide: showFieldsActionFactoryToken,
2461
- useValue: {
2462
- factory: (...args) => new ShowFieldsAction(...args),
2463
- isSuitable: (response) => {
2464
- return response.currentCommand === XpsCommand.check;
2465
- },
2466
- },
2467
- };
2468
-
2469
- class CheckStatusAction {
2470
- constructor(submitResponse) {
2471
- this.type = 'check_status';
2472
- const status = submitResponse.parameters.status;
2473
- this.data = {
2474
- invoice: status?.invoice,
2475
- signature: submitResponse.parameters.form.signature?.value,
2476
- locale: submitResponse.parameters.form.locale?.value,
2477
- testPs: submitResponse.parameters.form.testPs?.value,
2478
- testXsolla: submitResponse.parameters.form.testXsolla?.value,
2479
- testProject: submitResponse.parameters.form.testProject?.value,
2480
- userReturnStatus: submitResponse.parameters.form.userReturnStatus?.value,
2481
- };
2482
- }
2483
- }
2484
-
2485
- const checkStatusActionFactoryToken = new InjectionToken('CheckStatusAction');
2486
- const checkStatusActionFactoryProvider = {
2487
- provide: checkStatusActionFactoryToken,
2488
- useValue: {
2489
- factory: (...args) => new CheckStatusAction(...args),
2490
- isSuitable: (response) => {
2491
- return response.currentCommand === XpsCommand.status;
2492
- },
2493
- },
2494
- };
2495
-
2496
- const statusUpdatedActionFactoryToken = new InjectionToken('StatusUpdatedAction');
2497
- const statusUpdatedActionFactoryProvider = {
2498
- provide: statusUpdatedActionFactoryToken,
2499
- useValue: {
2500
- factory: (...args) => new StatusUpdatedAction(...args),
2501
- isSuitable: () => false,
2502
- },
2503
- };
2504
-
2505
- class RedirectAction {
2506
- constructor(submitResponse) {
2507
- this.type = 'redirect';
2508
- this.data = {
2509
- fields: submitResponse.fields,
2510
- errors: submitResponse.errors,
2511
- messages: submitResponse.messages,
2512
- order: submitResponse.summary,
2513
- invoiceId: submitResponse.fixInvoice,
2514
- redirect: this.getRedirect(submitResponse),
2515
- };
2516
- }
2517
- getRedirect(submitResponse) {
2518
- return {
2519
- redirectUrl: submitResponse.parameters.checkout.action,
2520
- data: submitResponse.parameters.checkout.data,
2521
- };
2522
- }
2523
- }
2524
-
2525
- const redirectActionFactoryToken = new InjectionToken('RedirectAction');
2526
- const redirectActionFactoryProvider = {
2527
- provide: redirectActionFactoryToken,
2528
- useValue: {
2529
- factory: (...args) => new RedirectAction(...args),
2530
- isSuitable: (response) => {
2531
- return (response.currentCommand === XpsCommand.account ||
2532
- (response.currentCommand === XpsCommand.checkout &&
2533
- Boolean(response.parameters.checkout)));
2534
- },
2535
- },
2536
- };
2537
-
2538
- const nextActionsToken = new InjectionToken('Action');
2539
- const nextActions = [
2540
- showFieldsActionFactoryProvider,
2541
- checkStatusActionFactoryProvider,
2542
- statusUpdatedActionFactoryProvider,
2543
- redirectActionFactoryProvider,
2544
- ];
2545
-
2546
- class NextActionService {
2547
- get flowUpdates$() {
2548
- return this.flowUpdatesSubject.asObservable();
2549
- }
2550
- constructor(nextActionTokens, injector) {
2551
- this.nextActionTokens = nextActionTokens;
2552
- this.injector = injector;
2553
- this.flowUpdatesSubject = new Subject();
2554
- this.nextActionsList = [];
2555
- this.fillNextActionsList();
2556
- }
2557
- getNextAction(submitResponse) {
2558
- if (!submitResponse.currentCommand) {
2559
- return null;
2560
- }
2561
- const nextActionFactory = this.findNextAction(submitResponse);
2562
- if (nextActionFactory) {
2563
- return nextActionFactory(submitResponse);
2564
- }
2565
- throw new Error('Next action is undefined.');
2566
- }
2567
- emitFlowUpdates(action) {
2568
- this.flowUpdatesSubject.next(action);
2569
- }
2570
- fillNextActionsList() {
2571
- this.nextActionTokens.forEach((nextAction) => {
2572
- const item = this.injector.get(nextAction.provide);
2573
- this.nextActionsList.push(item);
2574
- });
2575
- }
2576
- findNextAction(submitResponse) {
2577
- const actionType = this.nextActionsList.find((nextAction) => {
2578
- return nextAction.isSuitable(submitResponse);
2579
- });
2580
- if (!actionType) {
2581
- return;
2582
- }
2583
- return actionType.factory;
2584
- }
2585
- }
2586
- NextActionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NextActionService, deps: [{ token: nextActionsToken }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
2587
- NextActionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NextActionService, providedIn: 'root' });
2588
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NextActionService, decorators: [{
2589
- type: Injectable,
2590
- args: [{
2591
- providedIn: 'root',
2592
- }]
2593
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
2594
- type: Inject,
2595
- args: [nextActionsToken]
2596
- }] }, { type: i0.Injector }]; } });
2597
-
2598
2642
  class StatusService {
2599
2643
  constructor(urlService, statusRequestService, listenStatusService, nextActionService) {
2600
2644
  this.urlService = urlService;
@@ -2956,6 +3000,7 @@ class PaymentService {
2956
3000
  this.data = await this.initializeService.request(config);
2957
3001
  this.fields = this.getFields();
2958
3002
  this.form = this.formService.createForm(this.fields);
3003
+ this.listenSyncValidationErrors(this.form);
2959
3004
  this.emitFinanceDetails(this.data.paymentForm?.summary);
2960
3005
  this.setupSyncService(this.form, this.fields);
2961
3006
  return this.fields.filter((field) => field?.isVisible === "1" /* XpsBoolean.true */);
@@ -3029,6 +3074,31 @@ class PaymentService {
3029
3074
  .pipe(takeUntil(this.destroy$))
3030
3075
  .subscribe((financeDetails) => (this.financeDetails = financeDetails));
3031
3076
  }
3077
+ listenSyncValidationErrors(form) {
3078
+ form.statusChanges.subscribe(() => {
3079
+ const controls = this.form?.controls;
3080
+ if (controls) {
3081
+ const invalidControls = Object.entries(controls).filter(([key]) => controls[key].invalid);
3082
+ if (invalidControls.length) {
3083
+ const syncValidationErrors = invalidControls
3084
+ .map(([controlName, control]) => {
3085
+ const error = control.errors?.['rewritableError'];
3086
+ if (!error) {
3087
+ return null;
3088
+ }
3089
+ return {
3090
+ code: 101,
3091
+ fieldValidationError: error?.code,
3092
+ message: error?.message ?? '',
3093
+ element_name: controlName,
3094
+ };
3095
+ })
3096
+ .filter(Boolean);
3097
+ this.nextActionService.emitFlowUpdates(new ShowErrorsAction(syncValidationErrors));
3098
+ }
3099
+ }
3100
+ });
3101
+ }
3032
3102
  }
3033
3103
  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: NextActionService }, { token: ControlConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
3034
3104
  PaymentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, providedIn: 'root' });
@@ -3316,6 +3386,7 @@ CoreLibraryModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", versi
3316
3386
  useValue: nextActions,
3317
3387
  },
3318
3388
  ...nextActions,
3389
+ ...flowUpdateNextActions,
3319
3390
  ], imports: [HttpClientModule, FormModule] });
3320
3391
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryModule, decorators: [{
3321
3392
  type: NgModule,
@@ -3346,6 +3417,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
3346
3417
  useValue: nextActions,
3347
3418
  },
3348
3419
  ...nextActions,
3420
+ ...flowUpdateNextActions,
3349
3421
  ],
3350
3422
  }]
3351
3423
  }] });