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"); } } }
public void CreateCard_UsingPCardFactory_ReturnsCreditCardInstance() { IBankCard platinumCard = platinumCardCreator.CreateAndSetInitialDeposit(1000); platinumCard.Purchase(100); Assert.AreEqual(920, platinumCard.CheckBalance()); }
public void CreateCard_UsingCreditCardFactory_ReturnsCreditCardInstance() { IBankCard creditCard = creditCardCreator.CreateAndSetInitialDeposit(1000); creditCard.Purchase(100); Assert.AreEqual(910, creditCard.CheckBalance()); }
public void CreateCard_UsingDebitCardFactory_ReturnsDebitCardInstance() { IBankCard debitCard = debitCardCreator.CreateAndSetInitialDeposit(1000); debitCard.Purchase(100); Assert.AreEqual(900, debitCard.CheckBalance()); }
/// <summary> /// Additional method with some buisness logic. /// Despite its name, the Creator's primary responsibility is not creating products. /// Usually, it contains some core business logic that relies on Product objects, /// returned by the factory method. Subclasses can indirectly change that business logic /// by overriding the factory method and returning a different type of product from it. /// </summary> public IBankCard CreateAndSetInitialDeposit(float initialDeposit) { IBankCard newCard = CreateCard(); newCard.Deposit(initialDeposit); return(newCard); }
private bool SendAuthorizationRequest(int pin, IBankCard card, decimal transactionAmount, out bool transactionAuthorized, out AuthorizationResponseCode authorizationResponseCode) { transactionAuthorized = false; AuthorizationResponse authorizationResponse = card.AuthorizeTransaction(new TransactionEntities.AuthorizationRequest() { CardNumber = card.CardNumber, Pin = pin, TransactionAmount = transactionAmount }); authorizationResponseCode = (AuthorizationResponseCode)authorizationResponse.ResponseCode; transactionAuthorized = authorizationResponseCode == AuthorizationResponseCode.Authorised; return(transactionAuthorized); }
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)); }
public bool BuyItems(VendingMachineItem selectedItem, int itemAmount, int pin, IBankCard card) { //Validate the users input and environment will allow them to make a valid purchase if (!AreVendingItemsPresent(VendingItemAmount)) { Console.WriteLine("No Items Available To Purchase"); return(false); } else if (!IsUserSelectionValid(itemAmount, VendingItemAmount)) { Console.WriteLine($"Ensure Item Amount Is Valid"); return(false); } decimal transactionAmount = CalculateTransactionAmount(selectedItem, itemAmount); //Validate if (SendAuthorizationRequest(pin, card, transactionAmount, out bool transactionAuthorized, out AuthorizationResponseCode authorizationResponseCode)) { VendingItemAmount -= itemAmount; } Console.WriteLine($"{card.Name}: Transaction[{authorizationResponseCode.ToString()}]"); return(transactionAuthorized); }