public Merchant GetMerchantBasedOnApiKey(string apiKey)
 {
     return(_merchantDao.GetMerchantBasedOnApiKey(apiKey));
 }
        public PaymentResponse ProcessPayment(ProcessPaymentRequest request, string merchantApiKey)
        {
            //Get merchant
            var merchant = _merchantDao.GetMerchantBasedOnApiKey(merchantApiKey);

            if (merchant == null)
            {
                Logger.Info("Request from an unknown merchant received");
                throw new RequestValidationException("Unknown Merchant");
            }

            if (string.IsNullOrWhiteSpace(request.CardNumber))
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Card Number");
                throw new RequestValidationException("Missing Card Number");
            }

            if (!(request.CardNumber.Length == 19 || request.CardNumber.Length == 16))
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid Card Number");
                throw new RequestValidationException("Invalid Card Number");
            }

            if (string.IsNullOrWhiteSpace(request.CardCvv))
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Card CVV Number");
                throw new RequestValidationException("Missing Card CVV Number");
            }

            if (request.CardCvv.Length != 4)
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid Card Card CVV Number");
                throw new RequestValidationException("Invalid Card Card CVV Number");
            }

            if (request.PaymentAmount == 0)
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid Payment Amount");
                throw new RequestValidationException("Payment Amount should be greater than zero");
            }

            if (string.IsNullOrWhiteSpace(request.ExpiryDate))
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Card Expiry Date");
                throw new RequestValidationException("Missing Card Card Expiry Date");
            }

            DateTime expiryDate;

            try
            {
                expiryDate = DateTime.ParseExact(request.ExpiryDate, _expiryDateFormat, CultureInfo.InvariantCulture);
            }
            catch (Exception e)
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid ExpiryDate provided");
                throw new RequestValidationException("Invalid ExpiryDate provided");
            }

            if (string.IsNullOrWhiteSpace(request.Currency))
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Currency");
                throw new RequestValidationException("Missing Currency");
            }



            var currency = GetCurrency(request);

            if (currency == null)
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Unknown currency");
                throw new RequestValidationException("Unknown Currency");
            }



            var card = GetOrCreateCard(request, expiryDate);

            var paymentRequest = new PaymentRequest
            {
                MerchantId    = merchant.ID,
                CardId        = card.ID,
                CurrencyId    = currency.ID,
                Amount        = request.PaymentAmount,
                DateTimeAdded = DateTime.UtcNow
            };

            _paymentRequestDao.InsertPaymentRequest(paymentRequest);

            paymentRequest =
                _paymentRequestDao.GetPaymentRequestBasedOnMerchantIdCardIdCurrencyIdAndAmount(paymentRequest);
            Logger.Info($"Payment request from Merchant: {merchant.ID} logged. PaymentRequestId : {paymentRequest.Id}");

            var acquiringBankRequest = new  AcquiringBankRequest
            {
                CardNumber    = request.CardNumber,
                CardCvv       = request.CardCvv,
                PaymentAmount = request.PaymentAmount,
                ExpiryDate    = request.ExpiryDate,
                Currency      = request.Currency,
                MerchantId    = merchant.ID
            };
            var response = _acquiringBankService.ProcessPayment(acquiringBankRequest);

            var bankPaymentResponse = new BankPaymentResponse
            {
                PaymentRequestId      = paymentRequest.Id,
                Status                = response.PaymentStatus,
                BankPaymentIdentifier = response.PaymentIdentifier,
                DateTimeAdded         = DateTime.UtcNow
            };

            _bankPaymentResponseDao.InsertBankPaymentResponse(bankPaymentResponse);

            return(new PaymentResponse
            {
                Status = response.PaymentStatus,
                PaymentUniqueId = response.PaymentIdentifier
            });
        }