Example #1
0
        public MakePaymentResult MakePayment(MakePaymentRequest request)
        {
            // Although the implementation of the datastores is quite straightforward, we will more likely than not, want to expand it
            // by making it runtime configurable, in a more dynamic fashion than an app.config file
            var dataStore = DataStoreService.GetAccountDataStore();

            var account = dataStore.GetAccount(request.DebtorAccountNumber);

            var result = new MakePaymentResult
            {
                Success = RulesService.IsMovementAuthorized(account, request.PaymentScheme, request.Amount)
            };

            if (!result.Success)
            {
                LogService.LogException(
                    new ConstraintException("Unable to make payment, rules engine rejected the operation"));
                return(result);
            }

            account.Balance -= request.Amount;

            // Update debtor account
            dataStore.UpdateAccount(account);
            // Question pending: does the creditor account not need to have the funds deposited?

            // Log the successfull operation
            LogService.LogOperation(request, result);

            return(result);
        }
        public void MakePayment_ReturnsFailureIfAccountNotFound()
        {
            // Arrange
            var dataStore = new Mock <IAccountDataStore>();

            dataStore.Setup(ds => ds.GetAccount(It.IsAny <string>())).Returns((Account)null);

            var accountDataStoreFactory = new Mock <IAccountDataStoreFactory>();

            accountDataStoreFactory.Setup(f => f.BuildAccountDataStore()).Returns(dataStore.Object);

            var validator = new Mock <IValidator>();

            validator.Setup(v => v.AccountCanMakePayment(It.IsAny <Account>())).Returns(true);

            var validatorFactory = new Mock <IValidatorFactory>();

            validatorFactory.Setup(vf => vf.BuildValidator(It.IsAny <MakePaymentRequest>())).Returns(validator.Object);

            var service = new PaymentService(accountDataStoreFactory.Object, validatorFactory.Object);

            // Act
            MakePaymentResult result = service.MakePayment(new MakePaymentRequest());

            // Assert
            Assert.IsFalse(result.Success);
            dataStore.Verify(ds => ds.UpdateAccount(It.IsAny <Account>()), Times.Never);
        }
        public void Test_PaymentService_MakePayment_Success()
        {
            // arrange
            MakePaymentRequest makePaymentRequest = new MakePaymentRequest
            {
                Amount = 50,
                CreditorAccountNumber = "PR2408",
                DebtorAccountNumber   = "DC2404",
                PaymentDate           = DateTime.Now,
                PaymentScheme         = PaymentScheme.Bacs
            };

            Account account = new Account
            {
                AccountNumber         = "PR2408",
                AllowedPaymentSchemes = AllowedPaymentSchemes.Bacs | AllowedPaymentSchemes.Chaps,
                Balance = 250,
                Status  = AccountStatus.Live,
            };

            MakePaymentResult makePaymentResult = new MakePaymentResult {
                Success = true
            };

            _accountDataStore.Setup(x => x.GetAccount(makePaymentRequest.DebtorAccountNumber)).Returns(account);
            _accountDataStoreFactory.Setup(x => x.AccountDataStore(It.IsAny <string>())).Returns(_accountDataStore.Object);
            _makePaymentRequestValidator.Setup(x => x.IsAccountValidToMakePayment(account, makePaymentRequest)).Returns(makePaymentResult);

            // act
            makePaymentResult = _paymentSrevice.MakePayment(makePaymentRequest);

            // assert
            Assert.AreEqual(account.Balance, 200);
            Assert.AreEqual(makePaymentResult.Success, true);
        }
Example #4
0
        public MakePaymentResult MakePayment(MakePaymentRequest request)
        {
            Account account = GetAccount(request.DebitorAccountNumber) ?? null;

            var result = new MakePaymentResult();

            if (IsPaymentAllowed(request, account))
            {
                try
                {
                    account.Balance -= request.Amount;
                    // A call to do the actual transfer should be here
                    result.Success = true;
                    _datastore.UpdateAccount(account);
                }
                catch (Exception e)
                {
                    Console.WriteLine("An error occurred while making the payment: '{0}'", e);
                }
            }
            else
            {
                result.Success = false;
            }

            return(result);
        }
Example #5
0
        public MakePaymentResult MakePayment(MakePaymentRequest request)
        {
            var result           = new MakePaymentResult();
            var dataStoreType    = ConfigurationManager.AppSettings["DataStoreType"] ?? String.Empty;
            var accountDataStore = _accountDataStoreFactory.Create(dataStoreType);
            var account          = accountDataStore.GetAccount(request.DebtorAccountNumber);

            if (account == null)
            {
                return(result);
            }

            var paymentRule = _paymentRuleFactory.Create(request.PaymentScheme);

            if (paymentRule.IsPaymentAllowed(account, request.Amount))
            {
                account.Balance -= request.Amount;
                accountDataStore.UpdateAccount(account);
                //Have incorporated unit of work so account check and update can be atomic
                accountDataStore.Commit();
                result.Success = true;
            }

            return(result);
        }
Example #6
0
        public void MakePaymentRequestWithInvalidPayementScheme()
        {
            Dictionary <String, Object> debitorAccount  = (Dictionary <String, Object>)context["DebitorAccount"];
            Dictionary <String, Object> creditorAccount = (Dictionary <String, Object>)context["CreditorAccount"];
            DateTime paymentDate = DateTime.Now;

            string creditorAccountNumber = creditorAccount["AccountNumber"].ToString();
            string debitorAccountNumber  = debitorAccount["AccountNumber"].ToString();

            decimal debitAmount = (decimal)context["DebitAmount"];

            // Object status = Enum.Parse(typeof(AccountStatus), debitorAccount["AccountStatus"].ToString());
            PaymentScheme debitorPaymentScheme = (PaymentScheme)Enum.Parse(typeof(PaymentScheme), debitorAccount["PaymentScheme"].ToString());

            //Get invalid payment scheme
            var values = Enum.GetValues(typeof(PaymentScheme));

            foreach (var val in values)
            {
                if (!(val.ToString().Equals(debitorAccount["PaymentScheme"].ToString())))
                {
                    debitorPaymentScheme = (PaymentScheme)Enum.Parse(typeof(PaymentScheme), val.ToString());
                    break;
                }
            }

            MakePaymentRequest request = new MakePaymentRequest(creditorAccountNumber,
                                                                debitorAccountNumber, debitAmount, paymentDate, debitorPaymentScheme);

            PaymentService    paymentService = new PaymentService();
            MakePaymentResult result         = paymentService.MakePayment(request);

            context["MakePaymentResult"] = result;
        }
Example #7
0
        public void VerifyPaymentResult(bool expectedResult)
        {
            MakePaymentResult actualResult = (MakePaymentResult)context["MakePaymentResult"];

            Assert.AreEqual(expectedResult, actualResult.Success, "Verify expected payment result");
            Console.WriteLine("Make payment expected result : [" + expectedResult + "], actual result : [" + actualResult.Success + "]");
        }
Example #8
0
        public MakePaymentResult MakePayment(MakePaymentRequest request)
        {
            var dataStoreType = ConfigurationManager.AppSettings["DataStoreType"];

            Account account = null;

            if (dataStoreType == "Backup")
            {
                var accountDataStore = new BackupAccountDataStore();
                account = accountDataStore.GetAccount(request.DebtorAccountNumber);
            }
            else
            {
                var accountDataStore = new AccountDataStore();
                account = accountDataStore.GetAccount(request.DebtorAccountNumber);
            }

            var result = new MakePaymentResult();

            CheckPaymentScheme(request, account, result);

            ProcessPayment(request, dataStoreType, account, result);

            return(result);
        }
Example #9
0
        public MakePaymentResult MakePayment(MakePaymentRequest request)
        {
            var result = new MakePaymentResult();

            Account account = _accountDataStore.GetAccount(request.DebtorAccountNumber);
            if (account != null)
            {
                IPaymentRequestValidator paymentRequestValidator = _paymentSchemeValidatorService.GetPaymentSchemeValidator(request.PaymentScheme);
                if (paymentRequestValidator == null)
                {
                    result.Success = false;
                }
                else
                {
                    result.Success = paymentRequestValidator.IsValid(account, request);
                }
            }

            if (result.Success)
            {
                account.Balance -= request.Amount;
                _accountDataStore.UpdateAccount(account);
            }

            return result;
        }
Example #10
0
        public MakePaymentResult MakePayment(MakePaymentRequest request)
        {
            var result = new MakePaymentResult()
            {
                Success = false
            };
            //NOTE : We could move this validation logic to PaymentController class
            var validator = _paymentValidator.IsValid(request);

            if (!validator.IsValid)
            {
                return(result);
            }

            // To check the payment scheme and validations
            var paymentScheme = _paymentFact.GetPaymentScheme(request.PaymentScheme);

            if (paymentScheme == null)
            {
                return(result);
            }

            var debtorAccount = _accountRepo.AccountDataStore.GetAccount(request.DebtorAccountNumber);

            if (paymentScheme.MakePayment(debtorAccount, request))
            {
                _accountRepo.AccountDataStore.UpdateAccount(debtorAccount);
                result.Success = true;
            }
            return(result);
        }
Example #11
0
        // Abstract away following private helper methods into seprate sub-classes based and
        // may consider into Factories and write test cases accordingly, BUT for now I decided
        // not to do this at these stage - kept is simple for the purpose of readability.
        // NOTE: The account.AllowedPaymentSchemes.HasFlag(xxx) can be refactored into Is<T>Valid()
        private static MakePaymentResult TakePayment(MakePaymentRequest paymentRequest, Account accountInfo)
        {
            var paymentResult = new MakePaymentResult();

            // TODO: Factory pattern for each type of payment!
            // For now just call appropriate helper methods
            switch (paymentRequest.PaymentScheme)
            {
            case PaymentScheme.Bacs:
                BacsPaymentProcess(accountInfo, paymentResult);
                break;

            case PaymentScheme.Chaps:
                ChapsPaymentProcess(accountInfo, paymentResult);
                break;

            case PaymentScheme.FasterPayments:
                FasterPaymentProcess(paymentRequest, accountInfo, paymentResult);
                break;

            default:
                throw new InvalidEnumArgumentException("Invalid PaymentScheme enum");
            }

            return(paymentResult);
        }
Example #12
0
        public MakePaymentResult MakePayment(IPaymentRequest request)
        {
            IAccount account = DataStore.GetAccount(request.DebtorAccountNumber);

            // Assume will be unsuccessful
            var result = new MakePaymentResult()
            {
                Success = false
            };

            // Conditions for success
            if (account != null && account.Status == AccountStatus.Live && account.Balance >= request.Amount &&
                account.AllowedPaymentSchemes.Contains(request.PaymentScheme))
            {
                result.Success = true;
            }

            if (result.Success)
            {
                account.Balance -= request.Amount;
                DataStore.UpdateAccount(account);
            }

            return(result);
        }
        public void Test_PaymentService_MakePayment_UnSuccess_when_Account_Is_Null()
        {
            // arrange
            MakePaymentRequest makePaymentRequest = new MakePaymentRequest
            {
                Amount = 50,
                CreditorAccountNumber = "PR2408",
                DebtorAccountNumber   = "DC2404",
                PaymentDate           = DateTime.Now,
                PaymentScheme         = PaymentScheme.Bacs
            };


            MakePaymentResult makePaymentResult = new MakePaymentResult {
                Success = false
            };

            _accountDataStore.Setup(x => x.GetAccount(makePaymentRequest.DebtorAccountNumber)).Returns <Account>(null);
            _accountDataStoreFactory.Setup(x => x.AccountDataStore(It.IsAny <string>())).Returns(_accountDataStore.Object);
            _makePaymentRequestValidator.Setup(x => x.IsAccountValidToMakePayment(null, makePaymentRequest)).Returns(makePaymentResult);

            // act
            makePaymentResult = _paymentSrevice.MakePayment(makePaymentRequest);

            // assert
            Assert.AreEqual(makePaymentResult.Success, false);
            _accountDataStore.Verify(x => x.UpdateAccount(null), Times.Never);
        }
Example #14
0
        public void MakePaymentNotEligible()
        {
            //arrange
            makePaymentRequest.Amount = 10;
            makePaymentRequest.DebtorAccountNumber = "12345";
            makePaymentRequest.PaymentScheme       = PaymentScheme.Bacs;
            makePaymentRequest.PaymentDate         = DateTime.Now;

            var makePaymentResult = new MakePaymentResult()
            {
                Success = false
            };

            var mockResolvePaymentValidator = new Mock <IPaymentValidator>();

            mockResolvePaymentValidator.SetupAllProperties();
            mockResolvePaymentValidator.Setup(x => x.CheckPaymentEligible(PaymentScheme.Bacs, It.IsAny <Account>(), It.IsAny <decimal>())).Returns(makePaymentResult);
            paymentService = new PaymentService(mockResolvePaymentValidator.Object);

            //act
            var result = paymentService.MakePayment(makePaymentRequest);

            //assert
            Assert.IsFalse(result.Success);
        }
Example #15
0
        public MakePaymentResult MakePayment(MakePaymentRequest request)
        {
            var result = new MakePaymentResult
            {
                Success = false
            };

            accountDataStores = AccountDataStores.Get();
            var accountDataStore = accountDataStores.FirstOrDefault(x => x.CheckAccountType());

            if (accountDataStore == null)
            {
                return(result);
            }

            account = accountDataStore.GetAccount(request.DebtorAccountNumber);

            if (account == null)
            {
                return(result);
            }

            if (!account.IsAllowedPaymentScheme(request.PaymentScheme))
            {
                return(result);
            }

            result.Success = account.Decrease(request.Amount);

            return(result);
        }
Example #16
0
        public MakePaymentResult MakePayment(MakePaymentRequest request)
        {
            var result = new MakePaymentResult {
                Success = false
            };

            if (request == null)
            {
                return(result);
            }

            IAccountDataStore accountDataStore = _accountDataStoreFactory.BuildAccountDataStore();

            IValidator validator = _validatorFactory.BuildValidator(request);

            Account account = accountDataStore.GetAccount(request.DebtorAccountNumber);

            if (account == null || !validator.AccountCanMakePayment(account))
            {
                return(result);
            }

            account.Balance -= request.Amount;

            accountDataStore.UpdateAccount(account);

            result.Success = true;

            return(result);
        }
Example #17
0
        public MakePaymentResult MakePayment(MakePaymentRequest request)
        {
            var datastore = _dataStoreFactory.Create(_appConfig.GetKeyValue("DataStoreType"));
            var account   = datastore.GetAccount(request.DebtorAccountNumber);

            var result = new MakePaymentResult();

            switch (request.PaymentScheme)
            {
            case PaymentScheme.Bacs:
                result.Success = _accountValidatorBacs.Validate(request, account);
                break;

            case PaymentScheme.FasterPayments:
                result.Success = _accountValidatorFasterPayments.Validate(request, account);
                break;

            case PaymentScheme.Chaps:
                result.Success = _accountValidatorChaps.Validate(request, account);
                break;
            }


            if (result.Success)
            {
                account.Balance -= request.Amount;
                datastore.UpdateAccount(account);
            }

            return(result);
        }
        public void MakePayment_ReturnsNotNull()
        {
            // Arrange
            var dataStore = new Mock <IAccountDataStore>();

            dataStore.Setup(ds => ds.GetAccount(It.IsAny <string>())).Returns(new Account());

            var accountDataStoreFactory = new Mock <IAccountDataStoreFactory>();

            accountDataStoreFactory.Setup(f => f.BuildAccountDataStore()).Returns(dataStore.Object);

            var validator = new Mock <IValidator>();

            validator.Setup(v => v.AccountCanMakePayment(It.IsAny <Account>())).Returns(true);

            var validatorFactory = new Mock <IValidatorFactory>();

            validatorFactory.Setup(vf => vf.BuildValidator(It.IsAny <MakePaymentRequest>())).Returns(validator.Object);

            var service = new PaymentService(accountDataStoreFactory.Object, validatorFactory.Object);

            // Act
            MakePaymentResult result = service.MakePayment(new MakePaymentRequest());

            // Assert
            Assert.IsNotNull(result);
        }
Example #19
0
 private static void BacsPaymentProcess(Account account, MakePaymentResult result)
 {
     if (account == null)
     {
         return;
     }
     result.Success = !account.AllowedPaymentSchemes.HasFlag(AllowedPaymentSchemes.Bacs);
 }
Example #20
0
        public void MakePaymentFasterPaymentRequestProcessReturnsTrue()
        {
            var reqPay = new MakePaymentRequest {
                PaymentScheme = PaymentScheme.FasterPayments
            };

            _res = _ps.MakePayment(reqPay);
            Assert.True(_res.Success);
        }
Example #21
0
        public MakePaymentResult Validate(Account account, decimal requestAmount = 0)
        {
            var result = new MakePaymentResult();

            if (account != null && account.AllowedPaymentSchemes.HasFlag(AllowedPaymentSchemes.Bacs))
            {
                result.Success = true;
            }
            return(result);
        }
Example #22
0
        public void Test()
        {
            MakePaymentResult result = _paymentService.MakePayment(_paymentRequest);

            Assert.True(result.Success);
            Assert.Equal(5, _account.Balance);
            _mockAccountDataStore.Verify(d => d.GetAccount(_account.AccountNumber), Times.Once);
            _mockPaymentSchemeValidationHandler.Verify(v => v.IsPaymentValid(_paymentRequest, _account), Times.Once);
            _mockAccountDataStore.Verify(d => d.UpdateAccount(_account), Times.Once);
        }
Example #23
0
        public void Payment_Succeeds()
        {
            // Arrange
            PaymentService service = new PaymentService(dataStoreMock.Object);

            // Act
            MakePaymentResult result = service.MakePayment(requestMock.Object);

            // Assert
            Assert.IsTrue(result.Success, "Should succeed when all conditions are met");
        }
        protected override void Observe()
        {
            var paymentRequestBuilder = new PaymentRequestBuilder()
                                        .WithDebtorAccountNumber(accountNumber)
                                        .WithAmount(1000m)
                                        .WithPaymentDate(DateTime.Now)
                                        .WithPaymentScheme(PaymentScheme.FasterPayments)
                                        .Build();

            makePaymentResult = paymentService.MakePayment(paymentRequestBuilder);
        }
        public void Test_Verify_ChapsPaymentSchemeValidator_Result_With_Null_Account()
        {
            // arrange
            ChapsPaymentSchemeValidator chapsPaymentSchemeValidator = new ChapsPaymentSchemeValidator();

            // act
            MakePaymentResult makePaymentResult =
                chapsPaymentSchemeValidator.IsAccountValid(null, _makePaymentRequest);

            // assert
            Assert.IsFalse(makePaymentResult.Success);
        }
Example #26
0
        public MakePaymentResult MakePayment(MakePaymentRequest request)
        {
            var account = _accountService.GetAccount(request.DebtorAccountNumber);

            if (_paymentsValidationService.ValidatePayment(account, request.Amount, request.PaymentScheme))
            {
                _accountService.UpdateAccount(account, request.Amount);
                return(MakePaymentResult.OK());
            }

            return(MakePaymentResult.Fail());
        }
        public void WhenValidatorReturnsFalseResultIsFalse()
        {
            _mockValidator.Setup(a => a.ValidatePayment(It.IsAny <Account>(), It.IsAny <decimal>())).Returns(false);

            PaymentService sut = GetSystemUnderTest();

            MakePaymentResult result = sut.MakePayment(_paymentRequest);

            _mockAccountAccess.Verify(a => a.GetAccount(_paymentRequest.DebtorAccountNumber), Times.Once);
            _mockAccountAccess.Verify(a => a.UpdateAccount(It.IsAny <Account>()), Times.Never);

            Assert.False(result.Success);
        }
Example #28
0
        public MakePaymentResult Validate()
        {
            var result = new MakePaymentResult();

            if (!ValidateAccount())
            {
                return(result);
            }

            result.Success = Account.AllowedPaymentSchemes.HasFlag(AllowedPaymentSchemes.Bacs);

            return(result);
        }
Example #29
0
        public void Payment_FailsWhenPaymentSchemeNotAvailable()
        {
            // Arrange
            PaymentService service = new PaymentService(dataStoreMock.Object);

            requestMock.Setup(x => x.PaymentScheme).Returns(PaymentScheme.FasterPayments);

            // Act
            MakePaymentResult result = service.MakePayment(requestMock.Object);

            // Assert
            Assert.IsFalse(result.Success, "Should fail when payment scheme not available");
        }
        public MakePaymentResult MakePayment(MakePaymentRequest request)
        {
            Account account = _accountDataStore.GetAccount(request.DebtorAccountNumber);

            MakePaymentResult result = _validationService.Validate(request.PaymentScheme, account, request);

            if (result.Success)
            {
                account.Balance -= request.Amount;
                _accountDataStore.UpdateAccount(account);
            }
            return(result);
        }