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
        }
Beispiel #3
0
        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);
        }