public bool Process(Message message)
        {
            if (message.MessageStatus != MessageStatus.Submitted || message.MessageStatus != MessageStatus.Pending)
                throw new Exception("Only payment with a status of submitted or pending can be cancelled.");

            foreach (var transaction in message.Transactions)
            {
                transaction.Status = TransactionStatus.Cancelled;
                transaction.LastUpdatedDate = System.DateTime.Now;
            }

            _ctx.SaveChanges();

            return true;
        }
        private void ProcessPaymentRequest(Message message)
        {
            switch (message.MessageStatus)
            {
                case Domain.MessageStatus.Cancelled:
                    break;
                case Domain.MessageStatus.Completed:
                    break;
                case Domain.MessageStatus.Failed:
                    break;
                case Domain.MessageStatus.Pending:
                    break;
                case Domain.MessageStatus.Refunded:
                    break;
                case Domain.MessageStatus.Submitted:
                    _logger.Log(LogLevel.Error, String.Format("Starting Request Message Processor"));

                    IMessageProcessor messageProcessor = new SocialPayments.Services.MessageProcessors.SubmittedRequestMessageProcessor(_ctx);
                    messageProcessor.Process(message);

                    break;
                case Domain.MessageStatus.RequestAccepted:

                    //validate sender and recipient
                    //create withdraw and deposit records and batch
                    _transactionBatchService.BatchTransactions(message);

                    message.MessageStatus = Domain.MessageStatus.Pending;
                    message.LastUpdatedDate = System.DateTime.Now;

                    _ctx.SaveChanges();

                    //send sms and email confirmations
                    break;

                case Domain.MessageStatus.RequestRejected:

                    //send sms and email to sender
                    break;
            }
        }
        private void ProcessPayment(Message message)
        {
            _logger.Log(LogLevel.Error, String.Format("Processing Payment"));

            String smsMessage = "";
            switch (message.MessageStatus)
            {
                case Domain.MessageStatus.Submitted:

                    _logger.Log(LogLevel.Error, String.Format("Starting Payment Message Processor"));

                    IMessageProcessor messageProcessor = new SocialPayments.Services.MessageProcessors.SubmittedPaymentMessageProcessor(_ctx);
                    messageProcessor.Process(message);

                    break;

                //remove associated transactions from batch and cancel transactions
                case Domain.MessageStatus.CancelPending:

                    break;
                case Domain.MessageStatus.Cancelled:
                    //terminal state
                    break;

                case Domain.MessageStatus.Completed:
                    //terminal state
                    break;

                case Domain.MessageStatus.Failed:
                    //terminal state

                    break;
                case Domain.MessageStatus.Pending:
                    //moves to Completed State by NACHA processor when NACHA file is created

                    break;

                case Domain.MessageStatus.Refunded:
                    //terminal state

                    break;
            }
        }
        public void BatchTransactions(Message message)
        {
            var transactionBatch = GetOpenBatch();

            var withDrawalTransaction =
                new Domain.Transaction()
                {
                    Amount = message.Amount,
                    Category = Domain.TransactionCategory.Payment,
                    CreateDate = System.DateTime.Now,
                    FromAccountId = message.SenderAccountId.Value,
                    Id = Guid.NewGuid(),
                    MessageId = message.Id,
                    PaymentChannelType = Domain.PaymentChannelType.Single,
                    StandardEntryClass = Domain.StandardEntryClass.Web,
                    Status = Domain.TransactionStatus.Pending,
                    TransactionBatchId = transactionBatch.Id,
                    Type = Domain.TransactionType.Withdrawal,
                    UserId = message.SenderId,
                    Message = message,
                };

            transactionBatch.Transactions.Add(withDrawalTransaction);
            transactionBatch.TotalNumberOfWithdrawals += 1;
            transactionBatch.TotalWithdrawalAmount += withDrawalTransaction.Amount;

            Transaction deposit;

            if (message.Recipient != null && message.Recipient.PaymentAccounts.Count > 0)
            {
                _logger.Log(LogLevel.Info, String.Format("Found Recipient {0} for Message {1}", message.Recipient.UserId, message.Id));

                var depositTransaction =
                    new Domain.Transaction()
                    {
                        Amount = message.Amount,
                        Category = Domain.TransactionCategory.Payment,
                        CreateDate = System.DateTime.Now,
                        FromAccountId = message.Recipient.PaymentAccounts[0].Id,
                        Id = Guid.NewGuid(),
                        MessageId = message.Id,
                        PaymentChannelType = Domain.PaymentChannelType.Single,
                        StandardEntryClass = Domain.StandardEntryClass.Web,
                        Status = Domain.TransactionStatus.Pending,
                        TransactionBatchId = transactionBatch.Id,
                        Type = Domain.TransactionType.Deposit,
                        UserId = message.Recipient.UserId,
                    };

                transactionBatch.Transactions.Add(depositTransaction);
                transactionBatch.TotalNumberOfDeposits += 1;
                transactionBatch.TotalDepositAmount += depositTransaction.Amount;

                message.Recipient = message.Recipient;
            }

            message.MessageStatus = Domain.MessageStatus.Pending;
            message.LastUpdatedDate = System.DateTime.Now;

            _ctx.SaveChanges();
        }
        public void RemoveFromBatch(Message message)
        {
            foreach (var temp in message.Transactions)
            {
                var transactionBatch = GetOpenBatch();

                if (temp.Status == TransactionStatus.Submitted || temp.Status == TransactionStatus.Pending)
                {
                    var transaction = transactionBatch.Transactions
                        .FirstOrDefault(t => t.Id.Equals(temp.Id));

                    transaction.LastUpdatedDate = System.DateTime.Now;
                    transaction.Status = TransactionStatus.Cancelled;

                    transactionBatch.Transactions.Remove(temp);
                }
            }
        }
        public bool Process(Message message)
        {
            _logger.Log(LogLevel.Info, String.Format("Processing Request Message to {0}", message.RecipientUri));

            //Validate Payment Request
            //Batch Transacation WithDrawal

            URIType recipientType = _messageService.GetURIType(message.RecipientUri);

            _logger.Log(LogLevel.Info, String.Format("URI Type {0}", recipientType));

            //Attempt to find the recipient of the request
            var sender = message.Sender;
            _logger.Log(LogLevel.Info, String.Format("Getting Recipient"));

            var recipient = _userService.GetUser(message.RecipientUri);
            message.Recipient = recipient;

            string smsMessage;
            string emailSubject;
            string emailBody;

            _logger.Log(LogLevel.Info, String.Format("Getting Sender"));

            var senderName = _userService.GetSenderName(sender);
            _logger.Log(LogLevel.Info, String.Format("Retrieved Sender Name {0}", senderName));

            var recipientName = message.RecipientUri;

            if (recipient != null)
            {
                _logger.Log(LogLevel.Debug, String.Format("Recipient Found"));

                //if the recipient has a mobile #; send SMS
                if (!String.IsNullOrEmpty(recipient.MobileNumber))
                {
                    _logger.Log(LogLevel.Info, String.Format("Send SMS to Recipient"));

                    smsMessage = String.Format(_recipientSMSMessage, message.Amount, senderName);
                    _smsService.SendSMS(message.ApiKey, recipient.MobileNumber, smsMessage);
                }

                //if the recipient has an email address; send an email
                if(!String.IsNullOrEmpty(recipient.EmailAddress))
                {

                    _logger.Log(LogLevel.Info, String.Format("Send Email to Recipient"));

                    emailSubject = String.Format(_recipientConfirmationEmailSubject, message.Amount, senderName);
                    emailBody = String.Format(_recipientConfirmationEmailBody, message.Amount, senderName);

                    _emailService.SendEmail(message.ApiKey, _fromAddress, recipient.EmailAddress, emailSubject, emailBody);

                }
                //if the recipient has a device token; send a push notification
                if (!String.IsNullOrEmpty(recipient.DeviceToken))
                {
                    _logger.Log(LogLevel.Info, String.Format("Send Push Notification to Recipient"));

                }
                //if the recipient has a linked facebook account; send a facebook message
                if (recipient.FacebookUser != null)
                {
                    _logger.Log(LogLevel.Info, String.Format("Send Facebook Message to Recipient"));

                }

            }
            else
            {
                //if recipient Uri Type is Mobile Number, Send SMS
                if (recipientType == URIType.MobileNumber)
                {
                    _logger.Log(LogLevel.Info, String.Format("Send SMS Message to Recipient"));

                    smsMessage = String.Format(_recipientSMSMessage, message.Amount, senderName);
                    _smsService.SendSMS(message.ApiKey, message.RecipientUri, smsMessage);
                }
                //if recipient Uri Type is email address, Send Email
                if (recipientType == URIType.EmailAddress)
                {
                    _logger.Log(LogLevel.Info, String.Format("Send Emaili Message to Recipient"));

                    emailSubject = String.Format(_recipientConfirmationEmailSubject, message.Amount, senderName);
                    emailBody = String.Format(_recipientConfirmationEmailBody, message.Amount, senderName);

                    _emailService.SendEmail(message.ApiKey, _fromAddress, message.RecipientUri, emailSubject, emailBody);

                }
                //if recipient Uri Type is facebook count, send a facebook message
                if (recipientType == URIType.FacebookAccount)
                {
                    _logger.Log(LogLevel.Info, String.Format("Send Facebook Message to Recipient"));

                }
            }

            //if sender has mobile #, send confirmation email to sender
            if (!String.IsNullOrEmpty(sender.MobileNumber))
            {
                _logger.Log(LogLevel.Info, String.Format("Send SMS to Recipient"));

                smsMessage = String.Format(_senderSMSMessage, message.Amount, recipientName);
                _smsService.SendSMS(message.ApiKey, sender.MobileNumber, smsMessage);

            }

            //if sender has email address; send an email
            if (!String.IsNullOrEmpty(sender.EmailAddress))
            {
                _logger.Log(LogLevel.Info, String.Format("Send Email to Recipient"));

                emailSubject = String.Format(_senderConfirmationEmailSubject, recipientName);
                emailBody = String.Format(_senderConfirmationEmailBody, message.Amount, recipientName);

                _emailService.SendEmail(message.ApiKey, _fromAddress, sender.EmailAddress, emailSubject, emailBody);

            }

            //if sender has a device token; send a push notification
            if (!String.IsNullOrEmpty(sender.DeviceToken))
            {
                _logger.Log(LogLevel.Info, String.Format("Send Push Notification to Recipient"));

            }
            //if sender has a linked facebook account; send a facebook message
            if (sender.FacebookUser != null)
            {
                _logger.Log(LogLevel.Info, String.Format("Send Facebook Message to Recipient"));

            }

            //Update Payment Status
            _logger.Log(LogLevel.Info, String.Format("Updating Payment Request"));

            message.MessageStatus = MessageStatus.Pending;
            message.LastUpdatedDate = System.DateTime.Now;

            _ctx.SaveChanges();

            return true;
        }
        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;
        }