class PaymentService {

    public ResponseObject<CancelPaymentResponse> cancelPayment(PisPaymentCancellationRequest paymentCancellationRequest) {
        xs2aEventService.recordPisTppRequest(paymentCancellationRequest.getEncryptedPaymentId(), EventType.PAYMENT_CANCELLATION_REQUEST_RECEIVED);
        Optional<PisCommonPaymentResponse> pisCommonPaymentOptional = pisCommonPaymentService.getPisCommonPaymentById(paymentCancellationRequest.getEncryptedPaymentId());

        if (pisCommonPaymentOptional.isEmpty()) {
            log.info("Payment-ID [{}]. Cancel payment has failed. Payment not found by ID.",
                     paymentCancellationRequest.getEncryptedPaymentId());
            return ResponseObject.<CancelPaymentResponse>builder()
                       .fail(PIS_403, TppMessageInformation.of(RESOURCE_UNKNOWN_403))
                       .build();
        }

        PisCommonPaymentResponse pisCommonPaymentResponse = pisCommonPaymentOptional.get();
        CancelPaymentPO cancelPaymentPO = new CancelPaymentPO(pisCommonPaymentResponse, paymentCancellationRequest.getPaymentType(), paymentCancellationRequest.getPaymentProduct(), paymentCancellationRequest.getTppRedirectUri());

        ValidationResult validationResult = cancelPaymentValidator.validate(cancelPaymentPO);
        if (validationResult.isNotValid()) {
            log.info("Payment-ID [{}]. Cancel payment - validation failed: [{}]",
                     paymentCancellationRequest.getEncryptedPaymentId(), validationResult.getMessageError());
            return ResponseObject.<CancelPaymentResponse>builder()
                       .fail(validationResult.getMessageError())
                       .build();
        }

        if (pisCommonPaymentResponse.getTransactionStatus().isFinalisedStatus()) {
            log.info("Payment-ID [{}]. Cancel payment has failed. Payment has finalised status",
                     paymentCancellationRequest.getEncryptedPaymentId());
            return ResponseObject.<CancelPaymentResponse>builder()
                       .fail(PIS_400, TppMessageInformation.of(RESOURCE_BLOCKED))
                       .build();
        }

        CancelPaymentService cancelPaymentService = paymentServiceResolver.getCancelPaymentService(paymentCancellationRequest);
        ResponseObject<CancelPaymentResponse> responseObject = cancelPaymentService.cancelPayment(pisCommonPaymentResponse, paymentCancellationRequest);

        if (responseObject.hasError()) {
            log.info("Payment-ID: [{}]. Cancel payment failed: [{}]",
                     paymentCancellationRequest.getEncryptedPaymentId(),
                     responseObject.getError());
            return ResponseObject.<CancelPaymentResponse>builder()
                       .fail(responseObject.getError())
                       .build();
        }

        CancelPaymentResponse cancelPaymentResponse = responseObject.getBody();

        cancelPaymentResponse.setTppMessageInformation(cancelPaymentValidator.buildWarningMessages(cancelPaymentPO));

        loggingContextService.storeTransactionStatus(cancelPaymentResponse.getTransactionStatus());

        return ResponseObject.<CancelPaymentResponse>builder()
                   .body(cancelPaymentResponse)
                   .build();
    }

}