Files
banking-service/src/main/java/net/kapcake/bankingservice/validation/PaymentValidator.java

79 lines
3.7 KiB
Java

package net.kapcake.bankingservice.validation;
import net.kapcake.bankingservice.exceptions.ValidationException;
import net.kapcake.bankingservice.model.domain.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Component
public class PaymentValidator {
private final RestTemplate restTemplate;
private final String validationUrl;
private final List<String> forbiddenAccounts;
public PaymentValidator(RestTemplate restTemplate,
@Value("${banking-service.validation.iban-validator-url:}") String validationUrl,
@Value("${banking-service.validation.forbidden-accounts:}") List<String> forbiddenAccounts) {
this.restTemplate = restTemplate;
this.validationUrl = validationUrl;
this.forbiddenAccounts = forbiddenAccounts;
}
public void validate(List<BankAccount> userBankAccounts, Payment payment) throws ValidationException {
validateGiverAccount(userBankAccounts, payment);
validateBeneficiaryAccount(payment);
validateAccountBalance(payment);
}
private static void validateGiverAccount(List<BankAccount> userBankAccounts, Payment payment) {
boolean userOwnsGiverAccount = userBankAccounts.stream().anyMatch(bankAccount -> bankAccount.getId().equals(payment.getGiverAccount().getId()));
if (!userOwnsGiverAccount) {
throw new ValidationException("Giver account not owned by authenticated user.");
}
}
private void validateBeneficiaryAccount(Payment payment) {
IbanValidationResponse validationResponse;
try {
validationResponse = restTemplate.getForObject(validationUrl + "/" + payment.getBeneficiaryAccountNumber(), IbanValidationResponse.class);
} catch (RestClientException e) {
throw new ValidationException("Beneficiary account could not be validated.");
}
if (validationResponse == null) {
throw new ValidationException("Beneficiary account could not be validated.");
} else if (!validationResponse.valid()) {
throw new ValidationException("Beneficiary account not valid: " + validationResponse.messages());
}
boolean sameGiverAndBeneficiary = payment.getGiverAccount().getAccountNumber().equals(payment.getBeneficiaryAccountNumber());
if (sameGiverAndBeneficiary) {
throw new ValidationException("Beneficiary and giver account are the same.");
}
boolean isBeneficiaryForbidden = forbiddenAccounts.contains(payment.getBeneficiaryAccountNumber());
if (isBeneficiaryForbidden) {
throw new ValidationException("Beneficiary account is forbidden.");
}
}
private void validateAccountBalance(Payment payment) {
List<Balance> availableBalances = payment.getGiverAccount().getBalances().stream().filter(balance -> BalanceType.AVAILABLE.equals(balance.getType())).toList();
if (availableBalances.size() != 1) {
throw new ValidationException("Unable to retrieve available account balance.");
}
Balance balance = availableBalances.get(0);
boolean sameCurrencies = balance.getCurrency().equals(payment.getCurrency());
if (!sameCurrencies) {
throw new ValidationException("Payment and account currency must be the same.");
}
int compareResult = balance.getAmount().compareTo(payment.getAmount());
if (compareResult < 0) {
throw new ValidationException("Available account balance not sufficient.");
}
}
}