@xsolla/payment-client-core 0.2.75 → 0.2.77

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.
@@ -1371,8 +1371,8 @@ class SubmitResponse {
1371
1371
  (parameters.currentCommand === XpsCommand.checkout &&
1372
1372
  Boolean(parameters.checkout));
1373
1373
  this.buyData = parameters.buyData;
1374
- this.fixInvoice = this.fields.find((field) => field.name === FieldNames.fixInvoice)?.value;
1375
- this.signature = this.fields.find((field) => field.name === FieldNames.signature)?.value;
1374
+ this.fixInvoice = this.getFieldValue(FieldNames.fixInvoice);
1375
+ this.signature = this.getFieldValue(FieldNames.signature);
1376
1376
  this.hasFatalErrors = parameters.textAll?.fatal;
1377
1377
  this.userSession = parameters.userSession;
1378
1378
  this.pid = parameters.pid;
@@ -1386,6 +1386,18 @@ class SubmitResponse {
1386
1386
  isMap: parameters.isMap,
1387
1387
  };
1388
1388
  }
1389
+ setFieldValue(fieldName, value) {
1390
+ if (!this.parameters.form[fieldName])
1391
+ return;
1392
+ this.parameters.form[fieldName].value = value;
1393
+ const fieldToUpdate = this.fields.find((field) => field.name === fieldName);
1394
+ if (!fieldToUpdate)
1395
+ return;
1396
+ fieldToUpdate.value = value;
1397
+ }
1398
+ getFieldValue(fieldName) {
1399
+ return this.parameters.form[fieldName]?.value;
1400
+ }
1389
1401
  }
1390
1402
 
1391
1403
  class InitializeResponse {
@@ -1465,6 +1477,39 @@ const overrideFieldConfigs = {
1465
1477
  },
1466
1478
  };
1467
1479
 
1480
+ const getRestoreAllowSaveRule = (fieldName) => ({
1481
+ description: `Restore ${fieldName} field value entered by user before submit`,
1482
+ apply: (submitResponse, form) => {
1483
+ const control = form?.get(fieldName);
1484
+ if (!control)
1485
+ return;
1486
+ submitResponse.setFieldValue(fieldName, control.value);
1487
+ },
1488
+ });
1489
+ const updateAfterErrorRules = [
1490
+ getRestoreAllowSaveRule(FieldNames.allowSave),
1491
+ getRestoreAllowSaveRule(FieldNames.allowSubscription),
1492
+ getRestoreAllowSaveRule(FieldNames.allowRecurrentSubscription),
1493
+ {
1494
+ description: 'Restore zip field value entered by user before submit if no zip value in response',
1495
+ apply: (submitResponse, form) => {
1496
+ const valueInResponse = submitResponse.getFieldValue(FieldNames.zip);
1497
+ if (valueInResponse)
1498
+ return;
1499
+ const control = form?.get(FieldNames.zip);
1500
+ if (!control?.value)
1501
+ return;
1502
+ submitResponse.setFieldValue(FieldNames.zip, control.value);
1503
+ },
1504
+ },
1505
+ {
1506
+ description: 'Reset card_expire field value that sent by paycore for some reason',
1507
+ apply: (submitResponse) => {
1508
+ submitResponse.setFieldValue(FieldNames.cardExpire, '');
1509
+ },
1510
+ },
1511
+ ];
1512
+
1468
1513
  const initializeResponseFactoryToken = new InjectionToken('InitializeResponse');
1469
1514
  const initializeResponseFactoryProvider = {
1470
1515
  provide: initializeResponseFactoryToken,
@@ -4047,10 +4092,65 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImpor
4047
4092
  type: Injectable
4048
4093
  }], ctorParameters: () => [{ type: SyncService }] });
4049
4094
 
4095
+ const cpfLength = 11;
4096
+ const firstCheckDigitPosition = 9;
4097
+ const secondCheckDigitPosition = 10;
4098
+ const maxCheckDigit = 10;
4099
+ const repeatedDigitsRegex = /^(\d)\1+$/;
4100
+ const allowedCharactersRegex = /[^0-9 .-]+/;
4101
+ const moduloDivisor = 11;
4102
+ /**
4103
+ * Checks number match CPF validation algorithm.
4104
+ * Based on https://en.wikipedia.org/wiki/CPF_number
4105
+ */
4106
+ const cpfFormulaValidator = ({ value }) => {
4107
+ if (isEmptyInputValue(value) || !isString(value)) {
4108
+ return null;
4109
+ }
4110
+ const error = {
4111
+ rewritableError: {
4112
+ message: TranslateHelper.t('cpf-number.converter.validation.pattern', 'Enter a valid CPF number'),
4113
+ },
4114
+ };
4115
+ if (allowedCharactersRegex.test(value)) {
4116
+ // accept only spaces, digits, dots and dashes
4117
+ return error;
4118
+ }
4119
+ // Remove non-numeric characters from CPF
4120
+ const cpf = value.replace(/\D/g, '');
4121
+ // Check if CPF has 11 digits
4122
+ if (cpf.length !== cpfLength) {
4123
+ return error;
4124
+ }
4125
+ // Disallow CPFs with all same digits (e.g., "11111111111")
4126
+ if (repeatedDigitsRegex.test(cpf)) {
4127
+ return error;
4128
+ }
4129
+ function calculateCheckDigit(cpfNumber, checkDigitPosition) {
4130
+ let sum = 0;
4131
+ for (let i = 0; i < checkDigitPosition; i++) {
4132
+ sum += parseInt(cpfNumber.charAt(i)) * (checkDigitPosition + 1 - i);
4133
+ }
4134
+ const checkDigit = (sum * maxCheckDigit) % moduloDivisor;
4135
+ return checkDigit >= maxCheckDigit ? 0 : checkDigit;
4136
+ }
4137
+ // Validate the check digits
4138
+ for (const position of [firstCheckDigitPosition, secondCheckDigitPosition]) {
4139
+ const checkDigit = calculateCheckDigit(cpf, position);
4140
+ if (checkDigit !== parseInt(cpf.charAt(position))) {
4141
+ return error;
4142
+ }
4143
+ }
4144
+ return null;
4145
+ };
4146
+
4050
4147
  class CpfNumberConverter extends Converter {
4051
4148
  constructor(syncService) {
4052
4149
  super(syncService);
4053
4150
  }
4151
+ getValidators(field) {
4152
+ return super.getValidators(field).concat([cpfFormulaValidator]);
4153
+ }
4054
4154
  createControlConfig(field) {
4055
4155
  const config = this.createDefaultControlConfig(TextControlConfig, field);
4056
4156
  config.maskConfig = {
@@ -7180,6 +7280,7 @@ class PaymentService {
7180
7280
  }
7181
7281
  this.isSavingMethodMode = this.fields.some(({ name, value }) => name === 'savePsAccountOnly' && value === "1" /* XpsBoolean.true */);
7182
7282
  const submitResponse = await this.submitService.request(this.fields, this.form, this.config);
7283
+ this.handleSubmitWithErrors(submitResponse);
7183
7284
  this.data = submitResponse;
7184
7285
  this.emitFormResponse(this.data);
7185
7286
  if (!this.isSavingMethodMode) {
@@ -7559,6 +7660,11 @@ class PaymentService {
7559
7660
  return strategy.canAutoSubmit();
7560
7661
  });
7561
7662
  }
7663
+ handleSubmitWithErrors(submitResponse) {
7664
+ if (!submitResponse.errors?.length)
7665
+ return;
7666
+ updateAfterErrorRules.forEach((rule) => rule.apply(submitResponse, this.form));
7667
+ }
7562
7668
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: PaymentService, deps: [{ token: LoggerService }, { token: InitializeService }, { token: SubmitService }, { token: SyncService }, { token: FormService }, { token: StatusService }, { token: FinanceDetailsService }, { token: CreditCardStateService }, { token: NextActionService }, { token: InitializeNextActionService }, { token: ControlConfigService }, { token: ThreeDsService }, { token: FormMessagesService }, { token: SettingsService }, { token: CountryService }, { token: CheckStatusActionCreator }, { token: PrintInstructionService }, { token: PaymentBehaviourService }], target: i0.ɵɵFactoryTarget.Injectable }); }
7563
7669
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: PaymentService, providedIn: 'root' }); }
7564
7670
  }