// Simple check to see if model is valid
        // This is only used for final validation to detect account changes or tampering
        // therefore does not need to feed back errors to user
        public bool Validate(PaymentOptionsVm paymentOptionsVm)
        {
            PaymentOptionsVmValidator validator = new PaymentOptionsVmValidator();
            ValidationResult          result    = validator.Validate(paymentOptionsVm);

            return(result.IsValid);
        }
Esempio n. 2
0
        // Used to re-instate user entries after loading fresh data from CaseFlow or from cache
        public void UpdateFieldsFromUserEntries(IUserIdentity loggedInUser, PaymentOptionsVm paymentOptionsToUpdate, PaymentOptionsVm paymentOptionsUserEntries)
        {
            paymentOptionsToUpdate.DiscountAccepted      = paymentOptionsUserEntries.DiscountAccepted;
            paymentOptionsToUpdate.SelectedPaymentOption = paymentOptionsUserEntries.SelectedPaymentOption;

            paymentOptionsToUpdate.FullPaymentSelectedSourceOfFunds  = paymentOptionsUserEntries.FullPaymentSelectedSourceOfFunds;
            paymentOptionsToUpdate.FullPaymentSourceOfFundsOtherText = paymentOptionsUserEntries.FullPaymentSourceOfFundsOtherText;

            paymentOptionsToUpdate.PartialPaymentAmount = paymentOptionsUserEntries.PartialPaymentAmount;
            paymentOptionsToUpdate.PartialPaymentSelectedSourceOfFunds  = paymentOptionsUserEntries.PartialPaymentSelectedSourceOfFunds;
            paymentOptionsToUpdate.PartialPaymentSourceOfFundsOtherText = paymentOptionsUserEntries.PartialPaymentSourceOfFundsOtherText;

            paymentOptionsToUpdate.DirectDebitSelectedFrequency = paymentOptionsUserEntries.DirectDebitSelectedFrequency;
            paymentOptionsToUpdate.DirectDebitSelectedStartDate = paymentOptionsUserEntries.DirectDebitSelectedStartDate;
            paymentOptionsToUpdate.DirectDebitAmount            = paymentOptionsUserEntries.DirectDebitAmount;
            paymentOptionsToUpdate.AverageMonthlyPayment        = paymentOptionsUserEntries.AverageMonthlyPayment;
            paymentOptionsToUpdate.MonthlyDisposableIncome      = paymentOptionsUserEntries.MonthlyDisposableIncome;
            paymentOptionsToUpdate.SelectedPlanSetupOption      = paymentOptionsUserEntries.SelectedPlanSetupOption;
            paymentOptionsToUpdate.IandELessThanOrIs12MonthsOld = paymentOptionsUserEntries.IandELessThanOrIs12MonthsOld;

            // User should only have provided Direct Debit Email Address if they are anonymous (not logged in)
            // Email will have been pre-populated with user's email address during building of VM if they are logged in
            if (!loggedInUser.IsLoggedInUser)
            {
                paymentOptionsToUpdate.DirectDebitEmailAddress = paymentOptionsUserEntries.DirectDebitEmailAddress;
            }

            // User only ticks T&C box when anonymous. Will be defaulted to true by builder if logged in.
            if (!loggedInUser.IsLoggedInUser)
            {
                paymentOptionsToUpdate.AcceptTermsAndConditions = paymentOptionsUserEntries.AcceptTermsAndConditions;
            }
        }
Esempio n. 3
0
        public IActionResult Cancel(Guid id, PaymentOptionsVm paymentOptionsVmPostedBack)
        {
            // Restore VM from state field, so that we get lists and all other fields required to build view
            var paymentOptionsVm =
                DeserialiseModel <PaymentOptionsVm>(paymentOptionsVmPostedBack.InitialState);

            Debug.Assert(paymentOptionsVm.InitialState == null,
                         "Serialisation Loop Detected - InitialState should be marked as JsonIgnore");

            // Carry state through
            paymentOptionsVm.InitialState = paymentOptionsVmPostedBack.InitialState;

            // Place form field selections into restored VM
            _buildPaymentOptionsVmService.UpdateFieldsFromUserEntries(LoggedInUser, paymentOptionsVm,
                                                                      paymentOptionsVmPostedBack);

            // Construct model for Cancel view
            var cancelVm = new ReturnToFormVm
            {
                State                = SerialiseModel(paymentOptionsVm),
                StateFieldName       = nameof(PaymentOptionsStateVm.FilledInState),
                StateType            = nameof(PaymentOptionsVm),
                ReturnControllerName = ControllerName,
                ReturnActionName     = nameof(Change)
            };

            return(View("PaymentCancel", cancelVm));
        }
Esempio n. 4
0
        public void DirectDebit_SelectedPlanSetupOption_OtherPaymentOffer()
        {
            _accountVm = new PaymentOptionsVm()
            {
                AcceptTermsAndConditions     = true,
                AverageMonthlyPayment        = 48.00M,
                DirectDebitAmount            = 48.00M,
                MonthlyDisposableIncome      = 0.00M,
                DirectDebitEmailAddress      = "*****@*****.**",
                DirectDebitSelectedFrequency = "monthly",
                DirectDebitSelectedStartDate = DateTime.Now.Date.ToString(),
                DiscountAccepted             = false,
                DirectDebitStartDateEarliest = DateTime.Now.Date.AddDays(-1),
                DirectDebitStartDateLatest   = DateTime.Now.AddDays(1),
                DiscountAmount               = 0.00M,
                DiscountBalanceAvailable     = false,
                DiscountPercentage           = 0.00M,
                IandELessThanOrIs12MonthsOld = true,
                SelectedPaymentOption        = "direct-debit",
                FullPaymentBalance           = 123.45M,
                WithLowellSolicitors         = false,
                OutstandingBalance           = 123.45M,
                SelectedPlanSetupOption      = PlanSetupOptions.OtherPaymentOffer
            };

            var result = _validator.Validate(_accountVm);

            Assert.IsTrue(result.IsValid);
        }
        public void Validate_WhenModelIsInvalid_ReturnsFalse()
        {
            PaymentOptionsVm paymentOptionsVm = new PaymentOptionsVm()
            {
                SelectedPaymentOption = PaymentOptionsSelectionsVm.Values.PleaseSelect
            };

            Assert.IsFalse(_paymentOptionsValidatorProcess.Validate(paymentOptionsVm));
        }
        public void Validate_WhenModelIsValid_ReturnsTrue()
        {
            // Simplest possible valid scenario
            PaymentOptionsVm paymentOptionsVm = new PaymentOptionsVm()
            {
                SelectedPaymentOption            = PaymentOptionsSelectionsVm.Values.FullPayment,
                FullPaymentSelectedSourceOfFunds = "anything"
            };

            Assert.IsTrue(_paymentOptionsValidatorProcess.Validate(paymentOptionsVm));
        }
Esempio n. 7
0
        public void ShowPayOffDiscountedDDPlanWarning_DDPlanNotInPlace_DiscountNotAccepted()
        {
            PaymentOptionsVm vm = new PaymentOptionsVm()
            {
                PlanInPlace       = false,
                PlanIsDirectDebit = false,
                DiscountedBalancePreviouslyAccepted = false
            };

            Assert.IsFalse(vm.ShowPayOffDiscountedDDPlanWarning);
        }
Esempio n. 8
0
 public DirectDebitDetailsVm Build(PaymentOptionsVm paymentOptionsVm)
 {
     return(new DirectDebitDetailsVm()
     {
         LowellRef = paymentOptionsVm.LowellReference,
         DiscountAvailable = paymentOptionsVm.DiscountedBalancePreviouslyAccepted || paymentOptionsVm.DiscountBalanceAvailable,
         PaymentAmount = paymentOptionsVm.DirectDebitAmount,
         PaymentFrequency = paymentOptionsVm.DirectDebitSelectedFrequency,
         DiscountSelected = paymentOptionsVm.DiscountAccepted,
         SelectedPlanSetupOption = paymentOptionsVm.SelectedPlanSetupOption
     });
 }
Esempio n. 9
0
        public RequestDataModel CreateDataModel(PaymentOptionsVm accountVm)
        {
            var requestDataModel = new RequestDataModel();

            decimal?amount;

            if (accountVm.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.FullPayment)
            {
                amount = accountVm.FullPaymentAmountDerived;
            }
            else
            {
                amount = accountVm.PartialPaymentAmount;
            }

            // Should never be null, as validated with Fluent
            Debug.Assert(amount != null, "amount != null");

            requestDataModel.api                   = _verifoneSetting.ApiVersion;
            requestDataModel.merchantid            = _verifoneSetting.Merchant.MerchantId;
            requestDataModel.systemid              = _verifoneSetting.Merchant.SystemId;
            requestDataModel.systemguid            = _verifoneSetting.Merchant.SystemGuid;
            requestDataModel.merchantreference     = accountVm.VerifoneTransactionGuid.ToString();
            requestDataModel.returnurlxml          = $"<returnurl>{_verifoneSetting.CompletionUrlOverride}</returnurl>";
            requestDataModel.merchanttemplateid    = _verifoneSetting.Template.MerchantTemplateId.SetupPaymentPlan;
            requestDataModel.languagetemplateid    = 1;
            requestDataModel.capturemethod         = 12;
            requestDataModel.processingidentifier  = 1;
            requestDataModel.accountid             = _verifoneSetting.Merchant.AccountId;
            requestDataModel.transactionvalue      = amount.Value;
            requestDataModel.tokenidxml            = "";
            requestDataModel.registertoken         = "false";
            requestDataModel.tokenexpirationdate   = DateTime.Now.AddYears(4).ToString("ddMMyyyy");
            requestDataModel.allowedpaymentschemes = _verifoneSetting.AllowedPaymentSchemes;
            requestDataModel.allowedpaymentmethods = "1";
            requestDataModel.description           = "Payment to Lowell account " + accountVm.LowellReference;
            requestDataModel.firstname             = "";
            requestDataModel.lastname              = "";
            requestDataModel.email                 = "";
            requestDataModel.address1              = "";
            requestDataModel.address2              = "";
            requestDataModel.postcode              = "";
            requestDataModel.town                  = "";
            requestDataModel.totalamount           = accountVm.OutstandingBalance;
            requestDataModel.productname           = "Payment to Lowell account " + accountVm.LowellReference;
            requestDataModel.productcode           = accountVm.LowellReference;
            requestDataModel.processCPC            = false;
            requestDataModel.payerauthxml          = "";

            return(requestDataModel);
        }
        public void CreateDataModel_WhenSelectedPaymentOptionNotFull_TransactionValueIsPartialPaymentAmount()
        {
            PaymentOptionsVm paymentOptionsVm = new PaymentOptionsVm()
            {
                SelectedPaymentOption   = PaymentOptionsSelectionsVm.Values.PartialPayment,
                VerifoneTransactionGuid = "fb3ce06f-af36-40d4-a88b-dab5f39b0893",
                PartialPaymentAmount    = 987.65m,
                LowellReference         = "anyoldref",
                OutstandingBalance      = 211.12m
            };

            RequestDataModel requestDataModel = _createVerifoneRequestProcess.CreateDataModel(paymentOptionsVm);

            string tokenexpirationdate = DateTime.Now.AddYears(4).ToString("ddMMyyyy");

            Assert.AreEqual(null, requestDataModel.api);                               // ConfigurationManager.AppSettings["Verifone:PostData:Api"]
            Assert.AreEqual(null, requestDataModel.merchantid);                        // ConfigurationManager.AppSettings["Verifone:Merchant:MerchantId"]
            Assert.AreEqual(null, requestDataModel.systemid);                          // ConfigurationManager.AppSettings["Verifone:Merchant:SystemId"]
            Assert.AreEqual(null, requestDataModel.systemguid);                        // ConfigurationManager.AppSettings["Verifone:Merchant:SystemGuid"])
            Assert.AreEqual("fb3ce06f-af36-40d4-a88b-dab5f39b0893", requestDataModel.merchantreference);
            Assert.AreEqual("<returnurl></returnurl>", requestDataModel.returnurlxml); // $"<returnurl>{ConfigurationManager.AppSettings["Verifone:Url:CompletionUrlOverride"]}</returnurl>";
            Assert.AreEqual(null, requestDataModel.merchanttemplateid);                // ConfigurationManager.AppSettings["Verifone:Template:MerchantTemplateId:SetupPaymentPlan"]
            Assert.AreEqual(1, requestDataModel.languagetemplateid);
            Assert.AreEqual(12, requestDataModel.capturemethod);
            Assert.AreEqual(1, requestDataModel.processingidentifier);
            Assert.AreEqual(null, requestDataModel.accountid); // ConfigurationManager.AppSettings["Verifone:Merchant:AccountId"]
            Assert.AreEqual(987.65m, requestDataModel.transactionvalue);
            Assert.AreEqual("", requestDataModel.tokenidxml);
            Assert.AreEqual("false", requestDataModel.registertoken);
            Assert.AreEqual(tokenexpirationdate, requestDataModel.tokenexpirationdate);
            Assert.AreEqual(null, requestDataModel.allowedpaymentschemes); // ConfigurationManager.AppSettings["Verifone:PostData:AllowedPaymentSchemes"]
            Assert.AreEqual("1", requestDataModel.allowedpaymentmethods);
            Assert.AreEqual("Payment to Lowell account anyoldref", requestDataModel.description);
            Assert.AreEqual("", requestDataModel.firstname);
            Assert.AreEqual("", requestDataModel.lastname);
            Assert.AreEqual("", requestDataModel.email);
            Assert.AreEqual("", requestDataModel.address1);
            Assert.AreEqual("", requestDataModel.address2);
            Assert.AreEqual("", requestDataModel.postcode);
            Assert.AreEqual("", requestDataModel.town);
            Assert.AreEqual(211.12m, requestDataModel.totalamount);
            Assert.AreEqual("Payment to Lowell account anyoldref", requestDataModel.productname);
            Assert.AreEqual("anyoldref", requestDataModel.productcode);
            Assert.AreEqual(false, requestDataModel.processCPC);
            Assert.AreEqual("", requestDataModel.payerauthxml);

            Assert.Inconclusive("Unable to unit test completely. Should be taking IApplicationSettingsReader as a method parameter, so as to be able to mock config.");

            Assert.Inconclusive("Make internal method that takes token expiration date, so that it can be unit tested in detail.");
        }
Esempio n. 11
0
        public void Initialise()
        {
            _validator = new PaymentOptionsVmValidator();
            _accountVm = new PaymentOptionsVm()
            {
                OutstandingBalance       = 100,
                AcceptTermsAndConditions = true,
                SelectedPaymentOption    = PaymentOptionsSelectionsVm.Values.FullPayment,

                DirectDebitStartDateEarliest = new DateTime(2018, 8, 28),
                DirectDebitStartDateLatest   = new DateTime(2018, 8, 29),
                DirectDebitSelectedStartDate = "28/08/2018"
            };
        }
        private PaymentOptionsVm ConvertToPaymentOptionsVm(string seralisedState)
        {
            try
            {
                PaymentOptionsVm paymentOptionsVm = DeserialiseModel <PaymentOptionsVm>(seralisedState);

                return(paymentOptionsVm);
            }
            catch (Exception e)
            {
                Logger.LogError($"Failed to convert to PaymentVm. Exception details - {e.Message}");
            }

            return(null);
        }
        public async Task <IBuildDirectDebitPlanOverviewVmValidationResult> ValidateAndBuild(
            IUserIdentity loggedInUser, IApplicationSessionState applicationSessionState, Guid lowellReferenceSurrogateKey,
            PaymentOptionsVm paymentOptionsVmWithUserEntries, DirectDebitDetailsVm directDebitDetailsVmWithUserEntries, string caseflowUserId)
        {
            //
            // Payment Options - reconstruct from CaseFlow, populate user entris  and validate clean
            //

            PaymentOptionsVm paymentOptionsVm = await _buildPaymentOptionsVmService.Build(loggedInUser, applicationSessionState, lowellReferenceSurrogateKey, caseflowUserId);

            _buildPaymentOptionsVmService.UpdateFieldsFromUserEntries(loggedInUser, paymentOptionsVm, paymentOptionsVmWithUserEntries);

            if (!_paymentOptionsVmValidatorProcess.Validate(paymentOptionsVm))
            {
                return new ValidationResult()
                       {
                           IsValid = false
                       }
            }
            ;

            //
            // Direct Debit Details - reconstruct from fresh payment options, populate user entris and validate clean
            //
            DirectDebitDetailsVm directDebitDetailsVm = _buildDirectDebitDetailsVmService.Build(paymentOptionsVm);

            _buildDirectDebitDetailsVmService.UpdateFieldsFromUserEntries(directDebitDetailsVm, directDebitDetailsVmWithUserEntries);

            if (!_directDebitDetailsVmValidatorProcess.Validate(directDebitDetailsVm))
            {
                return new ValidationResult()
                       {
                           IsValid = false
                       }
            }
            ;

            //
            // Return valid result with overview built clean
            //
            return(new ValidationResult()
            {
                IsValid = true,
                DirectDebitPlanOverviewVm = Build(paymentOptionsVm, directDebitDetailsVm)
            });
        }
    }
}
        public async Task <ActionResult> Index(PaymentCancelledDto dto)
        {
            if (dto.PaymentStateType == nameof(PaymentOptionsVm))
            {
                PaymentOptionsVm vm = DeserialiseModel <PaymentOptionsVm>(dto.PaymentState);

                if (ApplicationSessionState.LogPaymentResult)
                {
                    await _webActivityService.LogOneOffPaymentCancelled(vm.LowellReference, LoggedInUserId, vm.SelectedPaymentOption == "partial-payment", vm.DiscountAccepted);

                    ApplicationSessionState.LogPaymentResult = false;
                }
            }

            if (dto.PaymentStateType == nameof(DirectDebitDetailsVm))
            {
                var vm = DeserialiseModel <DirectDebitDetailsVm>(dto.PaymentState);

                if (ApplicationSessionState.LogSetUpPlanResult)
                {
                    if (vm.DiscountSelected)
                    {
                        await LogDiscountDirectDebitCancelled(vm);
                    }
                    else
                    {
                        await LogDirectDebitCancelled(vm);
                    }

                    ApplicationSessionState.LogSetUpPlanResult = false;
                }
            }

            if (dto.PaymentStateType == nameof(AmendDirectDebitVm))
            {
                var vm = DeserialiseModel <AmendDirectDebitVm>(dto.PaymentState);

                if (ApplicationSessionState.LogSetUpPlanResult)
                {
                    await LogAmendDirectDebitCancelled(vm);

                    ApplicationSessionState.LogSetUpPlanResult = false;
                }
            }

            return(View());
        }
        public void RaisePaymentEvent_PageVisited(PaymentOptionsVm vm, string userId, string planType)
        {
            string plan_status = vm.PlanInPlace ? "Payment against Plan" : "No Plan in Place";

            plan_status = !String.IsNullOrEmpty(vm.ArrearsMessage) ? "Plan Arrears Payment" : plan_status;

            vm.GtmEvents.Add(new GtmEvent()
            {
                gtm_event          = GtmEvents.PaymentEvent,
                step               = PaymentSteps.Step1VisitMakeAPaymentPage,
                discount_available = vm.DiscountBalanceAvailable ? "Discount available" : "No discount available",
                plan_type          = planType,
                plan_status        = plan_status,
                guid               = String.IsNullOrEmpty(userId) ? null : userId,
                user_status        = String.IsNullOrEmpty(userId) ? "Not Logged In" : "Logged In"
            });
        }
Esempio n. 16
0
        private async Task LogDiscountDirectDebitCompleteFailure(PaymentOptionsVm paymentOptionsVm)
        {
            if (paymentOptionsVm.SelectedPlanSetupOption.HasValue)
            {
                switch (paymentOptionsVm.SelectedPlanSetupOption.Value)
                {
                case PlanSetupOptions.AverageSetupValue:
                {
                    await _webActivityService.LogDiscountDirectDebitPaymentASVOptionCompleteFailed(paymentOptionsVm.LowellReference,
                                                                                                   LoggedInUserId);

                    break;
                }

                case PlanSetupOptions.DisposableIncome:
                {
                    await _webActivityService.LogDiscountDirectDebitDIOptionCompleteFailed(paymentOptionsVm.LowellReference,
                                                                                           LoggedInUserId);

                    break;
                }

                case PlanSetupOptions.OtherPaymentOffer:
                {
                    if (paymentOptionsVm.IandENotAvailable || !paymentOptionsVm.IandELessThanOrIs12MonthsOld)
                    {
                        await _webActivityService.LogDiscountDirectDebitMyOfferOptionCompleteFailedWithNoIandE(paymentOptionsVm.LowellReference,
                                                                                                               LoggedInUserId);
                    }
                    else if (paymentOptionsVm.MonthlyDisposableIncome > 0)
                    {
                        await _webActivityService.LogDiscountDirectDebitMyOfferOptionCompleteFailedWithPositiveIandE(paymentOptionsVm.LowellReference,
                                                                                                                     LoggedInUserId);
                    }
                    else
                    {
                        await _webActivityService.LogDiscountDirectDebitMyOfferOptionCompleteFailedWithNegativeIandE(paymentOptionsVm.LowellReference,
                                                                                                                     LoggedInUserId);
                    }

                    break;
                }
                }
            }
        }
Esempio n. 17
0
        public async Task <IActionResult> Index(Guid id, PaymentOptionsVm paymentOptionsVmPostedBack)
        {
            // Restore VM from state field, so that we get lists and all other fields required to build view
            var paymentOptionsVm =
                DeserialiseModel <PaymentOptionsVm>(paymentOptionsVmPostedBack.InitialState);

            Debug.Assert(paymentOptionsVm.InitialState == null,
                         "Serialisation Loop Detected - InitialState should be marked as JsonIgnore");

            // Carry state through
            paymentOptionsVm.InitialState = paymentOptionsVmPostedBack.InitialState;

            // Place form field selections into restored VM
            _buildPaymentOptionsVmService.UpdateFieldsFromUserEntries(
                LoggedInUser, paymentOptionsVm, paymentOptionsVmPostedBack);

            return(await ProcessPaymentOptionsPost(id, paymentOptionsVm));
        }
        public DirectDebitPlanOverviewVm Build(PaymentOptionsVm accountVm, DirectDebitDetailsVm directDebitDetailsVm)
        {
            // Should never be null, as validated with Fluent
            Debug.Assert(accountVm.DirectDebitAmount != null, "accountVm.DirectDebitPayment.Amount != null");

            int totalMonths = _directDebitTermCalculator.CalculateTermInMonths(
                accountVm.FullPaymentAmountDerived, accountVm.DirectDebitAmount.Value,
                accountVm.DirectDebitSelectedFrequency);
            int years  = totalMonths / 12;
            int months = totalMonths % 12;

            DirectDebitPlanOverviewVm directDebitPlanOverview = new DirectDebitPlanOverviewVm()
            {
                SortCode           = directDebitDetailsVm.SortCode,
                AccountNumber      = directDebitDetailsVm.AccountNumber,
                AccountHoldersName = directDebitDetailsVm.AccountHoldersName,
                ClientName         = accountVm.ClientName,
                LowellReference    = accountVm.LowellReference,
                PaymentAmount      = accountVm.DirectDebitAmount.Value,
                PaymentType        = AccountMessages.DirectDebit,
                StartDate          = accountVm.DirectDebitSelectedStartDate,
                Frequency          =
                    _directDebitFrequencyTranslator.TranslateClientScriptCompatibleValueToDescription(
                        accountVm.DirectDebitSelectedFrequency),
                GuaranteeRead = directDebitDetailsVm.AcceptDirectDebitGuarantee,
                PlanTotal     = accountVm.DiscountedBalancePreviouslyAccepted
                    ? accountVm.DiscountedBalance
                    : accountVm.OutstandingBalance,
                DiscountAccepted        = accountVm.DiscountAccepted,
                DiscountAmount          = accountVm.DiscountAmount,
                EmailAddress            = accountVm.DirectDebitEmailAddress,
                DiscountAvailable       = directDebitDetailsVm.DiscountAvailable,
                PaymentFrequency        = directDebitDetailsVm.PaymentFrequency,
                TermYears               = years,
                TermMonths              = months,
                SelectedPlanSetupOption = directDebitDetailsVm.SelectedPlanSetupOption
            };

            return(directDebitPlanOverview);
        }
Esempio n. 19
0
        public string CreatePayload(PaymentOptionsVm accountVm)
        {
            using (var sr = new StreamReader("Verifone/PostData-template.txt"))
            {
                _postdataTemplateXml = sr.ReadToEnd();
            }

            using (var sr = new StreamReader("Verifone/EftRequest-template.txt"))
            {
                _requestTemplateXml = sr.ReadToEnd();
            }

            var requestDataModel = _createVerifoneRequestProcess.CreateDataModel(accountVm);

            var formattedRequestXml = _requestTemplateXml.FormatWith(requestDataModel);

            var htmlEncodedRequest = HttpUtility.HtmlEncode(formattedRequestXml);

            var postDataModel = _createVerifonePostProcess.CreateDataModel(htmlEncodedRequest);

            var formattedPostDataXml = _postdataTemplateXml.FormatWith(postDataModel);

            return(formattedPostDataXml);
        }
Esempio n. 20
0
        //
        // Private
        //
        private async Task <IActionResult> ProcessPaymentOptionsPost(Guid lowellReferenceSurrogateKey,
                                                                     PaymentOptionsVm paymentOptionsVmWithUserEntries)
        {
            if (!ModelState.IsValid)
            {
                var outstandingPayment = paymentOptionsVmWithUserEntries.FullPaymentAmountDerived;

                bool isDirectDebitPayment =
                    paymentOptionsVmWithUserEntries.SelectedPlanSetupOption == PlanSetupOptions.AverageSetupValue ||
                    paymentOptionsVmWithUserEntries.SelectedPlanSetupOption == PlanSetupOptions.DisposableIncome ||
                    paymentOptionsVmWithUserEntries.SelectedPlanSetupOption == PlanSetupOptions.OtherPaymentOffer;
                if (isDirectDebitPayment && paymentOptionsVmWithUserEntries.DirectDebitAmount > outstandingPayment)
                {
                    ModelState.Clear();
                    paymentOptionsVmWithUserEntries.DirectDebitAmount = null;
                    ModelState.AddModelError(nameof(PaymentOptionsVm.SelectedPlanSetupOption),
                                             $"{ValidationMessages.AmountGreaterThenAllowed}{outstandingPayment}");
                }
                else if (!isDirectDebitPayment && paymentOptionsVmWithUserEntries.PartialPaymentAmount.HasValue &&
                         paymentOptionsVmWithUserEntries.PartialPaymentAmount.Value >
                         outstandingPayment)
                {
                    ModelState.Clear();
                    paymentOptionsVmWithUserEntries.PartialPaymentAmount = null;
                    ModelState.AddModelError(nameof(PaymentOptionsVm.PartialPaymentAmount),
                                             $"{ValidationMessages.AmountGreaterThenAllowed}{outstandingPayment}");
                }
                else if (!isDirectDebitPayment && paymentOptionsVmWithUserEntries.PartialPaymentAmount.HasValue &&
                         paymentOptionsVmWithUserEntries.PartialPaymentAmount.Value < 1.0m
                         )
                {
                    ModelState.Clear();
                    paymentOptionsVmWithUserEntries.PartialPaymentAmount = null;
                    ModelState.AddModelError(nameof(PaymentOptionsVm.PartialPaymentAmount),
                                             $"{ValidationMessages.AmountLessThanOneGbp}");
                }

                Debug.Assert(paymentOptionsVmWithUserEntries.InitialState != null, "Initial state must be stashed to re-create view on round-trip");
                return(View(paymentOptionsVmWithUserEntries));
            }

            if (paymentOptionsVmWithUserEntries.SelectedPaymentOption ==
                PaymentOptionsSelectionsVm.Values.PartialPayment ||
                paymentOptionsVmWithUserEntries.SelectedPaymentOption ==
                PaymentOptionsSelectionsVm.Values.FullPayment)
            {
                OneOffPaymentReviewVm oneOffPaymentReviewVm;
                {
                    //
                    // IMPORTANT: Validates models again versus CaseFlow, to ensure no tamper or state changes since
                    // started process of entering payment information
                    //
                    var result = await _buildOneOffPaymentReviewVmService.ValidateAndBuild(
                        LoggedInUser, ApplicationSessionState, lowellReferenceSurrogateKey,
                        paymentOptionsVmWithUserEntries, GetCaseflowUserId());

                    if (result.IsValid == false)
                    {
                        return(View("ValidationFailed"));
                    }

                    oneOffPaymentReviewVm = result.OneOffPaymentReviewVm;
                }

                // Stash state of payment options form, so that 'change' feature can return
                oneOffPaymentReviewVm.FilledInPaymentOptionsState =
                    SerialiseModel(paymentOptionsVmWithUserEntries);

                var oneOffPaymentDto = _mapper.Map <OneOffPaymentReviewVm, OneOffPaymentDto>(oneOffPaymentReviewVm);

                _logger.LogDebug("Before AddVerifoneTransactionAsync");

                await _verifonePaymentProviderService.AddVerifoneTransactionAsync(
                    new VerifoneTransactionDto
                {
                    CompanyCode     = 1, //LFL
                    TransactionGuid = oneOffPaymentReviewVm.VerifoneTransactionGuid,
                    TransactionData = JsonConvert.SerializeObject(oneOffPaymentDto)
                });

                _gtmService.RaiseOneOffPaymentEvent_OptionsSelected(oneOffPaymentReviewVm, LoggedInUserId,
                                                                    "Regular Account");

                await _webActivityService.LogOneOffPaymentSelected(oneOffPaymentReviewVm.LowellReference,
                                                                   LoggedInUserId, !oneOffPaymentReviewVm.PaidInFull, oneOffPaymentReviewVm.DiscountSelected);

                // Ensure no model state is used in view render
                ModelState.Clear();

                ApplicationSessionState.LogPaymentResult = true;
                return(View("OneOff", oneOffPaymentReviewVm));
            }

            if (paymentOptionsVmWithUserEntries.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.DirectDebit)
            {
                // Not validated here - occurs on the final step (DirectDebitComplete)

                var directDebitDetailsVm =
                    _buildDirectDebitDetailsVmService.Build(paymentOptionsVmWithUserEntries);

                // Stash model in state, to allow view to be rebuilt on postback
                directDebitDetailsVm.InitialState = SerialiseModel(directDebitDetailsVm);

                // Stash payment options VM in Direct Debit VM to allow it to be passed back
                // (e.g. if user clicks 'change' and goes back to Payment Options)
                directDebitDetailsVm.PaymentOptionsFilledInState =
                    SerialiseModel(paymentOptionsVmWithUserEntries);

                if (directDebitDetailsVm.DiscountSelected)
                {
                    await LogDiscountDirectDebitOptionsSelected(paymentOptionsVmWithUserEntries);
                }
                else
                {
                    await LogDirectDebitOptionsSelected(paymentOptionsVmWithUserEntries);
                }

                // TODO: change over to building and returning view directly
                _gtmService.RaiseDirectDebitEvent_OptionsSelected(directDebitDetailsVm, LoggedInUserId,
                                                                  "Regular Account");

                ApplicationSessionState.LogSetUpPlanResult = true;

                return(View("DirectDebit", directDebitDetailsVm));
            }

            throw new ApplicationException("Invalid SelectedPaymentOption");
        }
Esempio n. 21
0
        public async Task <PaymentOptionsVm> Build(IUserIdentity loggedInUser, IApplicationSessionState applicationSessionState, Guid lowellReferenceSurrogateKey, string caseflowUserId)
        {
            string lowellReference = applicationSessionState.GetLowellReferenceFromSurrogate(lowellReferenceSurrogateKey);
            AccountReferenceDto accountReferenceDto = new AccountReferenceDto()
            {
                LowellReference = lowellReference
            };
            PaymentOptionsDto paymentOptionsDto = await _apiGatewayProxy.GetPaymentOptions(accountReferenceDto);

            IncomeAndExpenditureApiModel incomeAndExpenditureDto = await _apiGatewayProxy.GetIncomeAndExpenditure(lowellReference);

            List <AccountSummary> accounts;

            if (caseflowUserId != null)
            {
                accounts = await _accountsService.GetAccounts(caseflowUserId);
            }
            else
            {
                accounts = await _accountsService.GetMyAccountsSummary(lowellReference);
            }

            var workingAccounts = accounts.Count(a => !a.AccountStatusIsClosed);

            if (workingAccounts == 0)
            {
                workingAccounts = 1;
            }

            var accountDetails = await _accountsService.GetAccount(caseflowUserId, lowellReference);

            string[] planMessages = accountDetails.PlanMessages;

            var paymentOptionsVm = new PaymentOptionsVm()
            {
                OutstandingBalance                  = paymentOptionsDto.OutstandingBalance,
                LowellReference                     = paymentOptionsDto.LowellReference,
                ClientName                          = paymentOptionsDto.ClientName,
                ExcludedAccountMessage              = paymentOptionsDto.ExcludedAccountMessage,
                PlanInPlace                         = paymentOptionsDto.PlanInPlace,
                PlanIsDirectDebit                   = paymentOptionsDto.PaymentPlanIsDirectDebit,
                WithLowellSolicitors                = paymentOptionsDto.WithLowellSolicitors,
                PaymentOptions                      = new List <PaymentOptionsSelectionsVm>(),
                DiscountPercentage                  = paymentOptionsDto.DiscountPercentage,
                DiscountAmount                      = paymentOptionsDto.DiscountAmount,
                DiscountExpiryDate                  = paymentOptionsDto.DiscountExpiryDate,
                DiscountedBalance                   = paymentOptionsDto.DiscountedBalance,
                DiscountBalanceAvailable            = paymentOptionsDto.DiscountBalanceAvailable,
                ProposedDiscountedBalanceIfAccepted = paymentOptionsDto.ProposedDiscountedBalanceIfAccepted,
                DiscountedBalancePreviouslyAccepted = paymentOptionsDto.DiscountedBalancePreviouslyAccepted,
                ArrearsMessage                      = _arrearsDescriptionProcess.DeriveArrearsDetail(paymentOptionsDto.PaymentPlanArrearsAmount,
                                                                                                     paymentOptionsDto.PaymentPlanIsAutomated),
                StandingOrder           = paymentOptionsDto.StandingOrder,
                StandingOrderMessage    = paymentOptionsDto.StandingOrderMessage,
                VerifoneTransactionGuid = $"{paymentOptionsDto.LowellReference}_{Guid.NewGuid()}",
                DiscountAccepted        = paymentOptionsDto.DiscountedBalancePreviouslyAccepted,
                PlanMessage             = planMessages != null && planMessages.Length > 0? planMessages[0]:string.Empty
            };

            if (loggedInUser.IsLoggedInUser)
            {
                paymentOptionsVm.DirectDebitEmailAddress = loggedInUser.EmailAddress;
            }
            else
            {
                paymentOptionsVm.DirectDebitIsEmailAddressFieldVisible = true;
            }

            // Logged in user has accept T&C defaulted and will be hidden.
            // Anon user has tick box displayed. Must be ticked.
            if (loggedInUser.IsLoggedInUser)
            {
                paymentOptionsVm.AcceptTermsAndConditions = true;
            }
            else
            {
                paymentOptionsVm.IsAcceptTermsAndConditionsFieldVisible = true;
            }

            // Work out amount that needs to be paid to clear balance
            if (paymentOptionsVm.DiscountedBalancePreviouslyAccepted)
            {
                paymentOptionsVm.FullPaymentBalance = paymentOptionsVm.DiscountedBalance;
            }
            else
            {
                paymentOptionsVm.FullPaymentBalance = paymentOptionsVm.OutstandingBalance;
            }

            // Customer has a plan but it isn't direct debit.
            // Used to display a message informing customer that they can change to a DD online.
            if (paymentOptionsDto.PlanInPlace && !paymentOptionsDto.PaymentPlanIsDirectDebit)
            {
                paymentOptionsVm.HasNonDirectDebitPlanInPlace = true;
            }

            if (paymentOptionsDto.WithLowellSolicitors)
            {
                paymentOptionsVm.LowellSolicitorsRedirectLink = _portalSetting.SolicitorsRedirectDataProtectionUrl;
            }

            // Shared list of options for partial / full
            paymentOptionsVm.SourceOfFunds = BuildSourceOfFundsSelections(paymentOptionsDto);

            // Direct Debit
            paymentOptionsVm.DirectDebitFrequency         = BuildFrequencyList(paymentOptionsDto.DirectDebitFrequencies);
            paymentOptionsVm.DirectDebitStartDateEarliest = paymentOptionsDto.DirectDebitStartDateEarliest;
            paymentOptionsVm.DirectDebitStartDateLatest   = paymentOptionsDto.DirectDebitStartDateLatest;

            // TODO: Wrap the code below in a strategy pattern
            if (paymentOptionsDto.CanMakeFullPayment)
            {
                paymentOptionsVm.PaymentOptions.Add(new PaymentOptionsSelectionsVm()
                {
                    DisplayedText = "Card payment (Pay in Full)",
                    Value         = PaymentOptionsSelectionsVm.Values.FullPayment,
                    DataFormValue = PaymentOptionsSelectionsVm.Values.FullPayment
                });
            }
            if (paymentOptionsDto.CanMakePartialPayment)
            {
                paymentOptionsVm.PaymentOptions.Add(new PaymentOptionsSelectionsVm()
                {
                    DisplayedText = "Card payment (Partial amount)",
                    Value         = PaymentOptionsSelectionsVm.Values.PartialPayment,
                    DataFormValue = PaymentOptionsSelectionsVm.Values.PartialPayment,
                    ClassValue    = "js-hide-option"        // script hides this
                });
            }
            if (paymentOptionsDto.CanSetupDirectDebit)
            {
                paymentOptionsVm.PaymentOptions.Add(new PaymentOptionsSelectionsVm()
                {
                    DisplayedText = "Direct Debit plan",
                    Value         = PaymentOptionsSelectionsVm.Values.DirectDebit,
                    DataFormValue = PaymentOptionsSelectionsVm.Values.DirectDebit
                });
            }

            // Only add 'please select' if there are options
            // Required because view checks for availability of payment options
            if (paymentOptionsVm.PaymentOptions.Count > 0)
            {
                paymentOptionsVm.PaymentOptions.Insert(0, new PaymentOptionsSelectionsVm()
                {
                    DisplayedText = "Please Select",
                    Value         = PaymentOptionsSelectionsVm.Values.PleaseSelect,
                    DataFormValue = PaymentOptionsSelectionsVm.Values.PleaseSelect
                });
            }

            paymentOptionsVm.LowellReferenceSurrogate = lowellReferenceSurrogateKey;

            paymentOptionsVm.IandENotAvailable = incomeAndExpenditureDto == null;

            paymentOptionsVm.IandELessThanOrIs12MonthsOld =
                (incomeAndExpenditureDto != null && incomeAndExpenditureDto.Created.AddMonths(12).Date >= DateTime.Now.Date);
            paymentOptionsVm.AverageMonthlyPayment   = _portalSetting.AverageMonthlyPaymentAmount;
            paymentOptionsVm.MonthlyDisposableIncome =
                (incomeAndExpenditureDto == null ? 0 : (incomeAndExpenditureDto.DisposableIncome * (_portalSetting.MonthlyDisposableIncomePlanSetupPercentage / 100)));

            paymentOptionsVm.AccountCount = workingAccounts;
            paymentOptionsVm.MonthlyDisposableIncomePerAccount = paymentOptionsVm.MonthlyDisposableIncome / workingAccounts;

            return(paymentOptionsVm);
        }
        // Checks the information entered by the user against CaseFlow afresh
        // If validation fails, returns false and OneOffPaymentReviewVm will be output as NULL
        // If successful, returns true and OneOffPaymentReviewVm will be output populated
        public async Task <IBuildOneOffPaymentReviewVmValidationResult> ValidateAndBuild(
            IUserIdentity loggedInUser, IApplicationSessionState applicationSessionState,
            Guid lowellReferenceSurrogateKey, PaymentOptionsVm paymentOptionsVmWithUserEntries, string caseflowUserId)
        {
            // Reload from CaseFlow
            PaymentOptionsVm paymentOptionsVm =
                await _buildPaymentOptionsVmService.Build(loggedInUser, applicationSessionState, lowellReferenceSurrogateKey, caseflowUserId);

            // Populate user entries, giving a clean model to validate
            _buildPaymentOptionsVmService.UpdateFieldsFromUserEntries(loggedInUser, paymentOptionsVm, paymentOptionsVmWithUserEntries);

            if (!_paymentOptionsVmValidatorProcess.Validate(paymentOptionsVm))
            {
                return new ValidationResult()
                       {
                           IsValid = false
                       }
            }
            ;

            // Ensure we are not using this - must use clean, validated model (defensive coding)
            // ReSharper disable once RedundantAssignment
            paymentOptionsVmWithUserEntries = null;

            var postDataXml = _verifonePaymentProviderService.CreatePayload(paymentOptionsVm);

            OneOffPaymentReviewVm vm = new OneOffPaymentReviewVm()
            {
                LowellReference         = paymentOptionsVm.LowellReference,
                ClientName              = paymentOptionsVm.ClientName,
                VerifoneUrl             = _verifoneSetting.ApiEndpoint,
                VerifonePostDataXml     = postDataXml,
                VerifoneTransactionGuid = paymentOptionsVm.VerifoneTransactionGuid.ToString(),
                UserID            = loggedInUser.UserId,
                PaidInFull        = paymentOptionsVm.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.FullPayment,
                DiscountAvailable = paymentOptionsVm.DiscountBalanceAvailable,
                DiscountSelected  = paymentOptionsVm.DiscountAccepted,
                PlanInPlace       = paymentOptionsVm.PlanInPlace,
                InArrears         = !String.IsNullOrEmpty(paymentOptionsVm.ArrearsMessage)
            };

            // Source payment information from appropriate nested object
            if (paymentOptionsVm.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.FullPayment)
            {
                vm.PaymentAmount = paymentOptionsVm.FullPaymentAmountDerived;

                vm.SourceOfFunds      = paymentOptionsVm.FullPaymentSelectedSourceOfFunds;
                vm.SourceOfFundsOther = paymentOptionsVm.FullPaymentSourceOfFundsOtherText;
                vm.PaidInFull         = true;
            }
            else if (paymentOptionsVm.SelectedPaymentOption == PaymentOptionsSelectionsVm.Values.PartialPayment)
            {
                Debug.Assert(paymentOptionsVm.PartialPaymentAmount != null, "paymentOptionsVmWithUserEntries.PartialPaymentAmount != null");

                vm.PaymentAmount      = paymentOptionsVm.PartialPaymentAmount.Value;
                vm.SourceOfFunds      = paymentOptionsVm.PartialPaymentSelectedSourceOfFunds;
                vm.SourceOfFundsOther = paymentOptionsVm.PartialPaymentSourceOfFundsOtherText;
            }
            else
            {
                throw new ApplicationException("Invalid SelectedPaymentOption");
            }

            return(new ValidationResult()
            {
                IsValid = true, OneOffPaymentReviewVm = vm
            });
        }
    }
Esempio n. 23
0
        private async Task <IActionResult> ProcessDirectDebitDetailsPost(Guid lowellReferenceSurrogateKey,
                                                                         DirectDebitDetailsVm directDebitDetailsVmWithUserEntries)
        {
            if (!ModelState.IsValid)
            {
                Debug.Assert(directDebitDetailsVmWithUserEntries.InitialState != null,
                             "Initial state must be stashed to re-create view on round-trip");
                return(View(directDebitDetailsVmWithUserEntries));
            }

            //TODO: Change to async
            var result =
                await _directDebitPlanSetupService.CheckDirectDebitDetails(directDebitDetailsVmWithUserEntries);

            // Restore Payment Options from state embedded in Direct Debit VM
            PaymentOptionsVm paymentOptionsVm = DeserialiseModel <PaymentOptionsVm>(directDebitDetailsVmWithUserEntries.PaymentOptionsFilledInState);

            Debug.Assert(paymentOptionsVm.InitialState == null, "Serialisation Loop Detected - a previous step must have serialised a model that already contains InitialState");

            if (!result.IsSuccessful)
            {
                directDebitDetailsVmWithUserEntries.MessageForUser = result.MessageForUser;

                if (ApplicationSessionState.LogSetUpPlanResult)
                {
                    if (directDebitDetailsVmWithUserEntries.DiscountSelected)
                    {
                        await LogDiscountDirectDebitCompleteFailure(paymentOptionsVm);
                    }
                    else
                    {
                        await LogDirectDebitCompleteFailure(paymentOptionsVm);
                    }

                    ApplicationSessionState.LogSetUpPlanResult = false;
                }

                return(View(directDebitDetailsVmWithUserEntries));
            }

            DirectDebitPlanOverviewVm directDebitPlanOverview = _buildDirectDebitPlanOverviewVmService.Build(paymentOptionsVm, directDebitDetailsVmWithUserEntries);

            // Need to stash direct debit model, so that we can round-trip when 'change' options are selected on confirmation screen.
            Debug.Assert(!string.IsNullOrEmpty(directDebitDetailsVmWithUserEntries.PaymentOptionsFilledInState),
                         "Stashed model MUST contain stashed payment options model, so that it can be round-tripped back to Payment Options if choose to change that");

            directDebitPlanOverview.DirectDebitDetailsFilledInState =
                SerialiseModel(directDebitDetailsVmWithUserEntries);

            _gtmService.RaiseDirectDebitEvent_BankDetails(directDebitPlanOverview, LoggedInUserId, "Direct Debit Plan");

            if (directDebitDetailsVmWithUserEntries.DiscountSelected)
            {
                await LogDiscountDirectDebitDetailsEntered(paymentOptionsVm);
            }
            else
            {
                await LogDirectDebitDetailsEntered(paymentOptionsVm);
            }



            return(View("DirectDebitConfirm", directDebitPlanOverview));
        }