class PaymentService {

    public ResponseObject<GetPaymentStatusResponse> getPaymentStatusById(PaymentType paymentType, String paymentProduct, String encryptedPaymentId) {
        xs2aEventService.recordPisTppRequest(encryptedPaymentId, EventType.GET_TRANSACTION_STATUS_REQUEST_RECEIVED);
        Optional<PisCommonPaymentResponse> pisCommonPaymentOptional = pisCommonPaymentService.getPisCommonPaymentById(encryptedPaymentId);

        if (pisCommonPaymentOptional.isEmpty()) {
            log.info("Payment-ID [{}]. Get Payment Status failed. PIS CommonPayment not found by ID", encryptedPaymentId);
            return ResponseObject.<GetPaymentStatusResponse>builder()
                       .fail(PIS_403, TppMessageInformation.of(RESOURCE_UNKNOWN_403))
                       .build();
        }

        PisCommonPaymentResponse pisCommonPaymentResponse = pisCommonPaymentOptional.get();

        ValidationResult validationResult = getPaymentStatusByIdValidator.validate(new GetPaymentStatusByIdPO(pisCommonPaymentResponse, paymentType, paymentProduct));
        if (validationResult.isNotValid()) {
            log.info("Payment-ID [{}]. Get payment status by ID - validation failed: {}", encryptedPaymentId, validationResult.getMessageError());
            return ResponseObject.<GetPaymentStatusResponse>builder()
                       .fail(validationResult.getMessageError())
                       .build();
        }

        if (pisCommonPaymentResponse.getTransactionStatus() == TransactionStatus.RJCT) {
            return ResponseObject.<GetPaymentStatusResponse>builder().body(new GetPaymentStatusResponse(TransactionStatus.RJCT, null, MediaType.APPLICATION_JSON, null, null)).build();
        }

        SpiContextData spiContextData = spiContextDataProvider.provideWithPsuIdData(getPsuIdDataFromRequest());

        ReadPaymentStatusService readPaymentStatusService = paymentServiceResolver.getReadPaymentStatusService(pisCommonPaymentResponse);
        ReadPaymentStatusResponse readPaymentStatusResponse = readPaymentStatusService.readPaymentStatus(pisCommonPaymentResponse, spiContextData, encryptedPaymentId, requestProviderService.getAcceptHeader());

        if (readPaymentStatusResponse.hasError()) {
            ErrorHolder errorHolder = readPaymentStatusResponse.getErrorHolder();
            log.info("Payment-ID [{}]. Read Payment status failed: {}", encryptedPaymentId, errorHolder);
            return ResponseObject.<GetPaymentStatusResponse>builder()
                       .fail(errorHolder)
                       .build();
        }

        TransactionStatus transactionStatus = readPaymentStatusResponse.getStatus();

        if (transactionStatus == null) {
            log.info("Payment-ID [{}].  Get Payment Status by ID failed. Transaction status is null.", encryptedPaymentId);
            return ResponseObject.<GetPaymentStatusResponse>builder()
                       .fail(PIS_403, TppMessageInformation.of(RESOURCE_UNKNOWN_403))
                       .build();
        }

        if (!updatePaymentAfterSpiService.updatePaymentStatus(encryptedPaymentId, transactionStatus)) {
            log.info("Payment ID: [{}], Transaction status: [{}]. Update of a payment status in the CMS has failed.",
                     encryptedPaymentId, transactionStatus);
        }

        loggingContextService.storeTransactionStatus(transactionStatus);

        GetPaymentStatusResponse response = new GetPaymentStatusResponse(transactionStatus, readPaymentStatusResponse.getFundsAvailable(), readPaymentStatusResponse.getResponseContentType(), readPaymentStatusResponse.getPaymentStatusRaw(), readPaymentStatusResponse.getPsuMessage());
        return ResponseObject.<GetPaymentStatusResponse>builder().body(response).build();
    }

}