private async Task <bool> AttemptPaying(IAdaptToBank bankAdapter, Payment payment)
        {
            var payingAttempt = payment.MapToAcquiringBank();

            var circuitBreaker = CircuitBreaker(bankAdapter, payment, payingAttempt);

            IBankResponse bankResponse = new NullBankResponse();

            var policyResult = await circuitBreaker.Policy.ExecuteAndCaptureAsync(async() =>
            {
                using (var cts = new CancellationTokenSource())
                {
                    var timeout = _timeoutProviderForBankResponseWaiting.GetTimeout();
                    cts.CancelAfter(timeout);

                    bankResponse = await bankAdapter.RespondToPaymentAttempt(payingAttempt, cts.Token);
                }
            });

            if (policyResult.FinalException == null)
            {
                circuitBreaker.Reset();
            }
            else
            {
                return(false);
            }

            var strategy = BankResponseHandleStrategyBuilder.Build(bankResponse, _paymentsRepository);

            await strategy.Handle(_gatewayExceptionSimulator, bankResponse.GatewayPaymentId);

            return(true);
        }
        public async Task <IPaymentRequestHandlingResult> AttemptPaying(IAdaptToBank bankAdapter, Payment payment)
        {
            var payingAttempt = payment.MapToAcquiringBank();

            var circuitBreaker = CircuitBreaker(bankAdapter, payment);

            IBankResponse bankResponse = new NullBankResponse();

            var policyResult = await circuitBreaker.Policy.ExecuteAndCaptureAsync(async() =>
            {
                using (var cts = new CancellationTokenSource())
                {
                    var timeout = _timeoutProviderForBankResponseWaiting.GetTimeout();
                    cts.CancelAfter(timeout);

                    bankResponse = await bankAdapter.RespondToPaymentAttempt(payingAttempt, cts.Token);
                }
            });

            if (policyResult.FinalException == null)
            {
                circuitBreaker.Reset();
            }
            else if (policyResult.FinalException is BankDuplicatedPaymentIdException paymentDuplicatedException)
            {
                _logger.LogError(paymentDuplicatedException.Message);

                payment.HandleBankPaymentIdDuplication();
                await _paymentsRepository.Save(payment, payment.Version);

                return(PaymentRequestHandlingStatus.Fail(payingAttempt.GatewayPaymentId, payingAttempt.PaymentRequestId, policyResult.FinalException, "Bank Duplicated PaymentId"));
            }

            var strategy = BankResponseHandleStrategyBuilder.Build(bankResponse, _paymentsRepository);

            await strategy.Handle(_gatewayExceptionSimulator, bankResponse.GatewayPaymentId);

            return(PaymentRequestHandlingStatus.Finished(payingAttempt.GatewayPaymentId, payingAttempt.PaymentRequestId));
        }