public async Task <IActionResult> ProceedPaymentRequest([FromBody] PaymentRequest paymentRequest,
                                                                [FromServices] IGenerateGuid gatewayPaymentIdGenerator,
                                                                [FromServices] IKnowAllPaymentRequests paymentRequestsRepository,
                                                                [FromServices] IProcessPayment paymentProcessor)
        {
            var gatewayPaymentId = gatewayPaymentIdGenerator.Generate();

            var commandResult = await _commandHandler.Handle(paymentRequest.AsCommand(gatewayPaymentId));

            switch (commandResult)
            {
            case SuccessCommandResult <Payment> success:
                var paymentDto = success.Entity.AsDto();

                return(AcceptedAtRoute(nameof(PaymentReadController.GetPaymentInfo),
                                       routeValues: new { gateWayPaymentId = paymentDto.GatewayPaymentId },
                                       value: paymentDto));

            case InvalidCommandResult invalid:
                return(ActionResultHelper.ToActionResult(invalid));

            case FailureCommandResult failure:
                return(ActionResultHelper.ToActionResult(failure));


            default:
                throw new NotSupportedException();
            }
        }
        public async Task Return_InternalServerEror_When_AcquiringBank_sent_duplicated_PaymentId_Using_StupidBank(BankPaymentStatus bankPaymentStatus, PaymentStatus expectedPaymentStatusReturnedByGateway)
        {
            var requestId            = Guid.Parse("9cb25b95-45ba-4100-a180-deb13259d0e1");
            var paymentRequest       = TestsUtils.BuildPaymentRequest(requestId, MerchantsRepository.FailFromThe2ndPaymentMerchant);
            var secondRequestId      = Guid.Parse("9c940897-b1c4-4598-96a7-82502ca51845");
            var secondPaymentRequest = TestsUtils.BuildPaymentRequest(secondRequestId, MerchantsRepository.FailFromThe2ndPaymentMerchant);

            var           gatewayPaymentId          = Guid.Parse("002ee45f-fdfb-4666-b504-70aa26ecf646");
            var           secondGatewayPaymentId    = Guid.Parse("4cc3dd04-b3d8-4be4-8c68-e744c387fb6c");
            IGenerateGuid gatewayPaymentIdGenerator = Substitute.For <IGenerateGuid>();

            gatewayPaymentIdGenerator.Generate().Returns(gatewayPaymentId, secondGatewayPaymentId);

            var cqrs = await PaymentCQRS.Build(bankPaymentStatus, new DefaultBankPaymentIdGenerator(), new AlwaysSuccessBankConnectionBehavior(), new DelayProviderForTesting(TimeSpan.FromMilliseconds(1)), PaymentCQRS.TimeoutProviderForBankResponseWaiting(TimeSpan.FromMilliseconds(200)), Substitute.For <IKnowBufferAndReprocessPaymentRequest>(), Substitute.For <IAmCircuitBreakers>());

            await cqrs.RequestsController.ProceedPaymentRequest(paymentRequest, gatewayPaymentIdGenerator, cqrs.PaymentRequestsMemory, cqrs.PaymentProcessor);

            await cqrs.RequestsController.ProceedPaymentRequest(secondPaymentRequest, gatewayPaymentIdGenerator, cqrs.PaymentRequestsMemory, cqrs.PaymentProcessor);

            var secondFailedPayment = (await cqrs.PaymentReadController.GetPaymentInfo(secondGatewayPaymentId)).Value;

            Check.That(secondFailedPayment.RequestId).IsEqualTo(secondRequestId);
            Check.That(secondFailedPayment.GatewayPaymentId).IsEqualTo(secondGatewayPaymentId);

            Check.That(secondFailedPayment.Status).IsEqualTo(expectedPaymentStatusReturnedByGateway);
            Check.That(secondFailedPayment.Approved).IsEqualTo(secondFailedPayment.Status == PaymentGateway.Domain.PaymentStatus.Success);
            Check.That(secondFailedPayment.AcquiringBankPaymentId).IsNull();
        }