public async Task <PaymentDto> ProcessPaymentRequest(Guid merchantId, Guid requestId, PaymentReqestDto request) { try { // there should be preliminary fraud checking. var card = new Card(request.CardNumber, request.CardHolderName, request.ExpiryMonth, request.ExpiryYear, request.CVV); var amount = new Money(request.Currency, request.Amount); var paymentRequest = new PaymentRequest(merchantId, requestId, card, amount); await _paymentRequestDuplicateChecker.Check(paymentRequest); var paymentResult = await _acquiringBank.Process(paymentRequest); var payment = new Payment(CardDetails.From(card), amount, paymentResult.Status, paymentResult.AcquiringBankTransactionId, merchantId); await _paymentRepository.Save(payment); return(ToDto(payment)); } catch (DomainRuleViolationException e) { throw new ApplicationServiceException(e.Message, e); } }