public void WhenBatchingMessageWithOpenBatchWithWithdrawAndDepositTransactionThenTransactionsInBatchIs2() { ApplicationService applicationService = new ApplicationService(_ctx); MessageServices messageService = new MessageServices(_ctx); UserService userService = new UserService(_ctx); PaymentAccountService paymentAccountService = new PaymentAccountService(_ctx); TransactionBatchService transactionBatchService = new TransactionBatchService(_ctx, _logger); var transactionBatchGuid = Guid.NewGuid(); var transactionAmount = 2.75; _ctx.TransactionBatches.Add(new TransactionBatch() { CreateDate = System.DateTime.Now, Id = transactionBatchGuid, IsClosed = false, TotalDepositAmount = 0, TotalNumberOfDeposits = 0, TotalWithdrawalAmount = 0, TotalNumberOfWithdrawals = 0, Transactions = new List <Transaction>() }); _ctx.SaveChanges(); var application = applicationService.AddApplication("Test", "http://www.test.com", true); var sender = userService.AddUser(application.ApiKey, "*****@*****.**", "pdthx123", "*****@*****.**", "1234"); sender.SecurityPin = "2589"; userService.UpdateUser(sender); var senderPaymentAccount = paymentAccountService.AddPaymentAccount(sender.UserId.ToString(), "Sender PaidThx", "053000219", "1234123412", "Checking"); sender.PaymentAccounts = new System.Collections.ObjectModel.Collection <PaymentAccount>(); sender.PaymentAccounts.Add(senderPaymentAccount); var recipient = userService.AddUser(application.ApiKey, "*****@*****.**", "pdthx123", "*****@*****.**", "1234"); var recipientPaymentAccount = paymentAccountService.AddPaymentAccount(sender.UserId.ToString(), "Recipient PaidThx", "053000219", "1234123412", "Savings"); recipient.PaymentAccounts = new System.Collections.ObjectModel.Collection <PaymentAccount>(); recipient.PaymentAccounts.Add(recipientPaymentAccount); var message = messageService.AddMessage(application.ApiKey.ToString(), sender.EmailAddress, recipient.EmailAddress, senderPaymentAccount.Id.ToString(), transactionAmount, "Test Payment", "Payment", "2589"); message.Recipient = userService.FindUserByEmailAddress(recipient.EmailAddress); transactionBatchService.BatchTransactions(message); var transactionBatch = transactionBatchService.GetOpenBatch(); Assert.AreEqual(transactionBatchGuid, transactionBatch.Id); Assert.AreEqual(2, transactionBatch.Transactions.Count); Assert.AreEqual(1, transactionBatch.TotalNumberOfDeposits); Assert.AreEqual(1, transactionBatch.TotalNumberOfWithdrawals); }
public void Execute(JobExecutionContext context) { //Get Current Batch //Close Current Batch //And Open New One //Create a new BatchFile Record logger.Log(LogLevel.Info, String.Format("Creating Nacha ACH File at {0}", System.DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss"))); logger.Log(LogLevel.Info, String.Format("Batching Transactions")); var transactions = transactionBatchService.BatchTransactions(); FileGenerator fileGeneratorService = new FileGenerator(); fileGeneratorService.CompanyIdentificationNumber = ConfigurationManager.AppSettings["CompanyIdentificationNumber"]; fileGeneratorService.CompanyName = ConfigurationManager.AppSettings["CompanyName"]; fileGeneratorService.ImmediateDestinationId = ConfigurationManager.AppSettings["ImmediateDestinationId"]; fileGeneratorService.ImmediateDestinationName = ConfigurationManager.AppSettings["ImmediateDestinationName"]; fileGeneratorService.ImmediateOriginId = ConfigurationManager.AppSettings["ImmediateOriginId"]; fileGeneratorService.ImmediateOriginName = ConfigurationManager.AppSettings["ImmediateOriginName"]; fileGeneratorService.OriginatingTransitRoutingNumber = ConfigurationManager.AppSettings["OriginatingTransitRoutingNumber"]; fileGeneratorService.CompanyDiscretionaryData = ConfigurationManager.AppSettings["CompanyDiscretionaryData"]; logger.Log(LogLevel.Info, String.Format("Processing Transactions")); var results = fileGeneratorService.ProcessFile(transactions); logger.Log(LogLevel.Info, String.Format("Creating Batch File")); StringBuilder sb = new StringBuilder(); results.ForEach(s => sb.AppendLine(s)); string fileContext = sb.ToString(); logger.Log(LogLevel.Info, String.Format("Uploading Batch File to S3 Server")); string bucketName = ConfigurationManager.AppSettings["NachaFileBucketName"]; if (String.IsNullOrEmpty(bucketName)) { throw new Exception("S3 bucket name for NachaFileBucketName not configured"); } Amazon.S3.AmazonS3Client s3Client = new Amazon.S3.AmazonS3Client(); PutObjectRequest putRequest = new PutObjectRequest() { ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256, BucketName = bucketName, ContentBody = fileContext, Key = "NACHA_FILE_" + System.DateTime.Now.ToString("MMddyy_Hmmss") }; s3Client.PutObject(putRequest); //Move all payments to paid //Update Batch File //Start BatchFile Workflow }
public bool Process(Message message) { _formattingService = new FormattingServices(); _transactionBatchService = new TransactionBatchService(_ctx, _logger); _validationService = new ValidationService(_logger); _smsService = new SMSService(_ctx); _emailService = new EmailService(_ctx); _userService = new UserService(_ctx); _messageService = new MessageServices(_ctx); string fromAddress = "*****@*****.**"; URIType recipientType = _messageService.GetURIType(message.RecipientUri); _logger.Log(LogLevel.Info, String.Format("Processing Payment Message to {0}", message.RecipientUri)); _logger.Log(LogLevel.Info, String.Format("URI Type {0}", recipientType)); string smsMessage; string emailSubject; string emailBody; var sender = message.Sender; var recipient = _userService.GetUser(message.RecipientUri); message.Recipient = recipient; var senderName = _userService.GetSenderName(sender); var recipientName = message.RecipientUri; //check to see if recipient uri is mobile #, email address, or ME code //Validate Payment //Batch Transacations _logger.Log(LogLevel.Info, String.Format("Batching Transactions for message {0}", message.Id)); try { _transactionBatchService.BatchTransactions(message); } catch (Exception ex) { _logger.Log(LogLevel.Error, String.Format("Unable to process message {0}. {1}", message.Id, ex.Message)); throw ex; } //Attempt to assign payment to Payee if (recipient != null) { recipientName = recipient.UserName; if (!String.IsNullOrEmpty(recipient.SenderName)) { recipientName = recipient.SenderName; } else if (!String.IsNullOrEmpty(recipient.MobileNumber)) { recipientName = _formattingService.FormatMobileNumber(recipient.MobileNumber); } //Send out SMS Message to recipient if (!String.IsNullOrEmpty(recipient.MobileNumber)) { _logger.Log(LogLevel.Info, String.Format("Send SMS to Recipient")); smsMessage = String.Format(_recipientSMSMessage, message.Amount, senderName, _mobileWebSiteUrl); _smsService.SendSMS(message.ApiKey, recipient.MobileNumber, smsMessage); } //Send SMS Message to sender if (!String.IsNullOrEmpty(sender.MobileNumber)) { _logger.Log(LogLevel.Info, String.Format("Send SMS to Sender")); smsMessage = String.Format(_senderSMSMessage, message.Amount, recipientName, _mobileWebSiteUrl); _smsService.SendSMS(message.ApiKey, sender.MobileNumber, smsMessage); } //Send confirmation email to sender if (!String.IsNullOrEmpty(sender.EmailAddress)) { _logger.Log(LogLevel.Info, String.Format("Sending Email Confirmation to Sender")); emailSubject = String.Format(_senderConfirmationEmailSubject, recipientName); emailBody = String.Format(_senderConfirmationEmailBody, recipientName, message.Amount, _mobileWebSiteUrl); _emailService.SendEmail(message.ApiKey, fromAddress, sender.EmailAddress, emailSubject, emailBody); } //Send confirmation email to recipient if (!String.IsNullOrEmpty(recipient.EmailAddress)) { _logger.Log(LogLevel.Info, String.Format("Sending Email Confirmation to Recipient")); emailSubject = String.Format(_recipientConfirmationEmailSubject, senderName, message.Amount); //Payment Registered Recipient //first_name //last_name //rec_amount //rec_sender //rec_sender_photo_url //rec_datetime formatted dddd, MMMM dd(rd) at hh:mm tt //rec_comments //app_user //link_registration - empty _emailService.SendEmail(recipient.EmailAddress, emailSubject, _paymentReceivedRecipientRegisteredTemplate, new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("first_name", recipient.FirstName), new KeyValuePair <string, string>("last_name", recipient.LastName), new KeyValuePair <string, string>("rec_amount", String.Format("{0:C}", message.Amount)), new KeyValuePair <string, string>("rec_sender", senderName), new KeyValuePair <string, string>("rec_sender_photo_url", ""), new KeyValuePair <string, string>("rec_datetime", message.CreateDate.ToString("dddd, MMMM dd at hh:mm tt")), new KeyValuePair <string, string>("rec_comments", message.Comments), new KeyValuePair <string, string>("link_registration", ""), new KeyValuePair <string, string>("app_user", "false") }); } if (recipient.DeviceToken.Length > 0) { _logger.Log(LogLevel.Info, String.Format("Sending iOS Push Notification to Recipient")); // We need to know the number of pending requests that the user must take action on for the application badge # // The badge number is the number of PaymentRequests in the Messages database with the Status of (1 - Pending) // If we are processing a payment, we simply add 1 to the number in this list. This will allow the user to // Be notified of money received, but it will not stick on the application until the users looks at it. Simplyt // Opening the application is sufficient var numPending = _ctx.Messages.Where(p => p.MessageTypeValue.Equals((int)Domain.MessageType.PaymentRequest) && p.MessageStatusValue.Equals((int)Domain.MessageStatus.Pending)); _logger.Log(LogLevel.Info, String.Format("iOS Push Notification Num Pending: {0}", numPending.Count())); NotificationPayload payload = null; String notification; // Send a mobile push notification if (message.MessageType == Domain.MessageType.Payment) { notification = String.Format(_recipientWasPaidNotification, senderName, message.Amount); payload = new NotificationPayload(recipient.DeviceToken, notification, numPending.Count() + 1); payload.AddCustom("nType", "recPCNF"); } else if (message.MessageType == Domain.MessageType.PaymentRequest) { notification = String.Format(_recipientRequestNotification, senderName, message.Amount); payload = new NotificationPayload(recipient.DeviceToken, notification, numPending.Count()); payload.AddCustom("nType", "recPRQ"); } /* * Payment Notification Types: * Payment Request [recPRQ] * - Recipient receives notification that takes them to the * paystream detail view about that payment request * Payment Confirmation [recPCNF] * - Recipient receices notification that takes them to the paysteam detail view about the payment request */ payload.AddCustom("tID", message.Id); var notificationList = new List <NotificationPayload>() { payload }; List <string> result; try { var push = new PushNotification(true, @"C:\APNS\DevKey\aps_developer_identity.p12", "KKreap1566"); result = push.SendToApple(notificationList); // You are done! } catch (Exception ex) { _logger.Log(LogLevel.Fatal, String.Format("Exception sending iOS push notification. {0}", ex.Message)); var exception = ex.InnerException; while (exception != null) { _logger.Log(LogLevel.Fatal, String.Format("Exception sending iOS push notification. {0}", exception.Message)); } } } if (recipient.FacebookUser != null) { //Send Facebook Message // I don't think we can do this through the server. Nice try though. // We should, however, publish something to the user's page that says sender sent payment } } else { _logger.Log(LogLevel.Info, String.Format("Send SMS to Payee not found")); var link = String.Format("{0}{1}", _mobileWebSiteUrl, message.Id.ToString()); //Send out SMS message to sender if (!String.IsNullOrEmpty(sender.MobileNumber)) { _logger.Log(LogLevel.Info, String.Format("Send SMS to Sender (Recipient is not an registered user).")); smsMessage = String.Format(_senderSMSMessageRecipientNotRegistered, message.Amount, message.RecipientUri, link); _smsService.SendSMS(message.ApiKey, sender.MobileNumber, smsMessage); } if (!String.IsNullOrEmpty(sender.EmailAddress)) { emailSubject = String.Format(_senderConfirmationEmailSubjectRecipientNotRegistered, message.RecipientUri); emailBody = String.Format(_senderConfirmationEmailBodyRecipientNotRegistered, message.Amount, message.RecipientUri); //Send confirmation email to sender _logger.Log(LogLevel.Info, String.Format("Send Email to Sender (Recipient is not an registered user).")); _emailService.SendEmail(message.ApiKey, fromAddress, sender.EmailAddress, emailSubject, emailBody); } if (recipientType == URIType.MobileNumber) { //Send out SMS message to recipient _logger.Log(LogLevel.Info, String.Format("Send SMS to Recipient (Recipient is not an registered user).")); smsMessage = String.Format(_recipientSMSMessageRecipientNotRegistered, senderName, message.Amount, link); _smsService.SendSMS(message.ApiKey, message.RecipientUri, smsMessage); } emailSubject = String.Format(_recipientConfirmationEmailSubject, senderName, message.Amount); //Payment Registered Recipient //first_name //last_name //rec_amount //rec_sender //rec_sender_photo_url //rec_datetime formatted DayOfWeek, MM dd(rd) at hh:mm:tt //rec_comments //app_user //link_registration - empty if (recipientType == URIType.EmailAddress) { //Send confirmation email to recipient _logger.Log(LogLevel.Info, String.Format("Send Email to Recipient (Recipient is not an registered user).")); _emailService.SendEmail(message.RecipientUri, emailSubject, _paymentReceivedRecipientNotRegisteredTemplate, new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("first_name", ""), new KeyValuePair <string, string>("last_name", ""), new KeyValuePair <string, string>("rec_amount", String.Format("{0:C}", message.Amount)), new KeyValuePair <string, string>("rec_sender", senderName), new KeyValuePair <string, string>("rec_sender_photo_url", ""), new KeyValuePair <string, string>("rec_datetime", message.CreateDate.ToString("MM, dd yyyy hh:mm tt")), new KeyValuePair <string, string>("rec_comments", message.Comments), new KeyValuePair <string, string>("link_registration", link), new KeyValuePair <string, string>("app_user", "false") }); } } _logger.Log(LogLevel.Info, String.Format("Updating Payment")); message.MessageStatus = MessageStatus.Pending; message.LastUpdatedDate = System.DateTime.Now; _ctx.SaveChanges(); return(true); }
public void WhenBatching5TransactionsWithOpenBatchTransactionsInBatchIs5() { ApplicationService applicationService = new ApplicationService(_ctx); MessageServices messageService = new MessageServices(_ctx); UserService userService = new UserService(_ctx); PaymentAccountService paymentAccountService = new PaymentAccountService(_ctx); TransactionBatchService transactionBatchService = new TransactionBatchService(_ctx, _logger); var transactionBatchGuid = Guid.NewGuid(); var transactionAmount = 2.75; _ctx.TransactionBatches.Add(new TransactionBatch() { CreateDate = System.DateTime.Now, Id = transactionBatchGuid, IsClosed = true, TotalDepositAmount = 0, TotalNumberOfDeposits = 0, TotalWithdrawalAmount = 0, TotalNumberOfWithdrawals = 0, Transactions = new List <Transaction>() }); _ctx.SaveChanges(); var application = applicationService.AddApplication("Test", "http://www.test.com", true); var sender = userService.AddUser(application.ApiKey, "*****@*****.**", "pdthx123", "*****@*****.**", "1234"); sender.SecurityPin = "2589"; userService.UpdateUser(sender); var senderPaymentAccount = paymentAccountService.AddPaymentAccount(sender.UserId.ToString(), "Sender PaidThx", "053000219", "1234123412", "Checking"); sender.PaymentAccounts = new System.Collections.ObjectModel.Collection <PaymentAccount>(); sender.PaymentAccounts.Add(senderPaymentAccount); var transaction1 = new Domain.Transaction() { Amount = 1, Category = TransactionCategory.Payment, FromAccount = senderPaymentAccount, CreateDate = System.DateTime.Now, Id = Guid.NewGuid(), PaymentChannelType = PaymentChannelType.Single, StandardEntryClass = StandardEntryClass.Web, Status = TransactionStatus.Submitted, Type = TransactionType.Withdrawal, User = sender }; var transaction2 = new Domain.Transaction() { Amount = 2, Category = TransactionCategory.Payment, FromAccount = senderPaymentAccount, CreateDate = System.DateTime.Now, Id = Guid.NewGuid(), PaymentChannelType = PaymentChannelType.Single, StandardEntryClass = StandardEntryClass.Web, Status = TransactionStatus.Submitted, Type = TransactionType.Withdrawal, User = sender }; var transaction3 = new Domain.Transaction() { Amount = 3, Category = TransactionCategory.Payment, FromAccount = senderPaymentAccount, CreateDate = System.DateTime.Now, Id = Guid.NewGuid(), PaymentChannelType = PaymentChannelType.Single, StandardEntryClass = StandardEntryClass.Web, Status = TransactionStatus.Submitted, Type = TransactionType.Deposit, User = sender }; var transaction4 = new Domain.Transaction() { Amount = 4, Category = TransactionCategory.Payment, FromAccount = senderPaymentAccount, CreateDate = System.DateTime.Now, Id = Guid.NewGuid(), PaymentChannelType = PaymentChannelType.Single, StandardEntryClass = StandardEntryClass.Web, Status = TransactionStatus.Submitted, Type = TransactionType.Deposit, User = sender }; var transaction5 = new Domain.Transaction() { Amount = 5, Category = TransactionCategory.Payment, FromAccount = senderPaymentAccount, CreateDate = System.DateTime.Now, Id = Guid.NewGuid(), PaymentChannelType = PaymentChannelType.Single, StandardEntryClass = StandardEntryClass.Web, Status = TransactionStatus.Submitted, Type = TransactionType.Deposit, User = sender }; transactionBatchService.BatchTransactions(new List <Transaction>() { transaction1, transaction2, transaction3, transaction4, transaction5 }); var transactionBatch = transactionBatchService.GetOpenBatch(); Assert.AreEqual(5, transactionBatch.Transactions.Count); Assert.AreEqual(3, transactionBatch.TotalNumberOfDeposits); Assert.AreEqual(2, transactionBatch.TotalNumberOfWithdrawals); }
public bool Process(PaymentAccount paymentAccount) { //get random numbers between 10 and 49 that are not equal Random rand1 = new Random(10); Random rand2 = new Random(49); var depositAmount1 = (double)rand1.Next(10, 49) / 100; var depositAmount2 = (double)rand2.Next(10, 49) / 100; while (depositAmount1.Equals(depositAmount2)) { depositAmount2 = (double)rand2.Next(10, 49) / 100; } var withdrawalAmount = depositAmount1 + depositAmount2; var estimatedSettlementDate = System.DateTime.Now.AddDays(5); //create transactions var deposit1 = _ctx.Transactions.Add(new Transaction() { Amount = depositAmount1, Category = TransactionCategory.AccountVerification, CreateDate = System.DateTime.Now, FromAccount = paymentAccount, Id = Guid.NewGuid(), PaymentChannelType = PaymentChannelType.Single, StandardEntryClass = StandardEntryClass.Web, Status = TransactionStatus.Submitted, Type = TransactionType.Deposit, UserId = paymentAccount.UserId }); var deposit2 = _ctx.Transactions.Add(new Transaction() { Amount = depositAmount2, Category = TransactionCategory.AccountVerification, CreateDate = System.DateTime.Now, FromAccount = paymentAccount, Id = Guid.NewGuid(), PaymentChannelType = PaymentChannelType.Single, StandardEntryClass = StandardEntryClass.Web, Status = TransactionStatus.Submitted, Type = TransactionType.Deposit, UserId = paymentAccount.UserId }); var withdrawal = _ctx.Transactions.Add(new Transaction() { Amount = withdrawalAmount, Category = TransactionCategory.AccountVerification, CreateDate = System.DateTime.Now, FromAccount = paymentAccount, Id = Guid.NewGuid(), PaymentChannelType = PaymentChannelType.Single, StandardEntryClass = StandardEntryClass.Web, Status = TransactionStatus.Submitted, Type = TransactionType.Withdrawal, UserId = paymentAccount.UserId }); //batch two deposits into account and one withdrawal for total deposit amount try { _transactionBatchService.BatchTransactions(new List <Transaction>() { deposit1, deposit2, withdrawal }); } catch (Exception ex) { throw ex; } //log to PaymentAccountVerification log table and estimate when settlement complete var paymentAccountVerification = _paymentAccountVerificationService.AddVerification(paymentAccount.UserId.ToString(), paymentAccount.Id.ToString() , depositAmount1, depositAmount2, withdrawalAmount, System.DateTime.Now, estimatedSettlementDate); //first_name //last_name //acct_nickname //acct_lastfour //est_settle_date //est_settle_days //app_user t/f indicating whether you have signed in from an app //send email to account owner _emailService.SendEmail(paymentAccount.User.EmailAddress, "Your New PaidThx Payment Account", "New ACH Account Setup", new List <KeyValuePair <string, string> >() { }); return(true); }