private void ValidateBankCard(OnlinePaymentViewModel viewModel, out IBankCard bankCard) { bankCard = _bankCardService.FindBankCard(viewModel.CardNumber); if (bankCard == null) { ModelState.AddModelError(nameof(viewModel.CardNumber), "Invalid card number"); } else { if (!string.Equals(bankCard.CardHolder.ToUpper(), viewModel.CardHolderName, StringComparison.InvariantCulture)) { ModelState.AddModelError(nameof(viewModel.CardHolderName), "Invalid cardholder name"); } if (!string.Equals(bankCard.CardNumber.ToUpper(), viewModel.CardNumber, StringComparison.InvariantCulture)) { ModelState.AddModelError(nameof(viewModel.CardNumber), "Invalid card number"); } if (bankCard.ExpirationMonth != viewModel.MonthExpired) { ModelState.AddModelError(nameof(viewModel.MonthExpired), "Invalid month"); } if (bankCard.ExpirationYear != viewModel.YearExpired) { ModelState.AddModelError(nameof(viewModel.YearExpired), "Invalid year"); } if (!string.Equals(bankCard.CsvCode.ToUpper(), viewModel.SecurityCode, StringComparison.InvariantCulture)) { ModelState.AddModelError(nameof(viewModel.SecurityCode), "Invalid security code"); } } }
private void ValidateRequiredParameters(OnlinePaymentViewModel viewModel) { if (string.IsNullOrWhiteSpace(viewModel.CardHolderName)) { ModelState.AddModelError(nameof(viewModel.CardHolderName), "Cardholder name is required"); } if (string.IsNullOrWhiteSpace(viewModel.CardNumber)) { ModelState.AddModelError(nameof(viewModel.CardNumber), "Card number is required"); } if (string.IsNullOrWhiteSpace(viewModel.SecurityCode)) { ModelState.AddModelError(nameof(viewModel.SecurityCode), "Security code is required"); } if (!viewModel.Months.Contains(viewModel.MonthExpired)) { ModelState.AddModelError(nameof(viewModel.MonthExpired), "Invalid month"); } if (!viewModel.Years.Contains(viewModel.YearExpired)) { ModelState.AddModelError(nameof(viewModel.YearExpired), "Invalid year"); } }
public void ShouldValidateViewModelOnSubmit(string merchantId, string currency, string cardHolderName, string cardNumber, string securityCode, int monthExpired, int yearExpired, string expectedError) { // arrange var model = new OnlinePaymentViewModel { MerchantId = new Guid(merchantId), Amount = 1000, Currency = currency, RedirectUrl = "http://test.com", CardHolderName = cardHolderName, CardNumber = cardNumber, SecurityCode = securityCode, MonthExpired = monthExpired, YearExpired = yearExpired }; var bankCard = new BankCard("123", "0000", "EVGENY SHMANEV", "12345", 1, 2020); _bankCardService.Setup(x => x.FindBankCard("12345")).Returns(bankCard); var merchant = new Merchant("merchant", "test@com", "pass", new Guid("E5310F8F-117B-4D60-8239-39A42A94ADC9"), "store", "contact"); var account = merchant.AddAccount("9876543210", "USD"); _merchantService.Setup(x => x.FindMerchant(merchant.MerchantId)).Returns(merchant); // act var result = _controller.Payment(model).Result; // assert result.ShouldBeOfType <ViewResult>(); _controller.ModelState.IsValid.ShouldBeFalse(); _controller.ModelState.ShouldContain(x => x.Value.Errors.Any(error => error.ErrorMessage == expectedError)); }
public ActionResult Index(Guid merchant, string currency, decimal sum, string redirectUrl) { TempData["ViewModel"] = new OnlinePaymentViewModel { RedirectUrl = redirectUrl, MerchantId = merchant, Amount = sum, Currency = currency.ToUpper(), Months = GetMonths(), Years = GetYears() }; return(RedirectToAction("Payment")); }
public void ShouldShowView_Success() { // arrange var model = new OnlinePaymentViewModel(); _controller.TempData["ViewModel"] = model; // act var result = _controller.Payment(); // assert result.ShouldBeOfType <ViewResult>().Model.ShouldBe(model); }
private void ValidateMerchant(OnlinePaymentViewModel viewModel, out IMerchant merchant, out IAccount merchantAccount) { merchant = _merchantService.FindMerchant(viewModel.MerchantId); if (merchant == null) { merchantAccount = null; ModelState.AddModelError(string.Empty, "Invalid merchant"); } else { merchantAccount = merchant.Accounts.FirstOrDefault(x => string.Equals(x.Currency, viewModel.Currency, StringComparison.InvariantCultureIgnoreCase)); if (merchantAccount == null) { ModelState.AddModelError(string.Empty, "Invalid merchant currency"); } } }
public void ShouldRedirectToStoreAfterPayment(string merchantId, string currency, string cardHolderName, string cardNumber, string securityCode, int monthExpired, int yearExpired, string expectedError) { // arrange var model = new OnlinePaymentViewModel { MerchantId = new Guid(merchantId), Amount = 1000, Currency = currency, RedirectUrl = "http://test.com", CardHolderName = cardHolderName, CardNumber = cardNumber, SecurityCode = securityCode, MonthExpired = monthExpired, YearExpired = yearExpired }; var customer = new Individual("customer", "test@com", "pass", "Evgeny", "Shmanev"); var customerAccount = customer.AddAccount("11111111", "EUR"); customerAccount.BankCard = new BankCard("123", "0000", "EVGENY SHMANEV", "12345", 1, 2020); _bankCardService.Setup(x => x.FindBankCard("12345")).Returns(customerAccount.BankCard); var merchant = new Merchant("merchant", "test@com", "pass", new Guid("E5310F8F-117B-4D60-8239-39A42A94ADC9"), "store", "contact"); var merchantAccount = merchant.AddAccount("222222222", "USD"); _merchantService.Setup(x => x.FindMerchant(merchant.MerchantId)).Returns(merchant); // act var result = _controller.Payment(model).Result; // assert _controller.ModelState.IsValid.ShouldBeTrue(); _accountService.Verify(x => x.TransferMoney(customerAccount, merchantAccount, model.Amount, AmountConversionMode.TargetToSource, $"Online payment on {merchant.MerchantName}.")); result.ShouldBeOfType <RedirectResult>() .Url.ShouldBe("http://test.com?status=success"); }
public async Task <ActionResult> Payment(OnlinePaymentViewModel viewModel) { viewModel.Months = GetMonths(); viewModel.Years = GetYears(); // these values cannot be changed by user, so if they are changed we should return Bad Request if (string.IsNullOrWhiteSpace(viewModel.RedirectUrl) || viewModel.MerchantId == Guid.Empty || viewModel.Amount <= 0 || string.IsNullOrWhiteSpace(viewModel.Currency)) { return(BadRequest()); } // validate required parameters if (ModelState.IsValid) { ValidateRequiredParameters(viewModel); } // validate bank card IBankCard bankCard = null; if (ModelState.IsValid) { ValidateBankCard(viewModel, out bankCard); } IMerchant merchant = null; IAccount merchantAccount = null; if (ModelState.IsValid) { ValidateMerchant(viewModel, out merchant, out merchantAccount); } if (!ModelState.IsValid) { // Optionally we can calculate a number of failures and when a limit exceeds redirect to merchant with status=failure // At the moment it is out of the scope. // Redirect(url + "?status=failure"); return(View(viewModel)); } Debug.Assert(bankCard != null); Debug.Assert(merchant != null); Debug.Assert(merchantAccount != null); try { var description = $"Online payment on {merchant.MerchantName}."; await _accountService.TransferMoney(bankCard.Account, merchantAccount, viewModel.Amount, AmountConversionMode.TargetToSource, description); } catch (BankingServiceException ex) { ModelState.AddModelError(string.Empty, ex.Message); return(View(viewModel)); } catch (Exception ex) { Log.Error("Unexpected error has occurred while processing online payment", ex); ModelState.AddModelError(string.Empty, "Unexpected error has occurred. Please try again later."); return(View(viewModel)); } // redirect to merchant and pass Success status via query string var url = viewModel.RedirectUrl; url += url.Contains("?") ? "&status=success" : "?status=success"; return(Redirect(url)); }