} // ValidateOfferDate /// <summary> /// Add new paypoint card from paypoint callback. /// </summary> /// <param name="transId">Paypoint transaction id. null for test card</param> /// <param name="cardNo">Last digits of credit card. null for test card</param> /// <param name="expiry">Format: MMYY</param> /// <returns></returns> public virtual PayPointCard TryAddPayPointCard(string transId, string cardNo, string expiry, string cardHolder, PayPointAccount account) { var card = new PayPointCard { Customer = this, DateAdded = DateTime.UtcNow, CardNo = cardNo, TransactionId = transId, ExpireDateString = expiry, CardHolder = cardHolder, PayPointAccount = account, IsDefaultCard = true }; if (!string.IsNullOrEmpty(expiry) && expiry.Length == 4) { DateTime dt; if (DateTime.TryParseExact(expiry, "MMyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out dt)) { card.ExpireDate = dt; } } // if //if (!string.IsNullOrEmpty(card.CardNo) && card.ExpireDate.HasValue) { // var existing = PayPointCards // .Where(c => c.ExpireDate != null) // .Where(c => c.ExpireDate.Value.Year == card.ExpireDate.Value.Year) // .Where(c => c.ExpireDate.Value.Month == card.ExpireDate.Value.Month) // .FirstOrDefault(c => c.CardNo == card.CardNo); // if (existing != null) { // existing.TransactionId = card.TransactionId; // existing.DateAdded = card.DateAdded; // return existing; // } // if //} // if if (PayPointCards.Any()) { foreach (var payPointCard in PayPointCards) { payPointCard.IsDefaultCard = false; } } PayPointCards.Add(card); return(card); } // TryAddPayPointCard
public static PayPointCardModel FromCard(PayPointCard card) { return(new PayPointCardModel { Id = card.Id, CardNo = card.CardNo, DateAdded = card.DateAdded, ExpireDate = card.ExpireDate, TransactionId = card.TransactionId, IsDefault = card.IsDefaultCard, CardHolder = card.CardHolder, PayPointAccountName = card.PayPointAccount.Mid, BankAccountName = card.PayPointAccount.AccName, AccNumber = card.PayPointAccount.AccNumber, SortCode = card.PayPointAccount.SortCode }); }
public void tes_card_does_not_override() { var customer = new EZBob.DatabaseLib.Model.Database.Customer(); var paypointAccount = new PayPointAccount(); var payPointCard = new PayPointCard() { Customer = customer, DateAdded = new DateTime(2012, 10, 10), Id = 1, TransactionId = "0f22b1c-e8ec-4299-83c2-ed9f9443abf3", PayPointAccount = paypointAccount }; customer.PayPointCards.Add(payPointCard); var card = customer.TryAddPayPointCard("0f22b1c-e8ec-4299-83c2-ed9f9443abf2", null, null, null, paypointAccount); Assert.That(customer.PayPointCards.Count, Is.EqualTo(2)); }
public void if_new_card_expire_date_and_cardno_equal_to_existing_overwrite_it() { var customer = new EZBob.DatabaseLib.Model.Database.Customer(); var paypointAccount = new PayPointAccount(); var payPointCard = new PayPointCard() { CardNo = "1234", Customer = customer, DateAdded = new DateTime(2012, 10, 10), ExpireDate = new DateTime(2014, 10, 1), Id = 1, TransactionId = "0f22b1c-e8ec-4299-83c2-ed9f9443abf3", PayPointAccount = paypointAccount }; customer.PayPointCards.Add(payPointCard); var card = customer.TryAddPayPointCard("0f22b1c-e8ec-4299-83c2-ed9f9443abf2", "1234", "1014", null, paypointAccount); Assert.That(customer.PayPointCards.Count, Is.EqualTo(1)); Assert.That(customer.PayPointCards.First().TransactionId, Is.EqualTo("0f22b1c-e8ec-4299-83c2-ed9f9443abf2")); }
public JsonResult PayFast(string amount, string type, string paymentType, int loanId, int cardId) { try { decimal realAmount = decimal.Parse(amount, CultureInfo.InvariantCulture); var customer = this.context.Customer; log.Msg("Payment request for customer id {0}, amount {1}", customer.Id, realAmount); // TotalEarlyPayment realAmount = CalculateRealAmount(type, loanId, realAmount); if (realAmount < 0) { return(Json(new { error = "amount is too small" })); } PayPointCard card = cardId == -1 ? customer.PayPointCards.FirstOrDefault(c => c.IsDefaultCard) : customer.PayPointCards.FirstOrDefault(c => c.Id == cardId); if (card == null) { throw new Exception("Card not found"); } this.paypointApi.RepeatTransactionEx(card.PayPointAccount, card.TransactionId, realAmount); NL_Payments nlPayment = new NL_Payments() { CreatedByUserID = this.context.UserId, Amount = realAmount, PaymentMethodID = (int)NLLoanTransactionMethods.CustomerAuto, PaymentSystemType = NLPaymentSystemTypes.Paypoint }; log.Debug("PayFast: Sending nlPayment: {0} for customer {1}", nlPayment, customer.Id); LoanPaymentFacade loanRepaymentFacade = new LoanPaymentFacade(); PaymentResult payFastModel = loanRepaymentFacade.MakePayment( card.TransactionId, realAmount, null, type, loanId, customer, DateTime.UtcNow, "manual payment from customer", paymentType, "CustomerAuto", nlPayment ); payFastModel.CardNo = card.CardNo; SendEmails(loanId, realAmount, customer); this.logRepository.Log( this.context.UserId, DateTime.UtcNow, "Paypoint Pay Early Fast Callback", "Successful", "" ); return(Json(payFastModel)); } catch (PayPointException e) { this.logRepository.Log( this.context.UserId, DateTime.UtcNow, "Paypoint Pay Early Fast Callback", "Failed", e.ToString() ); return(Json(new { error = "Error occurred while making payment" })); } catch (Exception e) { this.logRepository.Log( this.context.UserId, DateTime.UtcNow, "Paypoint Pay Early Fast Callback", "Failed", e.ToString() ); return(Json(new { error = e.Message })); } // try } // PayFast
//----------------------------------------------------------------------------------- /// <summary> /// Make automatic payment for given installment /// Called from PaypointCharger job /// </summary> /// <param name="customerId"></param> /// <param name="loanId"></param> /// <param name="loanScheduleId">Installment Id</param> /// <param name="amount">Amount to pay</param> /// <returns>PayPointReturnData as a result of call to paypoint API</returns> public PayPointReturnData MakeAutomaticPayment( int customerId, int loanId, int loanScheduleId, decimal amount ) { LoanScheduleRepository installments = (LoanScheduleRepository)ObjectFactory.GetInstance <ILoanScheduleRepository>(); var loanPaymentFacade = new LoanPaymentFacade(); PayPointReturnData payPointReturnData = null; installments.BeginTransaction(); try { var installment = installments.Get(loanScheduleId); var loan = installment.Loan; var customer = loan.Customer; var now = DateTime.UtcNow; NL_Payments nlPayment = new NL_Payments() { Amount = amount, PaymentMethodID = (int)NLLoanTransactionMethods.Auto, PaymentStatusID = (int)NLPaymentStatuses.Active, PaymentSystemType = NLPaymentSystemTypes.Paypoint, CreationTime = now, CreatedByUserID = 1, Notes = "autocharger" }; Log.InfoFormat("Making automatic repayment for customer {0}(#{1}) for amount {2} for loan# {3}({4})", customer.PersonalInfo.Fullname, customer.RefNumber, amount, loan.RefNumber, loan.Id); PayPointCard defaultCard = customer.PayPointCards.FirstOrDefault(x => x.IsDefaultCard); if (defaultCard == null && customer.PayPointCards.Any()) { defaultCard = customer.PayPointCards.First(); } if (defaultCard == null) { // ReSharper disable once ThrowingSystemException throw new Exception("Debit card not found"); } var payPointTransactionId = defaultCard.TransactionId; try { payPointReturnData = RepeatTransactionEx(defaultCard.PayPointAccount, payPointTransactionId, amount); // set real charged amount nlPayment.Amount = amount; } catch (PayPointException ex) { loan.Transactions.Add(new PaypointTransaction { Amount = amount, Description = ex.PaypointData.Message ?? "Exception:" + ex.Message, PostDate = now, Status = LoanTransactionStatus.Error, PaypointId = payPointTransactionId, IP = "", Balance = loan.Balance, Principal = loan.Principal, Loan = loan, LoanTransactionMethod = ObjectFactory.GetInstance <DatabaseDataHelper>().LoanTransactionMethodRepository.FindOrDefault("Auto") }); installments.CommitTransaction(); // save failed NL payment + PP transaction long nlLoanId = ObjectFactory.GetInstance <IEzServiceAccessor>().GetLoanByOldID(loanId, customerId); if (nlLoanId > 0) { nlPayment.Amount = 0; nlPayment.PaymentStatusID = (int)NLPaymentStatuses.Error; nlPayment.PaypointTransactions.Clear(); nlPayment.PaypointTransactions.Add(new NL_PaypointTransactions() { TransactionTime = now, Amount = amount, // in the case of Exception amount should be 0 ???? Notes = ex.PaypointData.Message ?? "Exception:" + ex.Message, PaypointTransactionStatusID = (int)NLPaypointTransactionStatuses.Error, IP = string.Empty, PaypointUniqueID = payPointTransactionId, PaypointCardID = defaultCard.Id }); Log.InfoFormat("Failed Paypoint transaction: customerId={0} loanID = {1}, loanScheduleId={2} amount={3}; nlPayment={4}", customerId, loanId, loanScheduleId, amount, nlPayment); ObjectFactory.GetInstance <IEzServiceAccessor>().AddPayment(loan.Customer.Id, nlPayment); } return(ex.PaypointData); } installments.CommitTransaction(); loanPaymentFacade.PayLoan(loan, payPointReturnData.NewTransId, amount, null, now, "auto-charge", false, null, nlPayment); } catch (Exception e) { if (!(e is PayPointException)) { Log.Error(e); } if (payPointReturnData == null) { payPointReturnData = new PayPointReturnData { Error = e.Message } } ; installments.RollbackTransaction(); } return(payPointReturnData); }
} // constructor /// <exception cref="Exception">PacnetSafeGuard stopped money transfer</exception> /// <exception cref="OverflowException"><paramref /> is less than <see cref="F:System.TimeSpan.MinValue" /> or greater than <see cref="F:System.TimeSpan.MaxValue" />.-or-<paramref /> is <see cref="F:System.Double.PositiveInfinity" />.-or-<paramref name="value" /> is <see cref="F:System.Double.NegativeInfinity" />. </exception> /// <exception cref="LoanDelayViolationException">Condition. </exception> public Loan CreateLoan(Customer cus, decimal loanAmount, PayPointCard card, DateTime now, Ezbob.Backend.ModelsWithDB.NewLoan.NL_Model nlModel = null) { ValidateCustomer(cus); // continue (customer's data/status, finish wizard, bank account data) ValidateAmount(loanAmount, cus); // continue (loanAmount > customer.CreditSum) ValidateOffer(cus); // check offer validity dates - in AddLoan strategy ValidateLoanDelay(cus, now, TimeSpan.FromMinutes(1)); // checks if last loan was taken a minute before "now" - ?? to prevent multiple clicking on "create loan" button? ValidateRepaymentPeriodAndInterestRate(cus); bool isFakeLoanCreate = (card == null); var cr = cus.LastCashRequest; Loan loan = this.loanBuilder.CreateLoan(cr, loanAmount, now); var transfered = loan.LoanAmount - loan.SetupFee; PacnetReturnData ret; if (PacnetSafeGuard(cus, transfered)) { if (!isFakeLoanCreate && !cus.IsAlibaba) { ret = SendMoney(cus, transfered); VerifyAvailableFunds(transfered); } else { log.Debug( "Not sending money via Pacnet. isFake: {0}, isAlibaba: {1}", isFakeLoanCreate, cus.IsAlibaba ); ret = new PacnetReturnData { Status = "Done", TrackingNumber = "fake" }; } // if } else { log.Error("PacnetSafeGuard stopped money transfer"); // ReSharper disable once ThrowingSystemException throw new Exception("PacnetSafeGuard stopped money transfer"); } // if cr.HasLoans = true; loan.Customer = cus; loan.Status = LoanStatus.Live; loan.CashRequest = cr; loan.LoanType = cr.LoanType; loan.GenerateRefNumber(cus.RefNumber, cus.Loans.Count); if (nlModel == null) { nlModel = new NL_Model(cus.Id); } nlModel.UserID = this.context.UserId; // NL fund transfer nlModel.FundTransfer = new NL_FundTransfers() { Amount = loanAmount, // logic transaction - full amount TransferTime = now, FundTransferStatusID = (int)NLFundTransferStatuses.Pending, // (int)NLPacnetTransactionStatuses.InProgress, LoanTransactionMethodID = (int)NLLoanTransactionMethods.Pacnet, PacnetTransactions = new List <NL_PacnetTransactions>() }; PacnetTransaction loanTransaction; if (!cus.IsAlibaba) { loanTransaction = new PacnetTransaction { Amount = loan.LoanAmount, Description = "Ezbob " + FormattingUtils.FormatDateToString(DateTime.Now), PostDate = now, Status = (isFakeLoanCreate) ? LoanTransactionStatus.Done : LoanTransactionStatus.InProgress, TrackingNumber = ret.TrackingNumber, PacnetStatus = ret.Status, Fees = loan.SetupFee, LoanTransactionMethod = this.tranMethodRepo.FindOrDefault("Pacnet"), }; // NL pacnet transaction nlModel.FundTransfer.PacnetTransactions.Add(new NL_PacnetTransactions() { TransactionTime = now, Amount = loanAmount, Notes = "Ezbob " + FormattingUtils.FormatDateToString(DateTime.Now) + " Status: " + ret.Status + " Err:" + ret.Error, StatusUpdatedTime = DateTime.UtcNow, TrackingNumber = ret.TrackingNumber, PacnetTransactionStatusID = (isFakeLoanCreate) ? (int)NLPacnetTransactionStatuses.Done : (int)NLPacnetTransactionStatuses.InProgress, }); } else { // alibaba loanTransaction = new PacnetTransaction { Amount = loan.LoanAmount, Description = "Ezbob " + FormattingUtils.FormatDateToString(DateTime.Now), PostDate = now, Status = LoanTransactionStatus.Done, TrackingNumber = "alibaba deal. CustomerID: " + cus.Id, // TODO save who got the money PacnetStatus = ret.Status, Fees = loan.SetupFee, LoanTransactionMethod = this.tranMethodRepo.FindOrDefault("Manual") }; log.Debug("Alibaba loan, adding manual pacnet transaction to loan schedule"); // NL: only logic transaction created in "alibaba" case; real money transfer will be done later, not transferred to customer (alibaba buyer) directly, but to seller (3rd party) nlModel.FundTransfer.LoanTransactionMethodID = (int)NLLoanTransactionMethods.Manual; } // if // This is the place where the funds transferred to customer saved to DB log.Info( "Save transferred funds to customer {0} amount {1}, isFake {2} , isAlibaba {3}", cus.Id, transfered, isFakeLoanCreate, cus.IsAlibaba ); loan.AddTransaction(loanTransaction); var aprCalc = new APRCalculator(); loan.APR = (decimal)aprCalc.Calculate(loanAmount, loan.Schedule, loan.SetupFee, now); cus.AddLoan(loan); cus.FirstLoanDate = cus.Loans.Min(x => x.Date); cus.LastLoanDate = cus.Loans.Max(x => x.Date); cus.LastLoanAmount = cus.Loans.First(x => x.Date == cus.LastLoanDate).LoanAmount; cus.AmountTaken = cus.Loans.Sum(x => x.LoanAmount); cus.CreditSum = cus.CreditSum - loanAmount; if (loan.SetupFee > 0) { cus.SetupFee = loan.SetupFee; } /** * 1. Build/ReBuild agreement model - private AgreementModel GenerateAgreementModel(Customer customer, Loan loan, DateTime now, double apr); in \App\PluginWeb\EzBob.Web\Code\AgreementsModelBuilder.cs * 2. RenderAgreements: loan.Agreements.Add * 3. RenderAgreements: SaveAgreement (file?) \backend\Strategies\Misc\Agreement.cs strategy */ // NL model - loan. Create history here for agreements processing nlModel.Loan = new NL_Loans(); nlModel.Loan.Histories.Clear(); nlModel.Loan.Histories.Add(new NL_LoanHistory() { Amount = loanAmount, EventTime = now }); // populate nlModel by agreements data also this.agreementsGenerator.RenderAgreements(loan, true, nlModel); var loanHistoryRepository = new LoanHistoryRepository(this.session); loanHistoryRepository.SaveOrUpdate(new LoanHistory(loan, now)); // This is the place where the loan is created and saved to DB log.Info( "Create loan for customer {0} cash request {1} amount {2}", cus.Id, loan.CashRequest.Id, loan.LoanAmount ); // actually this is the place where the loan saved to DB this.session.Flush(); Loan oldloan = cus.Loans.First(s => s.RefNumber.Equals(loan.RefNumber)); nlModel.Loan.OldLoanID = oldloan.Id; nlModel.Loan.Refnum = loan.RefNumber; // TODO generate another refnum with new algorithm in addloan strategy try { // copy newly created agreementtemplateID (for new templeates) //foreach (NL_LoanAgreements ag in nlModel.Loan.LastHistory().Agreements) { // if (ag.LoanAgreementTemplateID == 0) // ag.LoanAgreementTemplateID = oldloan.Agreements.FirstOrDefault(a => a.FilePath.Equals(ag.FilePath)).TemplateID; //} this.serviceClient.Instance.AddLoan(null, cus.Id, nlModel); // ReSharper disable once CatchAllClause } catch (Exception ex) { log.Debug("Failed to save new loan {0}", ex); } // try if (!isFakeLoanCreate) { this.serviceClient.Instance.CashTransferred(cus.Id, transfered, loan.RefNumber, cus.Loans.Count() == 1); } this.serviceClient.Instance.LinkLoanToInvestor(this.context.UserId, cus.Id, loan.Id); // verify see above line 45-48 // // ++++++++ // \App\PluginWeb\EzBob.Web\Code\LoanBuilder.cs , method public Loan CreateNewLoan(CashRequest cr, decimal amount, DateTime now, int term, int interestOnlyTerm = 0) // // calculate setupFee // calculate CalculateBrokerFee // var loanLegal = cr.LoanLegals.LastOrDefault(); // // --------------------- // file \Integration\PaymentServices\Calculators\LoanScheduleCalculator.cs, method // public IList<LoanScheduleItem> Calculate(decimal total, Loan loan = null, DateTime? startDate = null, int interestOnlyTerm = 0) // // calculate Schedules, but use it only for "fill in loan with total data" // GetDiscounts // loanType => GetBalances => fill in loan with total data: Interest, LoanAmount; Principal, Balance (loan.LoanAmount loan.Interest); InterestRate; startDate.Value // --------------------- // // LoanSource // brokerFee // +++++++++++++++++++++ // // line 85 // prepare pacnet transaction => add to loan => loan.arp => add loan to cutomer // agreement // save loan via new LoanHistory (139) // SF // flush this.serviceClient.Instance.SalesForceUpdateOpportunity( cus.Id, cus.Id, new ServiceClientProxy.EzServiceReference.OpportunityModel { Email = cus.Name, CloseDate = now, TookAmount = (int)loan.LoanAmount, ApprovedAmount = (int)(cus.CreditSum ?? 0) + (int)loanAmount, DealCloseType = OpportunityDealCloseReason.Won.ToString(), Origin = cus.CustomerOrigin.Name } ); this.serviceClient.Instance.SalesForceAddUpdateLeadAccount(cus.Id, cus.Name, cus.Id, false, false); //update account with new number of loans HandleSalesForceTopup(cus, now); //EZ-3908 return(loan); } // CreateLoan