@xsolla/payment-client-core 0.0.3 → 0.0.5
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-components.interface.mjs +2 -0
- package/esm2020/lib/core/device-finger-print/device-finger-print.service.mjs +167 -0
- package/esm2020/lib/core/device-finger-print/fingerprint-js.interface.mjs +2 -0
- package/esm2020/lib/core/device-finger-print/hash.type.mjs +2 -0
- package/esm2020/lib/core/exceptions-handling/errors/default-terminal-error.class.mjs +8 -0
- package/esm2020/lib/core/exceptions-handling/errors/terminal-error.class.mjs +8 -0
- package/esm2020/lib/core/exceptions-handling/errors/token-error.class.mjs +7 -0
- package/esm2020/lib/core/legal/disclaimer.service.mjs +16 -0
- package/esm2020/lib/core/legal/legal.component.config.mjs +2 -0
- package/esm2020/lib/core/legal/legal.service.mjs +39 -0
- package/esm2020/lib/core/legal/refund-policy.service.mjs +30 -0
- package/esm2020/lib/core/legal/secure-connection.service.mjs +31 -0
- package/esm2020/lib/core/payment/actions/action-factory-value.interface.mjs +2 -0
- package/esm2020/lib/core/payment/actions/action-type-command.map.mjs +5 -0
- package/esm2020/lib/core/payment/actions/action.interface.mjs +2 -0
- package/esm2020/lib/core/payment/actions/check-status/check-status.action.type.mjs +2 -0
- package/esm2020/lib/core/payment/actions/next-action.interface.mjs +2 -0
- package/esm2020/lib/core/payment/actions/next-action.service.mjs +47 -0
- package/esm2020/lib/core/payment/actions/next-actions.mjs +5 -0
- package/esm2020/lib/core/payment/actions/show-fields/show-fields.action.class.mjs +16 -0
- package/esm2020/lib/core/payment/actions/show-fields/show-fields.action.token.mjs +11 -0
- package/esm2020/lib/core/payment/actions/show-fields/show-fields.action.type.mjs +2 -0
- package/esm2020/lib/core/payment/checkout-item.interface.mjs +2 -0
- package/esm2020/lib/core/payment/field-names.enum.mjs +64 -0
- package/esm2020/lib/core/payment/field.interface.mjs +2 -0
- package/esm2020/lib/core/payment/finance-details.interface.mjs +2 -0
- package/esm2020/lib/core/payment/form/common-control-config.interface.mjs +2 -0
- package/esm2020/lib/core/payment/form/controls/control-config.mjs +6 -0
- package/esm2020/lib/core/payment/form/controls/control-config.service.mjs +39 -0
- package/esm2020/lib/core/payment/form/controls/control-type.type.mjs +2 -0
- package/esm2020/lib/core/payment/form/controls/text-control.config.mjs +8 -0
- package/esm2020/lib/core/payment/form/converters/converter.abstract.mjs +75 -0
- package/esm2020/lib/core/payment/form/converters/converters-map.interface.mjs +2 -0
- package/esm2020/lib/core/payment/form/converters/converters-map.mjs +9 -0
- package/esm2020/lib/core/payment/form/converters/email.converter.mjs +29 -0
- package/esm2020/lib/core/payment/form/converters/zip.converter.mjs +64 -0
- package/esm2020/lib/core/payment/form/form-state.interface.mjs +2 -0
- package/esm2020/lib/core/payment/form/form.module.mjs +33 -0
- package/esm2020/lib/core/payment/form/form.service.mjs +28 -0
- package/esm2020/lib/core/payment/form/validators/convert.function.mjs +22 -0
- package/esm2020/lib/core/payment/form/validators/email-validator.mjs +7 -0
- package/esm2020/lib/core/payment/form/validators/required-validator.mjs +6 -0
- package/esm2020/lib/core/payment/form/validators/restricted-value.validator.mjs +6 -0
- package/esm2020/lib/core/payment/form/validators/validation-error.interface.mjs +2 -0
- package/esm2020/lib/core/payment/form/validators/validation-errors.interface.mjs +2 -0
- package/esm2020/lib/core/payment/form/validators/validator-fn.type.mjs +2 -0
- package/esm2020/lib/core/payment/initialize/initialize-request-params.interface.mjs +2 -0
- package/esm2020/lib/core/payment/initialize/initialize-response.class.mjs +43 -0
- package/esm2020/lib/core/payment/initialize/initialize-response.token.mjs +8 -0
- package/esm2020/lib/core/payment/initialize/initialize.service.mjs +46 -0
- package/esm2020/lib/core/payment/invoice.interface.mjs +2 -0
- package/esm2020/lib/core/payment/payment-config.interface.mjs +2 -0
- package/esm2020/lib/core/payment/payment-form.interface.mjs +2 -0
- package/esm2020/lib/core/payment/payment.interface.mjs +2 -0
- package/esm2020/lib/core/payment/payment.service.mjs +58 -0
- package/esm2020/lib/core/payment/status/finance-info-field.interface.mjs +2 -0
- package/esm2020/lib/core/payment/status/line-item.interface.mjs +2 -0
- package/esm2020/lib/core/payment/status/status.enum.mjs +12 -0
- package/esm2020/lib/core/payment/status/status.interface.mjs +2 -0
- package/esm2020/lib/core/payment/status/title-class.enum.mjs +7 -0
- package/esm2020/lib/core/payment/status/web-socket-client-type.enum.mjs +6 -0
- package/esm2020/lib/core/payment/submit/request/submit-request.class.mjs +16 -0
- package/esm2020/lib/core/payment/submit/request/submit-request.token.mjs +8 -0
- package/esm2020/lib/core/payment/submit/response/submit-response.class.mjs +31 -0
- package/esm2020/lib/core/payment/submit/response/submit-response.token.mjs +8 -0
- package/esm2020/lib/core/payment/submit/submit.service.mjs +59 -0
- package/esm2020/lib/core/payment/sync/field-sync-state.interface.mjs +2 -0
- package/esm2020/lib/core/payment/sync/sync-request.class.mjs +31 -0
- package/esm2020/lib/core/payment/sync/sync-request.token.mjs +8 -0
- package/esm2020/lib/core/payment/sync/sync-response.class.mjs +14 -0
- package/esm2020/lib/core/payment/sync/sync-response.token.mjs +8 -0
- package/esm2020/lib/core/payment/sync/sync.service.mjs +91 -0
- package/esm2020/lib/core/payment/virtual-currency.interface.mjs +2 -0
- package/esm2020/lib/core/payment/xps-api-part-request.abstract.mjs +8 -0
- package/esm2020/lib/core/payment/xps-comand.enum.mjs +10 -0
- package/esm2020/lib/core/payment/xps-error.interface.mjs +2 -0
- package/esm2020/lib/core/payment/xps-message.interface.mjs +2 -0
- package/esm2020/lib/core/payment/xps-request.abstract.mjs +8 -0
- package/esm2020/lib/core/payment/xps-response.interface.mjs +2 -0
- package/esm2020/lib/core/payment/xps-subscription-item.interface.mjs +2 -0
- package/esm2020/lib/core/saved-methods/saved-methods.service.mjs +5 -7
- package/esm2020/lib/core/xps-boolean.enum.mjs +2 -0
- package/esm2020/lib/core-library.module.mjs +31 -4
- package/esm2020/lib/core-library.service.mjs +27 -5
- package/esm2020/public-api.mjs +2 -1
- package/fesm2015/xsolla-payment-client-core.mjs +1214 -11
- package/fesm2015/xsolla-payment-client-core.mjs.map +1 -1
- package/fesm2020/xsolla-payment-client-core.mjs +1165 -11
- package/fesm2020/xsolla-payment-client-core.mjs.map +1 -1
- package/lib/core/device-finger-print/device-finger-print-components.interface.d.ts +4 -0
- package/lib/core/device-finger-print/device-finger-print.service.d.ts +44 -0
- package/lib/core/device-finger-print/fingerprint-js.interface.d.ts +6 -0
- package/lib/core/device-finger-print/hash.type.d.ts +3 -0
- package/lib/core/exceptions-handling/errors/default-terminal-error.class.d.ts +4 -0
- package/lib/core/exceptions-handling/errors/terminal-error.class.d.ts +5 -0
- package/lib/core/exceptions-handling/errors/token-error.class.d.ts +4 -0
- package/lib/core/legal/disclaimer.service.d.ts +6 -0
- package/lib/core/legal/legal.component.config.d.ts +10 -0
- package/lib/core/legal/legal.service.d.ts +18 -0
- package/lib/core/legal/refund-policy.service.d.ts +11 -0
- package/lib/core/legal/secure-connection.service.d.ts +13 -0
- package/lib/core/payment/actions/action-factory-value.interface.d.ts +5 -0
- package/lib/core/payment/actions/action-type-command.map.d.ts +4 -0
- package/lib/core/payment/actions/action.interface.d.ts +4 -0
- package/lib/core/payment/actions/check-status/check-status.action.type.d.ts +12 -0
- package/lib/core/payment/actions/next-action.interface.d.ts +3 -0
- package/lib/core/payment/actions/next-action.service.d.ts +16 -0
- package/lib/core/payment/actions/next-actions.d.ts +5 -0
- package/lib/core/payment/actions/show-fields/show-fields.action.class.d.ts +8 -0
- package/lib/core/payment/actions/show-fields/show-fields.action.token.d.ts +4 -0
- package/lib/core/payment/actions/show-fields/show-fields.action.type.d.ts +12 -0
- package/lib/core/payment/checkout-item.interface.d.ts +11 -0
- package/lib/core/payment/field-names.enum.d.ts +62 -0
- package/lib/core/payment/field.interface.d.ts +26 -0
- package/lib/core/payment/finance-details.interface.d.ts +2 -0
- package/lib/core/payment/form/common-control-config.interface.d.ts +9 -0
- package/lib/core/payment/form/controls/control-config.d.ts +9 -0
- package/lib/core/payment/form/controls/control-config.service.d.ts +15 -0
- package/lib/core/payment/form/controls/control-type.type.d.ts +1 -0
- package/lib/core/payment/form/controls/text-control.config.d.ts +11 -0
- package/lib/core/payment/form/converters/converter.abstract.d.ts +23 -0
- package/lib/core/payment/form/converters/converters-map.d.ts +4 -0
- package/lib/core/payment/form/converters/converters-map.interface.d.ts +5 -0
- package/lib/core/payment/form/converters/email.converter.d.ts +14 -0
- package/lib/core/payment/form/converters/zip.converter.d.ts +21 -0
- package/lib/core/payment/form/form-state.interface.d.ts +3 -0
- package/lib/core/payment/form/form.module.d.ts +7 -0
- package/lib/core/payment/form/form.service.d.ts +12 -0
- package/lib/core/payment/form/validators/convert.function.d.ts +3 -0
- package/lib/core/payment/form/validators/email-validator.d.ts +2 -0
- package/lib/core/payment/form/validators/required-validator.d.ts +2 -0
- package/lib/core/payment/form/validators/restricted-value.validator.d.ts +2 -0
- package/lib/core/payment/form/validators/validation-error.interface.d.ts +4 -0
- package/lib/core/payment/form/validators/validation-errors.interface.d.ts +4 -0
- package/lib/core/payment/form/validators/validator-fn.type.d.ts +3 -0
- package/lib/core/payment/initialize/initialize-request-params.interface.d.ts +6 -0
- package/lib/core/payment/initialize/initialize-response.class.d.ts +7 -0
- package/lib/core/payment/initialize/initialize-response.token.d.ts +6 -0
- package/lib/core/payment/initialize/initialize.service.d.ts +18 -0
- package/lib/core/payment/invoice.interface.d.ts +14 -0
- package/lib/core/payment/payment-config.interface.d.ts +5 -0
- package/lib/core/payment/payment-form.interface.d.ts +39 -0
- package/lib/core/payment/payment.interface.d.ts +15 -0
- package/lib/core/payment/payment.service.d.ts +33 -0
- package/lib/core/payment/status/finance-info-field.interface.d.ts +5 -0
- package/lib/core/payment/status/line-item.interface.d.ts +8 -0
- package/lib/core/payment/status/status.enum.d.ts +10 -0
- package/lib/core/payment/status/status.interface.d.ts +63 -0
- package/lib/core/payment/status/title-class.enum.d.ts +5 -0
- package/lib/core/payment/status/web-socket-client-type.enum.d.ts +4 -0
- package/lib/core/payment/submit/request/submit-request.class.d.ts +13 -0
- package/lib/core/payment/submit/request/submit-request.token.d.ts +6 -0
- package/lib/core/payment/submit/response/submit-response.class.d.ts +26 -0
- package/lib/core/payment/submit/response/submit-response.token.d.ts +6 -0
- package/lib/core/payment/submit/submit.service.d.ts +21 -0
- package/lib/core/payment/sync/field-sync-state.interface.d.ts +5 -0
- package/lib/core/payment/sync/sync-request.class.d.ts +15 -0
- package/lib/core/payment/sync/sync-request.token.d.ts +6 -0
- package/lib/core/payment/sync/sync-response.class.d.ts +11 -0
- package/lib/core/payment/sync/sync-response.token.d.ts +6 -0
- package/lib/core/payment/sync/sync.service.d.ts +27 -0
- package/lib/core/payment/virtual-currency.interface.d.ts +10 -0
- package/lib/core/payment/xps-api-part-request.abstract.d.ts +6 -0
- package/lib/core/payment/xps-comand.enum.d.ts +8 -0
- package/lib/core/payment/xps-error.interface.d.ts +7 -0
- package/lib/core/payment/xps-message.interface.d.ts +4 -0
- package/lib/core/payment/xps-request.abstract.d.ts +6 -0
- package/lib/core/payment/xps-response.interface.d.ts +261 -0
- package/lib/core/payment/xps-subscription-item.interface.d.ts +20 -0
- package/lib/core/saved-methods/saved-methods.service.d.ts +1 -3
- package/lib/core/xps-boolean.enum.d.ts +4 -0
- package/lib/core-library.module.d.ts +2 -1
- package/lib/core-library.service.d.ts +12 -1
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/xsolla-payment-client-core-0.0.5.tgz +0 -0
- package/xsolla-payment-client-core-0.0.3.tgz +0 -0
|
@@ -3,6 +3,7 @@ import { InjectionToken, Injectable, Inject, NgModule } from '@angular/core';
|
|
|
3
3
|
import { firstValueFrom, lastValueFrom, map, 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 { UntypedFormGroup, Validators, UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
|
|
6
7
|
import { catchError } from 'rxjs/operators';
|
|
7
8
|
import * as i1$1 from '@angular/router';
|
|
8
9
|
|
|
@@ -299,10 +300,9 @@ const savedMethodsResponseFactoryProvider = {
|
|
|
299
300
|
};
|
|
300
301
|
|
|
301
302
|
class SavedMethodsService {
|
|
302
|
-
constructor(responseFactory, settingsService,
|
|
303
|
+
constructor(responseFactory, settingsService, secureApi) {
|
|
303
304
|
this.responseFactory = responseFactory;
|
|
304
305
|
this.settingsService = settingsService;
|
|
305
|
-
this.countryService = countryService;
|
|
306
306
|
this.secureApi = secureApi;
|
|
307
307
|
this.apiRoute = 'savedmethods';
|
|
308
308
|
this.cache = new Map();
|
|
@@ -330,7 +330,7 @@ class SavedMethodsService {
|
|
|
330
330
|
return this.cache.get(cacheKey);
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
|
-
SavedMethodsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SavedMethodsService, deps: [{ token: savedMethodsResponseFactoryToken }, { token: SettingsService }, { token:
|
|
333
|
+
SavedMethodsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SavedMethodsService, deps: [{ token: savedMethodsResponseFactoryToken }, { token: SettingsService }, { token: SecureApiClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
334
334
|
SavedMethodsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SavedMethodsService, providedIn: 'root' });
|
|
335
335
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SavedMethodsService, decorators: [{
|
|
336
336
|
type: Injectable,
|
|
@@ -340,7 +340,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
340
340
|
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
341
341
|
type: Inject,
|
|
342
342
|
args: [savedMethodsResponseFactoryToken]
|
|
343
|
-
}] }, { type: SettingsService }, { type:
|
|
343
|
+
}] }, { type: SettingsService }, { type: SecureApiClient }]; } });
|
|
344
344
|
|
|
345
345
|
class UserBalanceResponse {
|
|
346
346
|
constructor(userBalance) {
|
|
@@ -398,13 +398,1106 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
398
398
|
args: [userBalanceResponseFactoryToken]
|
|
399
399
|
}] }, { type: SettingsService }, { type: SecureApiClient }]; } });
|
|
400
400
|
|
|
401
|
+
class InitializeResponse {
|
|
402
|
+
constructor(response) {
|
|
403
|
+
this.paymentForm = null;
|
|
404
|
+
this.paymentForm = this.extractPaymentForm(response);
|
|
405
|
+
}
|
|
406
|
+
extractPaymentForm(response) {
|
|
407
|
+
if (!response) {
|
|
408
|
+
return null;
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
totalAmount: response.buyData.sum,
|
|
412
|
+
currency: response.buyData.currency,
|
|
413
|
+
fields: Object.keys(response.form).map((key) => response.form[key]),
|
|
414
|
+
taxDisclaimer: response.taxDisclaimer,
|
|
415
|
+
number: response.number,
|
|
416
|
+
barcode: response.barcode,
|
|
417
|
+
instruction: response.instruction,
|
|
418
|
+
offers: response.offers,
|
|
419
|
+
error: response.error,
|
|
420
|
+
errors: response.errors,
|
|
421
|
+
restrictions: response.restrictions,
|
|
422
|
+
info: response.info,
|
|
423
|
+
buyData: response.buyData,
|
|
424
|
+
pid: response.pid,
|
|
425
|
+
messages: response.messages ?? [],
|
|
426
|
+
title: response.title,
|
|
427
|
+
summary: response.summary,
|
|
428
|
+
skipForm: response.skipForm,
|
|
429
|
+
isSavedMethodPayment: !!response.form?.saved_method_id,
|
|
430
|
+
couponCode: response.form?.couponCode?.value || '',
|
|
431
|
+
publicId: response.public_id,
|
|
432
|
+
skipCheckout: response.skipCheckout,
|
|
433
|
+
koreaNotification: response.form.korea_limits_instruction,
|
|
434
|
+
isCheckout: response.isCheckout,
|
|
435
|
+
categories: response.categories,
|
|
436
|
+
hasFatalErrors: response.textAll?.fatal,
|
|
437
|
+
userSession: response.userSession,
|
|
438
|
+
statusText: response.status?.statusData?.stateText ?? null,
|
|
439
|
+
country: response.country ? response.country.iso : null,
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const initializeResponseFactoryToken = new InjectionToken('InitializeResponse');
|
|
445
|
+
const initializeResponseFactoryProvider = {
|
|
446
|
+
provide: initializeResponseFactoryToken,
|
|
447
|
+
useValue: (...args) => new InitializeResponse(...args),
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
class InitializeService {
|
|
451
|
+
constructor(responseFactory, secureApi, settingsService, countryService) {
|
|
452
|
+
this.responseFactory = responseFactory;
|
|
453
|
+
this.secureApi = secureApi;
|
|
454
|
+
this.settingsService = settingsService;
|
|
455
|
+
this.countryService = countryService;
|
|
456
|
+
this.apiRoute = 'directpayment';
|
|
457
|
+
}
|
|
458
|
+
async request(config) {
|
|
459
|
+
const requestParams = {
|
|
460
|
+
access_token: this.settingsService.token,
|
|
461
|
+
pid: String(config.paymentMethodId),
|
|
462
|
+
country: this.countryService.getCountry(),
|
|
463
|
+
returnUrl: config.returnUrl,
|
|
464
|
+
};
|
|
465
|
+
return lastValueFrom(this.secureApi
|
|
466
|
+
.post(this.apiRoute, new URLSearchParams({ ...requestParams }), {
|
|
467
|
+
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
|
|
468
|
+
responseType: 'json',
|
|
469
|
+
})
|
|
470
|
+
.pipe(map((response) => this.responseFactory(response)))).catch((error) => {
|
|
471
|
+
throw new ResponseError(error.message);
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
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 });
|
|
476
|
+
InitializeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, providedIn: 'root' });
|
|
477
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: InitializeService, decorators: [{
|
|
478
|
+
type: Injectable,
|
|
479
|
+
args: [{
|
|
480
|
+
providedIn: 'root',
|
|
481
|
+
}]
|
|
482
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
483
|
+
type: Inject,
|
|
484
|
+
args: [initializeResponseFactoryToken]
|
|
485
|
+
}] }, { type: SecureApiClient }, { type: SettingsService }, { type: CountryService }]; } });
|
|
486
|
+
|
|
487
|
+
class XpsApiPartRequest {
|
|
488
|
+
addXpsParameters(parameters) {
|
|
489
|
+
for (const key in parameters) {
|
|
490
|
+
this[`xps_${key}`] = parameters[key];
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
class TokenError extends AppError {
|
|
496
|
+
constructor() {
|
|
497
|
+
super('XPS API needs token.');
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
class SubmitRequest extends XpsApiPartRequest {
|
|
502
|
+
constructor(parameters) {
|
|
503
|
+
super();
|
|
504
|
+
const { token, dfpHash } = parameters;
|
|
505
|
+
if (token === null) {
|
|
506
|
+
throw new TokenError();
|
|
507
|
+
}
|
|
508
|
+
this.access_token = token;
|
|
509
|
+
if (dfpHash) {
|
|
510
|
+
this.xps_dfp_hash = dfpHash;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const submitRequestFactoryToken = new InjectionToken('SubmitRequest');
|
|
516
|
+
const submitRequestFactoryProvider = {
|
|
517
|
+
provide: submitRequestFactoryToken,
|
|
518
|
+
useValue: (...args) => new SubmitRequest(...args),
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
var XpsCommand;
|
|
522
|
+
(function (XpsCommand) {
|
|
523
|
+
XpsCommand["form"] = "form";
|
|
524
|
+
XpsCommand["check"] = "check";
|
|
525
|
+
XpsCommand["status"] = "status";
|
|
526
|
+
XpsCommand["checkout"] = "checkout";
|
|
527
|
+
XpsCommand["account"] = "account";
|
|
528
|
+
XpsCommand["create"] = "create";
|
|
529
|
+
})(XpsCommand || (XpsCommand = {}));
|
|
530
|
+
|
|
531
|
+
var FieldNames;
|
|
532
|
+
(function (FieldNames) {
|
|
533
|
+
FieldNames["address1"] = "address1";
|
|
534
|
+
FieldNames["address2"] = "address2";
|
|
535
|
+
FieldNames["address"] = "address";
|
|
536
|
+
FieldNames["allowRecurrentSubscription"] = "allowRecurrentSubscription";
|
|
537
|
+
FieldNames["allowSubscription"] = "allowSubscription";
|
|
538
|
+
FieldNames["apt"] = "apt";
|
|
539
|
+
FieldNames["availableCardTypes"] = "available_card_types";
|
|
540
|
+
FieldNames["bank"] = "bank";
|
|
541
|
+
FieldNames["birthDate"] = "birth_date";
|
|
542
|
+
FieldNames["cardMonth"] = "card_month";
|
|
543
|
+
FieldNames["cardYear"] = "card_year";
|
|
544
|
+
FieldNames["cardNumber"] = "card_number";
|
|
545
|
+
FieldNames["cardholdername"] = "cardholdername";
|
|
546
|
+
FieldNames["city"] = "city";
|
|
547
|
+
FieldNames["couponCode"] = "couponCode";
|
|
548
|
+
FieldNames["cpfName"] = "cpf_name";
|
|
549
|
+
FieldNames["cpfNumber"] = "cpf_number";
|
|
550
|
+
FieldNames["cvv"] = "cvv";
|
|
551
|
+
FieldNames["description"] = "description";
|
|
552
|
+
FieldNames["email"] = "email";
|
|
553
|
+
FieldNames["psEmail"] = "psEmail";
|
|
554
|
+
FieldNames["euCheck"] = "eu_check";
|
|
555
|
+
FieldNames["extraCvv"] = "extra_cvv";
|
|
556
|
+
FieldNames["extraCardNumber"] = "extra_card_number";
|
|
557
|
+
FieldNames["extraCardType"] = "extra_card_type";
|
|
558
|
+
FieldNames["fName"] = "f_name";
|
|
559
|
+
FieldNames["installments"] = "installments";
|
|
560
|
+
FieldNames["lName"] = "l_name";
|
|
561
|
+
FieldNames["needInstallments"] = "needInstallments";
|
|
562
|
+
FieldNames["personId"] = "person_id";
|
|
563
|
+
FieldNames["personIdAr"] = "person_id_ar";
|
|
564
|
+
FieldNames["personIdCo"] = "person_id_co";
|
|
565
|
+
FieldNames["phone"] = "phone";
|
|
566
|
+
FieldNames["purchaseDescription"] = "purchaseDescription";
|
|
567
|
+
FieldNames["recurrentType"] = "recurrent_type";
|
|
568
|
+
FieldNames["rockstarTaxes"] = "rockstar_taxes";
|
|
569
|
+
FieldNames["state"] = "state";
|
|
570
|
+
FieldNames["street"] = "street";
|
|
571
|
+
FieldNames["streetNumber"] = "street_number";
|
|
572
|
+
FieldNames["take2Taxes"] = "take2_taxes";
|
|
573
|
+
FieldNames["termsAndConditions"] = "termsAndConditions";
|
|
574
|
+
FieldNames["termsAndConditionsAtariPp"] = "termsAndConditionsAtariPP";
|
|
575
|
+
FieldNames["termsAndConditionsAtariTc"] = "termsAndConditionsAtariTC";
|
|
576
|
+
FieldNames["termsAndConditionsHtcEula"] = "termsAndConditionsHtcEula";
|
|
577
|
+
FieldNames["termsAndConditionsRobloxEula"] = "termsAndConditionsRobloxEula";
|
|
578
|
+
FieldNames["termsAndConditionsRolandEula"] = "termsAndConditionsRolandEula";
|
|
579
|
+
FieldNames["termsAndConditionsDeusLoVultEula"] = "termsAndConditionsDeusLoVultEula";
|
|
580
|
+
FieldNames["termsAndConditionsOnzenga"] = "termsAndConditionsOnzenga";
|
|
581
|
+
FieldNames["xsollaTipsAmount"] = "xsollaTipsAmount";
|
|
582
|
+
FieldNames["zip"] = "zip";
|
|
583
|
+
FieldNames["allowSave"] = "allowSave";
|
|
584
|
+
FieldNames["koreaLimitsInstruction"] = "korea_limits_instruction";
|
|
585
|
+
FieldNames["tokenApplePay"] = "token_applepay";
|
|
586
|
+
FieldNames["fixInvoice"] = "fix_invoice";
|
|
587
|
+
FieldNames["fixPid"] = "fix_pid";
|
|
588
|
+
FieldNames["signature"] = "signature";
|
|
589
|
+
FieldNames["qr"] = "qr";
|
|
590
|
+
FieldNames["sum"] = "sum";
|
|
591
|
+
FieldNames["out"] = "out";
|
|
592
|
+
FieldNames["tinkoffDisclaimer"] = "ps.tinkoff.disclaimer";
|
|
593
|
+
})(FieldNames || (FieldNames = {}));
|
|
594
|
+
|
|
595
|
+
class SubmitResponse {
|
|
596
|
+
constructor(parameters, responseNumber = 0) {
|
|
597
|
+
this.responseNumber = responseNumber;
|
|
598
|
+
/* Todo split into properties */
|
|
599
|
+
this.parameters = parameters;
|
|
600
|
+
this.fields = Object.keys(parameters.form).map((key) => parameters.form[key]);
|
|
601
|
+
if (parameters.onlineBanking) {
|
|
602
|
+
this.onlineBanking = {
|
|
603
|
+
url: parameters.onlineBanking.value,
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
this.isNeedRedirect =
|
|
607
|
+
parameters.currentCommand === XpsCommand.account ||
|
|
608
|
+
(parameters.currentCommand === XpsCommand.checkout &&
|
|
609
|
+
Boolean(parameters.checkout));
|
|
610
|
+
this.buyData = parameters.buyData;
|
|
611
|
+
this.fixInvoice = this.fields.find((field) => field.name === FieldNames.fixInvoice)?.value;
|
|
612
|
+
this.signature = this.fields.find((field) => field.name === FieldNames.signature)?.value;
|
|
613
|
+
this.hasFatalErrors = parameters.textAll?.fatal;
|
|
614
|
+
this.userSession = parameters.userSession;
|
|
615
|
+
this.pid = parameters.pid;
|
|
616
|
+
this.errors = parameters.errors;
|
|
617
|
+
this.summary = parameters.summary;
|
|
618
|
+
this.title = parameters.title;
|
|
619
|
+
this.currentCommand = parameters.currentCommand;
|
|
620
|
+
this.messages = parameters.messages;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
const submitResponseFactoryToken = new InjectionToken('SubmitResponse');
|
|
625
|
+
const submitResponseFactoryProvider = {
|
|
626
|
+
provide: submitResponseFactoryToken,
|
|
627
|
+
useValue: (...args) => new SubmitResponse(...args),
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
class TerminalError extends AppError {
|
|
631
|
+
constructor(message, code) {
|
|
632
|
+
super(message);
|
|
633
|
+
this.code = code;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
class DefaultTerminalError extends TerminalError {
|
|
638
|
+
constructor() {
|
|
639
|
+
const message = `It's not you, it's us, but we can help. Please contact our customer support.`;
|
|
640
|
+
super(message, '1000-0002');
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
class DeviceFingerPrintService {
|
|
645
|
+
constructor(secureApi, settingsService, window) {
|
|
646
|
+
this.secureApi = secureApi;
|
|
647
|
+
this.settingsService = settingsService;
|
|
648
|
+
this.window = window;
|
|
649
|
+
this.apiRoute = 'dfp';
|
|
650
|
+
this.fingerprintApiUrl = 'https://afs.xsolla.com/dfp/api/v1/';
|
|
651
|
+
}
|
|
652
|
+
async init() {
|
|
653
|
+
if (!this.settingsService.isInitialized) {
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
this.fingerprintJs = await this.loadFingerprintJs();
|
|
657
|
+
this.hash = await this.buildHash();
|
|
658
|
+
this.antifraudFingerprintLibrary =
|
|
659
|
+
await this.loadAntifraudFingerprintLibrary();
|
|
660
|
+
}
|
|
661
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
662
|
+
async getHash() {
|
|
663
|
+
return this.hash;
|
|
664
|
+
}
|
|
665
|
+
async loadFingerprintJs() {
|
|
666
|
+
const { default: library, murmurX64Hash128: getHash } = await import('@fingerprintjs/fingerprintjs');
|
|
667
|
+
return { library, getHash };
|
|
668
|
+
}
|
|
669
|
+
async loadAntifraudFingerprintLibrary() {
|
|
670
|
+
const library = await import('@xsolla/antifraud-fingerprint');
|
|
671
|
+
return library.default;
|
|
672
|
+
}
|
|
673
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
674
|
+
async makeAntifraudFingerprint() {
|
|
675
|
+
if (!this.settingsService.token) {
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
const antifraudFingerprint = this.antifraudFingerprintLibrary;
|
|
679
|
+
try {
|
|
680
|
+
return new antifraudFingerprint({
|
|
681
|
+
api: {
|
|
682
|
+
url: this.fingerprintApiUrl,
|
|
683
|
+
token: this.settingsService.token,
|
|
684
|
+
timeout: 3000,
|
|
685
|
+
},
|
|
686
|
+
retry: {
|
|
687
|
+
num: 1,
|
|
688
|
+
timeout: 500,
|
|
689
|
+
},
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
catch (error) {
|
|
693
|
+
return null;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
*Загружаем библиотеку, генерируем данные,
|
|
698
|
+
*хешируем с помощью BASE64 и отправляем на бэкенд,
|
|
699
|
+
*в ответ получаем dfp_hash.
|
|
700
|
+
**/
|
|
701
|
+
async buildHash() {
|
|
702
|
+
const fingerPrintData = await this.generate();
|
|
703
|
+
const hash = await this.send(fingerPrintData).catch(() => {
|
|
704
|
+
return null;
|
|
705
|
+
});
|
|
706
|
+
return JSON.stringify(hash);
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
*Новая версия библиотеки содержит не все компоненты, некоторые приходится имплементировать самостоятельно
|
|
710
|
+
**/
|
|
711
|
+
getHasLiedResolution() {
|
|
712
|
+
const { screen } = this.window;
|
|
713
|
+
return (screen.width < screen.availWidth || screen.height < screen.availHeight);
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
*Бэкенд заточен под конкретные поля, которые необходимо смапить.
|
|
717
|
+
**/
|
|
718
|
+
getComponents(components) {
|
|
719
|
+
return {
|
|
720
|
+
user_agent: navigator.userAgent,
|
|
721
|
+
language: components.languages.value?.shift()?.shift() ?? '',
|
|
722
|
+
color_depth: components.colorDepth.value,
|
|
723
|
+
device_memory: components.deviceMemory.value,
|
|
724
|
+
hardware_concurrency: components.hardwareConcurrency.value,
|
|
725
|
+
resolution: components.screenResolution.value,
|
|
726
|
+
available_resolution: components.screenResolution.value,
|
|
727
|
+
timezone_offset: new Date().getTimezoneOffset(),
|
|
728
|
+
session_storage: components.sessionStorage.value ? 1 : 0,
|
|
729
|
+
local_storage: components.localStorage.value ? 1 : 0,
|
|
730
|
+
indexed_db: components.indexedDB.value ? 1 : 0,
|
|
731
|
+
open_database: components.openDatabase.value ? 1 : 0,
|
|
732
|
+
navigator_platform: components.platform.value,
|
|
733
|
+
regular_plugins: components.plugins.value?.map((plugin) => plugin.name) ?? [],
|
|
734
|
+
canvas: components.canvas.value?.text,
|
|
735
|
+
webgl: components.canvas.value?.text,
|
|
736
|
+
webgl_vendor: components.vendor.value,
|
|
737
|
+
has_lied_resolution: this.getHasLiedResolution(),
|
|
738
|
+
touch_support: Object.values(components.touchSupport.value ?? {}),
|
|
739
|
+
js_fonts: components.fonts.value,
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Получаем данные dfp с помощью FingerprintJS, мапим необходимые поля, добавляем хэш
|
|
744
|
+
**/
|
|
745
|
+
async generate() {
|
|
746
|
+
const { library, getHash } = this.fingerprintJs;
|
|
747
|
+
const fingerprint = await library.load();
|
|
748
|
+
const commonFingerPrintData = await fingerprint.get();
|
|
749
|
+
const fingerPrintData = this.getComponents(commonFingerPrintData.components);
|
|
750
|
+
fingerPrintData.hash = getHash(JSON.stringify(fingerPrintData));
|
|
751
|
+
return fingerPrintData;
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Отправка dfp на сервер, в ответ получаем dfp_hash
|
|
755
|
+
**/
|
|
756
|
+
async send(fingerPrintData) {
|
|
757
|
+
const token = this.settingsService.token;
|
|
758
|
+
if (token === null) {
|
|
759
|
+
throw new DefaultTerminalError();
|
|
760
|
+
}
|
|
761
|
+
const requestBody = {
|
|
762
|
+
access_token: token,
|
|
763
|
+
'dfp[200]': '',
|
|
764
|
+
};
|
|
765
|
+
requestBody['dfp[200]'] = btoa(encodeURIComponent(JSON.stringify(fingerPrintData)));
|
|
766
|
+
return lastValueFrom(this.secureApi.post(this.apiRoute, new URLSearchParams(requestBody), {
|
|
767
|
+
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
|
|
768
|
+
responseType: 'json',
|
|
769
|
+
}))
|
|
770
|
+
.then((response) => {
|
|
771
|
+
return response.dfp_hash;
|
|
772
|
+
})
|
|
773
|
+
.then(async (hash) => {
|
|
774
|
+
const fingerprint = await this.makeAntifraudFingerprint();
|
|
775
|
+
if (!fingerprint) {
|
|
776
|
+
return null;
|
|
777
|
+
}
|
|
778
|
+
await fingerprint
|
|
779
|
+
?.dispatch(hash['200'])
|
|
780
|
+
.catch((err) => console.log(err));
|
|
781
|
+
const afsHash = await fingerprint.hash();
|
|
782
|
+
return { '301': afsHash, ...hash };
|
|
783
|
+
})
|
|
784
|
+
.catch((error) => {
|
|
785
|
+
const response = error.getHttpErrorData().response;
|
|
786
|
+
throw new TerminalError(response.data?.errors[0]?.message ?? '', response.data?.errors[0]?.support_code ?? '');
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
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 });
|
|
791
|
+
DeviceFingerPrintService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, providedIn: 'root' });
|
|
792
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DeviceFingerPrintService, decorators: [{
|
|
793
|
+
type: Injectable,
|
|
794
|
+
args: [{
|
|
795
|
+
providedIn: 'root',
|
|
796
|
+
}]
|
|
797
|
+
}], ctorParameters: function () { return [{ type: SecureApiClient }, { type: SettingsService }, { type: undefined, decorators: [{
|
|
798
|
+
type: Inject,
|
|
799
|
+
args: [windowToken]
|
|
800
|
+
}] }]; } });
|
|
801
|
+
|
|
802
|
+
class SubmitService {
|
|
803
|
+
constructor(requestFactory, responseFactory, settingsService, deviceFingerPrintService, secureApi) {
|
|
804
|
+
this.requestFactory = requestFactory;
|
|
805
|
+
this.responseFactory = responseFactory;
|
|
806
|
+
this.settingsService = settingsService;
|
|
807
|
+
this.deviceFingerPrintService = deviceFingerPrintService;
|
|
808
|
+
this.secureApi = secureApi;
|
|
809
|
+
this.directPaymentApiRoute = 'directpayment';
|
|
810
|
+
}
|
|
811
|
+
// NB: Never add 'async' statement for this method!
|
|
812
|
+
// 'Async' statement wraps current promise into another.
|
|
813
|
+
// In this way two promises become unequal, that can broke XPS API requests logic.
|
|
814
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
815
|
+
request(fields, form) {
|
|
816
|
+
const responsePromise = this.deviceFingerPrintService
|
|
817
|
+
.getHash()
|
|
818
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
819
|
+
.then((dfpHash) => {
|
|
820
|
+
const request = this.requestFactory({
|
|
821
|
+
token: this.settingsService.token,
|
|
822
|
+
fields,
|
|
823
|
+
form,
|
|
824
|
+
dfpHash,
|
|
825
|
+
});
|
|
826
|
+
return lastValueFrom(this.secureApi.post(this.directPaymentApiRoute, request, {
|
|
827
|
+
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
|
|
828
|
+
responseType: 'json',
|
|
829
|
+
}))
|
|
830
|
+
.then((response) => this.responseFactory(response))
|
|
831
|
+
.catch((error) => {
|
|
832
|
+
throw new ResponseError(error.message);
|
|
833
|
+
});
|
|
834
|
+
});
|
|
835
|
+
return responsePromise;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
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 });
|
|
839
|
+
SubmitService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, providedIn: 'root' });
|
|
840
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SubmitService, decorators: [{
|
|
841
|
+
type: Injectable,
|
|
842
|
+
args: [{ providedIn: 'root' }]
|
|
843
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
844
|
+
type: Inject,
|
|
845
|
+
args: [submitRequestFactoryToken]
|
|
846
|
+
}] }, { type: undefined, decorators: [{
|
|
847
|
+
type: Inject,
|
|
848
|
+
args: [submitResponseFactoryToken]
|
|
849
|
+
}] }, { type: SettingsService }, { type: DeviceFingerPrintService }, { type: SecureApiClient }]; } });
|
|
850
|
+
|
|
851
|
+
class XpsRequest {
|
|
852
|
+
addXpsParameters(parameters) {
|
|
853
|
+
for (const key in parameters) {
|
|
854
|
+
this[`xps_${key}`] = parameters[key];
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
860
|
+
class SyncRequest extends XpsRequest {
|
|
861
|
+
constructor(parameters) {
|
|
862
|
+
super();
|
|
863
|
+
this.xps_fix_command = 'calculate';
|
|
864
|
+
this.access_token = parameters.token;
|
|
865
|
+
const fieldsValues = this.getFieldsValues(parameters.changedField, parameters.fields, parameters.form);
|
|
866
|
+
this.addXpsParameters({
|
|
867
|
+
...fieldsValues,
|
|
868
|
+
change_element: parameters.changedField.name,
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
getFieldsValues(changedField, fields, form) {
|
|
872
|
+
const fieldsMap = this.getFieldsMap(fields);
|
|
873
|
+
return changedField?.javascript?.change.params.reduce((xpsParams, fieldName) => {
|
|
874
|
+
const formControl = form.get(fieldName);
|
|
875
|
+
const field = fieldsMap.get(fieldName);
|
|
876
|
+
if (formControl || field) {
|
|
877
|
+
xpsParams[fieldName] = formControl?.value ?? field?.value;
|
|
878
|
+
}
|
|
879
|
+
return xpsParams;
|
|
880
|
+
}, {});
|
|
881
|
+
}
|
|
882
|
+
getFieldsMap(fields) {
|
|
883
|
+
const map = new Map();
|
|
884
|
+
fields.forEach((field) => map.set(field.name, field));
|
|
885
|
+
return map;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
const syncRequestFactoryToken = new InjectionToken('SyncRequest');
|
|
890
|
+
const syncRequestFactoryProvider = {
|
|
891
|
+
provide: syncRequestFactoryToken,
|
|
892
|
+
useValue: (...args) => new SyncRequest(...args),
|
|
893
|
+
};
|
|
894
|
+
|
|
895
|
+
class SyncResponse {
|
|
896
|
+
constructor(changedField, response) {
|
|
897
|
+
const fieldError = response?.errors?.find((error) => error.element_name === changedField.name);
|
|
898
|
+
if (fieldError) {
|
|
899
|
+
this.rewritableError = {
|
|
900
|
+
code: fieldError.code,
|
|
901
|
+
message: fieldError.message,
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
this.fields = Object.keys(response.form).map((key) => response.form[key]);
|
|
905
|
+
this.parameters = response;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
const syncResponseFactoryToken = new InjectionToken('SyncResponse');
|
|
910
|
+
const syncResponseFactoryProvider = {
|
|
911
|
+
provide: syncResponseFactoryToken,
|
|
912
|
+
useValue: (...args) => new SyncResponse(...args),
|
|
913
|
+
};
|
|
914
|
+
|
|
915
|
+
class SyncService {
|
|
916
|
+
constructor(requestFactory, responseFactory, secureApi, settingsService) {
|
|
917
|
+
this.requestFactory = requestFactory;
|
|
918
|
+
this.responseFactory = responseFactory;
|
|
919
|
+
this.secureApi = secureApi;
|
|
920
|
+
this.settingsService = settingsService;
|
|
921
|
+
this.apiRoute = 'directpayment';
|
|
922
|
+
this.prevFieldSyncStates = {};
|
|
923
|
+
this.form = new UntypedFormGroup({});
|
|
924
|
+
this.fields = [];
|
|
925
|
+
}
|
|
926
|
+
setup(form, fields) {
|
|
927
|
+
this.reset();
|
|
928
|
+
this.form = form;
|
|
929
|
+
this.fields = fields;
|
|
930
|
+
}
|
|
931
|
+
reset() {
|
|
932
|
+
this.prevFieldSyncStates = {};
|
|
933
|
+
this.form = new UntypedFormGroup({});
|
|
934
|
+
this.fields = [];
|
|
935
|
+
}
|
|
936
|
+
async validate(field) {
|
|
937
|
+
if (!this.isReadyField(field)) {
|
|
938
|
+
return Promise.resolve(null);
|
|
939
|
+
}
|
|
940
|
+
const control = this.form.get(field.name);
|
|
941
|
+
const value = control?.value;
|
|
942
|
+
const prevFieldState = this.getPrevFieldSyncState(field);
|
|
943
|
+
const isInitialValue = value === field.value && !prevFieldState;
|
|
944
|
+
if (isInitialValue) {
|
|
945
|
+
return Promise.resolve(null);
|
|
946
|
+
}
|
|
947
|
+
if (prevFieldState && value === prevFieldState.value) {
|
|
948
|
+
return Promise.resolve(prevFieldState.result);
|
|
949
|
+
}
|
|
950
|
+
const requestPromise = this.request(field);
|
|
951
|
+
this.setPrevFieldSyncState(field, value, requestPromise);
|
|
952
|
+
return requestPromise.then((response) => {
|
|
953
|
+
return response.rewritableError ?? null;
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
async request(field) {
|
|
957
|
+
const requestParams = this.requestFactory({
|
|
958
|
+
token: this.settingsService.token,
|
|
959
|
+
changedField: field,
|
|
960
|
+
fields: this.fields,
|
|
961
|
+
form: this.form,
|
|
962
|
+
});
|
|
963
|
+
return lastValueFrom(this.secureApi.post(this.apiRoute, new URLSearchParams(requestParams), {
|
|
964
|
+
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'),
|
|
965
|
+
responseType: 'json',
|
|
966
|
+
})).then((response) => {
|
|
967
|
+
return this.responseFactory(field, response);
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
isReadyField(field) {
|
|
971
|
+
const isSyncEnabled = !!field.javascript?.change;
|
|
972
|
+
const isExistsInForm = !!this.form?.get(field.name);
|
|
973
|
+
return isSyncEnabled && isExistsInForm;
|
|
974
|
+
}
|
|
975
|
+
getPrevFieldSyncState(field) {
|
|
976
|
+
return this.prevFieldSyncStates[field.name];
|
|
977
|
+
}
|
|
978
|
+
setPrevFieldSyncState(field, value, result) {
|
|
979
|
+
this.prevFieldSyncStates[field.name] = { value, result };
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
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 });
|
|
983
|
+
SyncService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, providedIn: 'root' });
|
|
984
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SyncService, decorators: [{
|
|
985
|
+
type: Injectable,
|
|
986
|
+
args: [{
|
|
987
|
+
providedIn: 'root',
|
|
988
|
+
}]
|
|
989
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
990
|
+
type: Inject,
|
|
991
|
+
args: [syncRequestFactoryToken]
|
|
992
|
+
}] }, { type: undefined, decorators: [{
|
|
993
|
+
type: Inject,
|
|
994
|
+
args: [syncResponseFactoryToken]
|
|
995
|
+
}] }, { type: SecureApiClient }, { type: SettingsService }]; } });
|
|
996
|
+
|
|
997
|
+
class ControlConfig {
|
|
998
|
+
constructor() {
|
|
999
|
+
this.shouldHideUserInput = false;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
class TextControlConfig extends ControlConfig {
|
|
1004
|
+
constructor() {
|
|
1005
|
+
super(...arguments);
|
|
1006
|
+
this.controlType = 'text';
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
function convert(validator, message) {
|
|
1011
|
+
return (control) => {
|
|
1012
|
+
const errors = validator(control);
|
|
1013
|
+
if (!errors) {
|
|
1014
|
+
return errors;
|
|
1015
|
+
}
|
|
1016
|
+
const firstErrorKey = Object.keys(errors)[0];
|
|
1017
|
+
let error = errors[firstErrorKey];
|
|
1018
|
+
error = typeof error === 'object' && error !== null ? error : {};
|
|
1019
|
+
const rewritableError = { ...error };
|
|
1020
|
+
rewritableError.message = message;
|
|
1021
|
+
if (error[firstErrorKey] != null) {
|
|
1022
|
+
rewritableError.value = error[firstErrorKey];
|
|
1023
|
+
}
|
|
1024
|
+
if (rewritableError.requiredLength) {
|
|
1025
|
+
rewritableError.number = rewritableError.requiredLength;
|
|
1026
|
+
}
|
|
1027
|
+
errors.rewritableError = rewritableError;
|
|
1028
|
+
return errors;
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
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
|
|
1033
|
+
function emailValidator() {
|
|
1034
|
+
return convert(Validators.pattern(emailRegexp), 'Enter a valid email');
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
function requiredValidator() {
|
|
1038
|
+
return convert(Validators.required, 'Required');
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
class Converter {
|
|
1042
|
+
constructor(syncService) {
|
|
1043
|
+
this.syncService = syncService;
|
|
1044
|
+
}
|
|
1045
|
+
convertToConfig(field, formState) {
|
|
1046
|
+
const config = this.createControlConfig(field, formState);
|
|
1047
|
+
if (formState?.disabled) {
|
|
1048
|
+
config.disabled = true;
|
|
1049
|
+
}
|
|
1050
|
+
return config;
|
|
1051
|
+
}
|
|
1052
|
+
convertToFormControl(field) {
|
|
1053
|
+
return new UntypedFormControl(this.getValue(field), this.getValidators(field), this.getAsyncValidators(field));
|
|
1054
|
+
}
|
|
1055
|
+
getValidators(field) {
|
|
1056
|
+
const validators = [];
|
|
1057
|
+
if (field.isMandatory === "1" /* XpsBoolean.true */) {
|
|
1058
|
+
validators.push(requiredValidator());
|
|
1059
|
+
}
|
|
1060
|
+
if (field.regex) {
|
|
1061
|
+
const match = /^\/(.*)\/([gim]*)$/.exec(field.regex);
|
|
1062
|
+
if (match) {
|
|
1063
|
+
const pattern = new RegExp(match[1], match[2]);
|
|
1064
|
+
const errorMessage = field.validation_error_msg
|
|
1065
|
+
? field.validation_error_msg
|
|
1066
|
+
: 'Enter valid data';
|
|
1067
|
+
validators.push(convert(Validators.pattern(pattern), errorMessage));
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
return validators;
|
|
1071
|
+
}
|
|
1072
|
+
getAsyncValidators(field) {
|
|
1073
|
+
return async () => this.syncService.validate(field);
|
|
1074
|
+
}
|
|
1075
|
+
createDefaultControlConfig(controlConfigClass, field) {
|
|
1076
|
+
const config = new controlConfigClass();
|
|
1077
|
+
this.copyCommonOptions(config, field);
|
|
1078
|
+
return config;
|
|
1079
|
+
}
|
|
1080
|
+
getValue(field) {
|
|
1081
|
+
return field.value;
|
|
1082
|
+
}
|
|
1083
|
+
getDataType() {
|
|
1084
|
+
return 'text';
|
|
1085
|
+
}
|
|
1086
|
+
getAutocomplete() {
|
|
1087
|
+
return 'off';
|
|
1088
|
+
}
|
|
1089
|
+
shouldHideUserInput() {
|
|
1090
|
+
return false;
|
|
1091
|
+
}
|
|
1092
|
+
getCommonControlConfig(field) {
|
|
1093
|
+
return {
|
|
1094
|
+
name: field.name,
|
|
1095
|
+
title: field.title,
|
|
1096
|
+
labelHint: field.label_hint,
|
|
1097
|
+
dataType: this.getDataType(),
|
|
1098
|
+
readonly: field.isReadonly === "1" /* XpsBoolean.true */,
|
|
1099
|
+
placeholder: field.example,
|
|
1100
|
+
autocomplete: this.getAutocomplete(),
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
copyCommonOptions(target, field) {
|
|
1104
|
+
const commonControlConfig = this.getCommonControlConfig(field);
|
|
1105
|
+
Object.keys(commonControlConfig).forEach((sourceKey) => {
|
|
1106
|
+
if (!(sourceKey in target)) {
|
|
1107
|
+
target[sourceKey] = commonControlConfig[sourceKey];
|
|
1108
|
+
}
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
class EmailConverter extends Converter {
|
|
1114
|
+
constructor(syncService) {
|
|
1115
|
+
super(syncService);
|
|
1116
|
+
}
|
|
1117
|
+
getValidators(field) {
|
|
1118
|
+
return super.getValidators(field).concat([emailValidator()]);
|
|
1119
|
+
}
|
|
1120
|
+
createControlConfig(field) {
|
|
1121
|
+
const config = this.createDefaultControlConfig(TextControlConfig, field);
|
|
1122
|
+
config.autocomplete = 'email';
|
|
1123
|
+
config.icon = 'mail';
|
|
1124
|
+
return config;
|
|
1125
|
+
}
|
|
1126
|
+
getDataType() {
|
|
1127
|
+
return 'email';
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
EmailConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter, deps: [{ token: SyncService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1131
|
+
EmailConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter });
|
|
1132
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: EmailConverter, decorators: [{
|
|
1133
|
+
type: Injectable
|
|
1134
|
+
}], ctorParameters: function () { return [{ type: SyncService }]; } });
|
|
1135
|
+
|
|
1136
|
+
const restrictedValueValidator = (restrictedValue) => {
|
|
1137
|
+
return ({ value }) => {
|
|
1138
|
+
return value !== restrictedValue ? null : { valueAllowed: false };
|
|
1139
|
+
};
|
|
1140
|
+
};
|
|
1141
|
+
|
|
1142
|
+
class ZipConverter extends Converter {
|
|
1143
|
+
constructor(syncService, countryService) {
|
|
1144
|
+
super(syncService);
|
|
1145
|
+
this.countryService = countryService;
|
|
1146
|
+
this.minLength = 3;
|
|
1147
|
+
this.maxLength = 10;
|
|
1148
|
+
this.usCountryLength = 5;
|
|
1149
|
+
}
|
|
1150
|
+
get isUsCountry() {
|
|
1151
|
+
return this.countryService.getCountry() === 'US';
|
|
1152
|
+
}
|
|
1153
|
+
getValidators(field) {
|
|
1154
|
+
const minLength = this.isUsCountry ? this.usCountryLength : this.minLength;
|
|
1155
|
+
const maxLength = this.isUsCountry ? this.usCountryLength : this.maxLength;
|
|
1156
|
+
const validators = super
|
|
1157
|
+
.getValidators(field)
|
|
1158
|
+
.concat([
|
|
1159
|
+
convert(Validators.minLength(minLength), 'Enter at least ${minLength} characters'),
|
|
1160
|
+
convert(Validators.maxLength(maxLength), 'Enter no more than ${maxLength} characters'),
|
|
1161
|
+
]);
|
|
1162
|
+
if (this.isUsCountry) {
|
|
1163
|
+
validators.push(convert(restrictedValueValidator('00000'), 'Enter a valid ZIP code'));
|
|
1164
|
+
}
|
|
1165
|
+
return validators;
|
|
1166
|
+
}
|
|
1167
|
+
createControlConfig(field) {
|
|
1168
|
+
const config = this.createDefaultControlConfig(TextControlConfig, field);
|
|
1169
|
+
config.icon = 'location';
|
|
1170
|
+
if (this.isUsCountry) {
|
|
1171
|
+
config.maskConfig = {
|
|
1172
|
+
mask: () => new Array(this.usCountryLength).fill('9').join(''),
|
|
1173
|
+
guide: false,
|
|
1174
|
+
unmaskModelValue: true,
|
|
1175
|
+
showMask: true,
|
|
1176
|
+
};
|
|
1177
|
+
config.inputMode = 'numeric';
|
|
1178
|
+
}
|
|
1179
|
+
else {
|
|
1180
|
+
config.maxLength = this.maxLength;
|
|
1181
|
+
}
|
|
1182
|
+
return config;
|
|
1183
|
+
}
|
|
1184
|
+
getAutocomplete() {
|
|
1185
|
+
return 'postal-code';
|
|
1186
|
+
}
|
|
1187
|
+
getDataType() {
|
|
1188
|
+
return 'text';
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
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 });
|
|
1192
|
+
ZipConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ZipConverter });
|
|
1193
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ZipConverter, decorators: [{
|
|
1194
|
+
type: Injectable
|
|
1195
|
+
}], ctorParameters: function () { return [{ type: SyncService }, { type: CountryService }]; } });
|
|
1196
|
+
|
|
1197
|
+
const convertersMapToken = new InjectionToken('ConvertersTokensMap');
|
|
1198
|
+
const convertersMap = {
|
|
1199
|
+
zip: ZipConverter,
|
|
1200
|
+
email: EmailConverter,
|
|
1201
|
+
};
|
|
1202
|
+
|
|
1203
|
+
class ControlConfigService {
|
|
1204
|
+
constructor(convertersMap, injector) {
|
|
1205
|
+
this.convertersMap = convertersMap;
|
|
1206
|
+
this.injector = injector;
|
|
1207
|
+
}
|
|
1208
|
+
getFormControl(field) {
|
|
1209
|
+
const converter = this.getConverter(field);
|
|
1210
|
+
if (!converter) {
|
|
1211
|
+
return null;
|
|
1212
|
+
}
|
|
1213
|
+
return converter.convertToFormControl(field);
|
|
1214
|
+
}
|
|
1215
|
+
getConverter(field) {
|
|
1216
|
+
if (!field) {
|
|
1217
|
+
return null;
|
|
1218
|
+
}
|
|
1219
|
+
const sanitizedName = field.name.replace(/^fix_/i, '');
|
|
1220
|
+
let converter = this.convertersMap[sanitizedName];
|
|
1221
|
+
if (!converter) {
|
|
1222
|
+
converter = this.convertersMap[field.type];
|
|
1223
|
+
}
|
|
1224
|
+
if (!converter) {
|
|
1225
|
+
return null;
|
|
1226
|
+
}
|
|
1227
|
+
return this.injector.get(converter);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
ControlConfigService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ControlConfigService, deps: [{ token: convertersMapToken }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1231
|
+
ControlConfigService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ControlConfigService });
|
|
1232
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: ControlConfigService, decorators: [{
|
|
1233
|
+
type: Injectable
|
|
1234
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
1235
|
+
type: Inject,
|
|
1236
|
+
args: [convertersMapToken]
|
|
1237
|
+
}] }, { type: i0.Injector }]; } });
|
|
1238
|
+
|
|
1239
|
+
class FormService {
|
|
1240
|
+
constructor(controlConfigService) {
|
|
1241
|
+
this.controlConfigService = controlConfigService;
|
|
1242
|
+
}
|
|
1243
|
+
createForm(fields) {
|
|
1244
|
+
const controls = this.getVisibleFields(fields).reduce((result, field) => {
|
|
1245
|
+
const formControl = this.controlConfigService.getFormControl(field);
|
|
1246
|
+
if (formControl) {
|
|
1247
|
+
result[field.name] = formControl;
|
|
1248
|
+
}
|
|
1249
|
+
return result;
|
|
1250
|
+
}, {});
|
|
1251
|
+
return new UntypedFormGroup(controls);
|
|
1252
|
+
}
|
|
1253
|
+
getVisibleFields(fields) {
|
|
1254
|
+
return fields.filter(({ isVisible }) => isVisible === "1" /* XpsBoolean.true */);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
FormService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: FormService, deps: [{ token: ControlConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1258
|
+
FormService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: FormService });
|
|
1259
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: FormService, decorators: [{
|
|
1260
|
+
type: Injectable
|
|
1261
|
+
}], ctorParameters: function () { return [{ type: ControlConfigService }]; } });
|
|
1262
|
+
|
|
1263
|
+
class ShowFieldsAction {
|
|
1264
|
+
constructor(submitResponse) {
|
|
1265
|
+
this.type = 'show_fields';
|
|
1266
|
+
this.data = {
|
|
1267
|
+
fields: [],
|
|
1268
|
+
errors: [],
|
|
1269
|
+
messages: [],
|
|
1270
|
+
order: {},
|
|
1271
|
+
};
|
|
1272
|
+
this.data.fields = submitResponse.fields;
|
|
1273
|
+
this.data.errors = submitResponse.errors;
|
|
1274
|
+
this.data.messages = submitResponse.messages;
|
|
1275
|
+
this.data.order = submitResponse.summary;
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
const showFieldsActionFactoryToken = new InjectionToken('ShowFieldsAction');
|
|
1280
|
+
const showFieldsActionFactoryProvider = {
|
|
1281
|
+
provide: showFieldsActionFactoryToken,
|
|
1282
|
+
useValue: {
|
|
1283
|
+
factory: (...args) => new ShowFieldsAction(...args),
|
|
1284
|
+
type: 'show_fields',
|
|
1285
|
+
},
|
|
1286
|
+
};
|
|
1287
|
+
|
|
1288
|
+
const nextActionsToken = new InjectionToken('Action');
|
|
1289
|
+
const nextActions = [showFieldsActionFactoryProvider];
|
|
1290
|
+
|
|
1291
|
+
const actionTypeCommandMap = {
|
|
1292
|
+
[XpsCommand.check]: 'show_fields',
|
|
1293
|
+
};
|
|
1294
|
+
|
|
1295
|
+
class NextActionService {
|
|
1296
|
+
constructor(nextActionTokens, injector) {
|
|
1297
|
+
this.nextActionTokens = nextActionTokens;
|
|
1298
|
+
this.injector = injector;
|
|
1299
|
+
this.nextActionsMap = new Map();
|
|
1300
|
+
this.fillNextActionsMap();
|
|
1301
|
+
}
|
|
1302
|
+
getNextAction(submitResponse) {
|
|
1303
|
+
if (!submitResponse.currentCommand) {
|
|
1304
|
+
return null;
|
|
1305
|
+
}
|
|
1306
|
+
const nextActionFactory = this.findNextAction(submitResponse.currentCommand);
|
|
1307
|
+
if (nextActionFactory) {
|
|
1308
|
+
return nextActionFactory(submitResponse);
|
|
1309
|
+
}
|
|
1310
|
+
throw new Error('Next action is undefined.');
|
|
1311
|
+
}
|
|
1312
|
+
fillNextActionsMap() {
|
|
1313
|
+
this.nextActionTokens.forEach((nextAction) => {
|
|
1314
|
+
const item = this.injector.get(nextAction.provide);
|
|
1315
|
+
this.nextActionsMap.set(item.type, item.factory);
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
findNextAction(command) {
|
|
1319
|
+
const actionType = actionTypeCommandMap[command];
|
|
1320
|
+
if (!actionType) {
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1323
|
+
return this.nextActionsMap.get(actionType);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
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 });
|
|
1327
|
+
NextActionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NextActionService, providedIn: 'root' });
|
|
1328
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: NextActionService, decorators: [{
|
|
1329
|
+
type: Injectable,
|
|
1330
|
+
args: [{
|
|
1331
|
+
providedIn: 'root',
|
|
1332
|
+
}]
|
|
1333
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
1334
|
+
type: Inject,
|
|
1335
|
+
args: [nextActionsToken]
|
|
1336
|
+
}] }, { type: i0.Injector }]; } });
|
|
1337
|
+
|
|
1338
|
+
class PaymentService {
|
|
1339
|
+
constructor(initializeService, submitService, syncService, formService, nextActionService) {
|
|
1340
|
+
this.initializeService = initializeService;
|
|
1341
|
+
this.submitService = submitService;
|
|
1342
|
+
this.syncService = syncService;
|
|
1343
|
+
this.formService = formService;
|
|
1344
|
+
this.nextActionService = nextActionService;
|
|
1345
|
+
this.form = null;
|
|
1346
|
+
this.data = null;
|
|
1347
|
+
this.fields = [];
|
|
1348
|
+
}
|
|
1349
|
+
async initialize(config) {
|
|
1350
|
+
this.data = await this.initializeService.request(config);
|
|
1351
|
+
this.fields = this.getFields();
|
|
1352
|
+
this.form = this.formService.createForm(this.fields);
|
|
1353
|
+
this.syncService.setup(this.form, this.fields);
|
|
1354
|
+
return this.fields;
|
|
1355
|
+
}
|
|
1356
|
+
async submit(fields, form) {
|
|
1357
|
+
const submitResponse = await this.submitService.request(fields, form);
|
|
1358
|
+
return this.nextActionService.getNextAction(submitResponse);
|
|
1359
|
+
}
|
|
1360
|
+
getFields() {
|
|
1361
|
+
return this.data?.paymentForm?.fields ?? [];
|
|
1362
|
+
}
|
|
1363
|
+
async validate(field) {
|
|
1364
|
+
return this.syncService.validate(field);
|
|
1365
|
+
}
|
|
1366
|
+
runThreeDs() {
|
|
1367
|
+
throw new Error('Method not implemented.');
|
|
1368
|
+
}
|
|
1369
|
+
getFinanceDetails() {
|
|
1370
|
+
throw new Error('Method not implemented.');
|
|
1371
|
+
}
|
|
1372
|
+
getStatus() {
|
|
1373
|
+
throw new Error('Method not implemented.');
|
|
1374
|
+
}
|
|
1375
|
+
changeFieldValue(name, value) {
|
|
1376
|
+
const formControl = this.form?.get(name);
|
|
1377
|
+
formControl?.setValue(value);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
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: NextActionService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1381
|
+
PaymentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, providedIn: 'root' });
|
|
1382
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: PaymentService, decorators: [{
|
|
1383
|
+
type: Injectable,
|
|
1384
|
+
args: [{
|
|
1385
|
+
providedIn: 'root',
|
|
1386
|
+
}]
|
|
1387
|
+
}], ctorParameters: function () { return [{ type: InitializeService }, { type: SubmitService }, { type: SyncService }, { type: FormService }, { type: NextActionService }]; } });
|
|
1388
|
+
|
|
1389
|
+
class RefundPolicyService {
|
|
1390
|
+
constructor(settingsService) {
|
|
1391
|
+
this.settingsService = settingsService;
|
|
1392
|
+
this.defaultVersionId = 2;
|
|
1393
|
+
this.defaultUrl = 'https://xsolla.com/refund-policy-ps';
|
|
1394
|
+
}
|
|
1395
|
+
get url() {
|
|
1396
|
+
if (!this.settingsService.token) {
|
|
1397
|
+
return 'https://xsolla.com/refundpolicy/en-us';
|
|
1398
|
+
}
|
|
1399
|
+
const language = this.settingsService.user.local ?? 'en';
|
|
1400
|
+
const versionId = this.settingsService.project.refundPolicySettings?.policy_version_id ??
|
|
1401
|
+
this.defaultVersionId;
|
|
1402
|
+
const countryIso = this.settingsService.user.country.value ?? '';
|
|
1403
|
+
const projectId = this.settingsService.project.id;
|
|
1404
|
+
return `${this.defaultUrl}?policy_version_id=${versionId}&language=${language}&country=${countryIso}&project_id=${projectId}`;
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
RefundPolicyService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: RefundPolicyService, deps: [{ token: SettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1408
|
+
RefundPolicyService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: RefundPolicyService, providedIn: 'root' });
|
|
1409
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: RefundPolicyService, decorators: [{
|
|
1410
|
+
type: Injectable,
|
|
1411
|
+
args: [{
|
|
1412
|
+
providedIn: 'root',
|
|
1413
|
+
}]
|
|
1414
|
+
}], ctorParameters: function () { return [{ type: SettingsService }]; } });
|
|
1415
|
+
|
|
1416
|
+
class SecureConnectionService {
|
|
1417
|
+
get isWhiteLabel() {
|
|
1418
|
+
return !!this.settingsService.settings?.white_label;
|
|
1419
|
+
}
|
|
1420
|
+
get secureConnectionUrl() {
|
|
1421
|
+
this.setSecureConnectionUrl();
|
|
1422
|
+
return this._secureConnectionUrl;
|
|
1423
|
+
}
|
|
1424
|
+
constructor(settingsService) {
|
|
1425
|
+
this.settingsService = settingsService;
|
|
1426
|
+
this.secureConnectionApi = 'https://verify.xsolla.com/?url=';
|
|
1427
|
+
}
|
|
1428
|
+
setSecureConnectionUrl() {
|
|
1429
|
+
const projectUrl = this.settingsService.project?.projectUrl;
|
|
1430
|
+
if (projectUrl) {
|
|
1431
|
+
this._secureConnectionUrl = `${this.secureConnectionApi}${encodeURIComponent(projectUrl)}`;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
SecureConnectionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SecureConnectionService, deps: [{ token: SettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1436
|
+
SecureConnectionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SecureConnectionService, providedIn: 'root' });
|
|
1437
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: SecureConnectionService, decorators: [{
|
|
1438
|
+
type: Injectable,
|
|
1439
|
+
args: [{
|
|
1440
|
+
providedIn: 'root',
|
|
1441
|
+
}]
|
|
1442
|
+
}], ctorParameters: function () { return [{ type: SettingsService }]; } });
|
|
1443
|
+
|
|
1444
|
+
class DisclaimerService {
|
|
1445
|
+
constructor() {
|
|
1446
|
+
this.disclaimer = 'disclaimer';
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
DisclaimerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DisclaimerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1450
|
+
DisclaimerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DisclaimerService, providedIn: 'root' });
|
|
1451
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: DisclaimerService, decorators: [{
|
|
1452
|
+
type: Injectable,
|
|
1453
|
+
args: [{
|
|
1454
|
+
providedIn: 'root',
|
|
1455
|
+
}]
|
|
1456
|
+
}] });
|
|
1457
|
+
|
|
1458
|
+
class LegalService {
|
|
1459
|
+
get isJapanUser() {
|
|
1460
|
+
return this.settingsService.user?.local === 'ja';
|
|
1461
|
+
}
|
|
1462
|
+
constructor(settingsService, refundPolicyService, secureConnectionService, disclaimerService) {
|
|
1463
|
+
this.settingsService = settingsService;
|
|
1464
|
+
this.refundPolicyService = refundPolicyService;
|
|
1465
|
+
this.secureConnectionService = secureConnectionService;
|
|
1466
|
+
this.disclaimerService = disclaimerService;
|
|
1467
|
+
this.sctlPolicyUrl = 'https://xsolla.com/sctl';
|
|
1468
|
+
}
|
|
1469
|
+
getLegalComponentConfig() {
|
|
1470
|
+
return {
|
|
1471
|
+
isJapanUser: this.isJapanUser,
|
|
1472
|
+
refundPolicyUrl: this.refundPolicyService.url,
|
|
1473
|
+
sctlPolicyUrl: this.sctlPolicyUrl,
|
|
1474
|
+
secureConnection: {
|
|
1475
|
+
secureConnectionUrl: this.secureConnectionService.secureConnectionUrl,
|
|
1476
|
+
isWhiteLabel: this.secureConnectionService.isWhiteLabel,
|
|
1477
|
+
},
|
|
1478
|
+
disclaimer: this.disclaimerService.disclaimer,
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
LegalService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: LegalService, deps: [{ token: SettingsService }, { token: RefundPolicyService }, { token: SecureConnectionService }, { token: DisclaimerService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1483
|
+
LegalService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: LegalService, providedIn: 'root' });
|
|
1484
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: LegalService, decorators: [{
|
|
1485
|
+
type: Injectable,
|
|
1486
|
+
args: [{
|
|
1487
|
+
providedIn: 'root',
|
|
1488
|
+
}]
|
|
1489
|
+
}], ctorParameters: function () { return [{ type: SettingsService }, { type: RefundPolicyService }, { type: SecureConnectionService }, { type: DisclaimerService }]; } });
|
|
1490
|
+
|
|
401
1491
|
class CoreLibraryService {
|
|
402
|
-
constructor(settingsService, countryService, paymentMethodsService, savedMethodsService, userBalanceService) {
|
|
1492
|
+
constructor(settingsService, countryService, paymentMethodsService, savedMethodsService, userBalanceService, paymentService, deviceFingerPrintService, legalService) {
|
|
403
1493
|
this.settingsService = settingsService;
|
|
404
1494
|
this.countryService = countryService;
|
|
405
1495
|
this.paymentMethodsService = paymentMethodsService;
|
|
406
1496
|
this.savedMethodsService = savedMethodsService;
|
|
407
1497
|
this.userBalanceService = userBalanceService;
|
|
1498
|
+
this.paymentService = paymentService;
|
|
1499
|
+
this.deviceFingerPrintService = deviceFingerPrintService;
|
|
1500
|
+
this.legalService = legalService;
|
|
408
1501
|
this.paymentMethods = {
|
|
409
1502
|
getList: async () => this.paymentMethodsService.getList(),
|
|
410
1503
|
getQuickMethods: async () => this.paymentMethodsService.getQuickMethods(),
|
|
@@ -413,20 +1506,36 @@ class CoreLibraryService {
|
|
|
413
1506
|
};
|
|
414
1507
|
}
|
|
415
1508
|
async init(configuration) {
|
|
416
|
-
|
|
1509
|
+
await this.settingsService.init(configuration);
|
|
1510
|
+
await this.deviceFingerPrintService.init();
|
|
417
1511
|
}
|
|
418
1512
|
setCountry(country) {
|
|
419
1513
|
this.countryService.setCountry(country);
|
|
420
1514
|
}
|
|
1515
|
+
createPayment(config) {
|
|
1516
|
+
return {
|
|
1517
|
+
initialize: async () => this.paymentService.initialize(config),
|
|
1518
|
+
submit: async (fields, form) => this.paymentService.submit(fields, form),
|
|
1519
|
+
getFields: () => this.paymentService.getFields(),
|
|
1520
|
+
changeFieldValue: (name, value) => this.paymentService.changeFieldValue(name, value),
|
|
1521
|
+
validate: async (field) => this.paymentService.validate(field),
|
|
1522
|
+
getFinanceDetails: () => this.paymentService.getFinanceDetails(),
|
|
1523
|
+
runThreeDs: () => this.paymentService.runThreeDs(),
|
|
1524
|
+
getStatus: () => this.paymentService.getStatus(),
|
|
1525
|
+
};
|
|
1526
|
+
}
|
|
1527
|
+
getLegalComponentConfig() {
|
|
1528
|
+
return this.legalService.getLegalComponentConfig();
|
|
1529
|
+
}
|
|
421
1530
|
}
|
|
422
|
-
CoreLibraryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryService, deps: [{ token: SettingsService }, { token: CountryService }, { token: PaymentMethodsService }, { token: SavedMethodsService }, { token: UserBalanceService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1531
|
+
CoreLibraryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryService, deps: [{ token: SettingsService }, { token: CountryService }, { token: PaymentMethodsService }, { token: SavedMethodsService }, { token: UserBalanceService }, { token: PaymentService }, { token: DeviceFingerPrintService }, { token: LegalService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
423
1532
|
CoreLibraryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryService, providedIn: 'root' });
|
|
424
1533
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryService, decorators: [{
|
|
425
1534
|
type: Injectable,
|
|
426
1535
|
args: [{
|
|
427
1536
|
providedIn: 'root',
|
|
428
1537
|
}]
|
|
429
|
-
}], ctorParameters: function () { return [{ type: SettingsService }, { type: CountryService }, { type: PaymentMethodsService }, { type: SavedMethodsService }, { type: UserBalanceService }]; } });
|
|
1538
|
+
}], ctorParameters: function () { return [{ type: SettingsService }, { type: CountryService }, { type: PaymentMethodsService }, { type: SavedMethodsService }, { type: UserBalanceService }, { type: PaymentService }, { type: DeviceFingerPrintService }, { type: LegalService }]; } });
|
|
430
1539
|
|
|
431
1540
|
class HttpError extends AppError {
|
|
432
1541
|
constructor(error, req) {
|
|
@@ -483,10 +1592,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
483
1592
|
type: Injectable
|
|
484
1593
|
}], ctorParameters: function () { return [{ type: i1$1.Router }]; } });
|
|
485
1594
|
|
|
1595
|
+
class FormModule {
|
|
1596
|
+
}
|
|
1597
|
+
FormModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: FormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1598
|
+
FormModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.7", ngImport: i0, type: FormModule, imports: [ReactiveFormsModule] });
|
|
1599
|
+
FormModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: FormModule, providers: [
|
|
1600
|
+
FormService,
|
|
1601
|
+
ControlConfigService,
|
|
1602
|
+
ZipConverter,
|
|
1603
|
+
EmailConverter,
|
|
1604
|
+
{ provide: convertersMapToken, useValue: convertersMap },
|
|
1605
|
+
], imports: [ReactiveFormsModule] });
|
|
1606
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: FormModule, decorators: [{
|
|
1607
|
+
type: NgModule,
|
|
1608
|
+
args: [{
|
|
1609
|
+
imports: [ReactiveFormsModule],
|
|
1610
|
+
providers: [
|
|
1611
|
+
FormService,
|
|
1612
|
+
ControlConfigService,
|
|
1613
|
+
ZipConverter,
|
|
1614
|
+
EmailConverter,
|
|
1615
|
+
{ provide: convertersMapToken, useValue: convertersMap },
|
|
1616
|
+
],
|
|
1617
|
+
}]
|
|
1618
|
+
}] });
|
|
1619
|
+
|
|
486
1620
|
class CoreLibraryModule {
|
|
487
1621
|
}
|
|
488
1622
|
CoreLibraryModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
489
|
-
CoreLibraryModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryModule, imports: [HttpClientModule] });
|
|
1623
|
+
CoreLibraryModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryModule, imports: [HttpClientModule, FormModule] });
|
|
490
1624
|
CoreLibraryModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryModule, providers: [
|
|
491
1625
|
{
|
|
492
1626
|
provide: HTTP_INTERCEPTORS,
|
|
@@ -497,11 +1631,21 @@ CoreLibraryModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", versi
|
|
|
497
1631
|
paymentMethodsResponseFactoryProvider,
|
|
498
1632
|
savedMethodsResponseFactoryProvider,
|
|
499
1633
|
userBalanceResponseFactoryProvider,
|
|
500
|
-
|
|
1634
|
+
initializeResponseFactoryProvider,
|
|
1635
|
+
submitRequestFactoryProvider,
|
|
1636
|
+
submitResponseFactoryProvider,
|
|
1637
|
+
syncRequestFactoryProvider,
|
|
1638
|
+
syncResponseFactoryProvider,
|
|
1639
|
+
{
|
|
1640
|
+
provide: nextActionsToken,
|
|
1641
|
+
useValue: nextActions,
|
|
1642
|
+
},
|
|
1643
|
+
...nextActions,
|
|
1644
|
+
], imports: [HttpClientModule, FormModule] });
|
|
501
1645
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: CoreLibraryModule, decorators: [{
|
|
502
1646
|
type: NgModule,
|
|
503
1647
|
args: [{
|
|
504
|
-
imports: [HttpClientModule],
|
|
1648
|
+
imports: [HttpClientModule, FormModule],
|
|
505
1649
|
providers: [
|
|
506
1650
|
{
|
|
507
1651
|
provide: HTTP_INTERCEPTORS,
|
|
@@ -512,6 +1656,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
|
|
|
512
1656
|
paymentMethodsResponseFactoryProvider,
|
|
513
1657
|
savedMethodsResponseFactoryProvider,
|
|
514
1658
|
userBalanceResponseFactoryProvider,
|
|
1659
|
+
initializeResponseFactoryProvider,
|
|
1660
|
+
submitRequestFactoryProvider,
|
|
1661
|
+
submitResponseFactoryProvider,
|
|
1662
|
+
syncRequestFactoryProvider,
|
|
1663
|
+
syncResponseFactoryProvider,
|
|
1664
|
+
{
|
|
1665
|
+
provide: nextActionsToken,
|
|
1666
|
+
useValue: nextActions,
|
|
1667
|
+
},
|
|
1668
|
+
...nextActions,
|
|
515
1669
|
],
|
|
516
1670
|
}]
|
|
517
1671
|
}] });
|