public async Task <ICommandResult> Handle(RequestPaymentCommand command) { Payment payment; try { var paymentRequestId = new PaymentRequestId(command.RequestId); if (await _paymentRequestsMemory.AlreadyHandled(paymentRequestId)) { //payment request already handled return(this.Invalid(command.RequestId, "Identical payment request will not be handled more than once")); } var bankAdapter = _bankAdapterMapper.FindBankAdapter(command.MerchantId); payment = new Payment(command.GatewayPaymentId, command.MerchantId, command.RequestId, command.Card, command.Amount); await _repository.Save(payment, Stream.NotCreatedYet); await _paymentRequestsMemory.Remember(paymentRequestId); //TODO: Add cancellation with a timeout if (_synchronyMaster.SendPaymentRequestAsynchronously()) { _paymentProcessor.AttemptPaying(bankAdapter, payment).ContinueWith((task) => { if (task.IsFaulted) { _logger.LogError($"Payment request '{command.RequestId}' with exception {task.Exception}"); } }); } else { var requestHandlingResult = await _paymentProcessor.AttemptPaying(bankAdapter, payment); if (requestHandlingResult.Status == RequestHandlingStatus.Fail) { return(this.Failure($"{requestHandlingResult.Identifier} {requestHandlingResult} ")); } } } catch (BankOnboardMissingException e) { return(this.Invalid(command.RequestId, e.Message)); } return(this.Success(payment)); }