private void CompleteNewStripeSubscription(CreateInvoiceReturn output)
        {
            try
            {
                // Create the Stripe Request and get the data back.
                var response = PerformStripeSubscriptionCheckout(output);
                // If it was successful we will now have a redirect link
                if (response != null)
                {
                    // Try to save the data to our database
                    var result = AddInvoiceToDatabase();

                    if (result)
                    {
                        // Everything was successful
                        if (invoice.Subscription != null)
                        {
                            output.InvoiceId = invoice.InvoiceId;
                            output.Status = InvoiceStatus.Subscription_Running;
                            output.SubscriptionEndsOn = invoice.Subscription.ValidUntil;
                            if (invoice.Subscription.SubscriptionPeriodStripe != SubscriptionPeriodStripe.Monthly_RN_Sponsor)
                            {
                                EmailLeagueAboutSuccessfulSubscription(invoice.Subscription.InternalObject, invoice.InvoiceId, invoice.Subscription.Price, invoice.Subscription.ValidUntil, invoice.InvoiceBilling.Email);

                                RDN.Library.Classes.League.LeagueFactory.UpdateLeagueSubscriptionPeriod(output.SubscriptionEndsOn, true, invoice.Subscription.InternalObject);
                            }
                            else
                            {

                                var emailData = new Dictionary<string, string>
                                        {
                                            { "Why: ", invoice.Note }, 
                                            { "invoiceId",invoice.InvoiceId.ToString().Replace("-","") },
                                            { "Paid",invoice.FinancialData.TotalIncludingTax.ToString("N2")}
                                        };
                                EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_ADMIN_EMAIL_ADMIN, EmailServer.EmailServer.DEFAULT_SUBJECT + " Receipt For RN Subscription", emailData, EmailServer.EmailServerLayoutsEnum.Default);
                                EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_KRIS_WORLIDGE_EMAIL_ADMIN, EmailServer.EmailServer.DEFAULT_SUBJECT + " New Payment Made", emailData, EmailServer.EmailServerLayoutsEnum.Default);

                            }
                        }
                    }
                    else
                    {
                        // Could not save to our database
                        output.Error = "Failed to save to RDN database";
                        output.Status = InvoiceStatus.Failed;
                    }
                }
                else
                {
                    // Could not create a google link
                    //output.Error = response.Error;
                    if (output.Status != InvoiceStatus.Card_Was_Declined)
                        output.Status = InvoiceStatus.Failed;
                }
            }
            catch (Exception exception)
            {
                ErrorDatabaseManager.AddException(exception, exception.GetType());
            }
        }
        /// <summary>
        /// stripe is just telling us they are about to make a new charge and we need to create an invoice.
        /// </summary>
        /// <param name="output"></param>
        private void CompleteStripeSubscriptionUpdated(CreateInvoiceReturn output)
        {
            try
            {
                // Create the Stripe Request and get the data back.
                // Try to save the data to our database
                var result = AddInvoiceToDatabase();

                if (result)
                {
                    // Everything was successful
                    //we just added a new invoice.  Thats all that happened.
                }
                else
                {
                    // Could not save to our database
                    output.Error = "Failed to save to RDN database";
                    output.Status = InvoiceStatus.Failed;
                }
            }
            catch (Exception exception)
            {
                ErrorDatabaseManager.AddException(exception, exception.GetType());
            }
        }
        private void HandleStripePayments(CreateInvoiceReturn output)
        {
            if (invoice.ChargeType == ChargeTypeEnum.Refund_Paywall)
            {
                invoice.InvoiceStatus = InvoiceStatus.Refund_Started;

                // Create the Stripe Request and get the data back.
                var response = PerformStripeRefund();
                // If it was successful we will now have a redirect link
                if (response != null)
                {
                    // Try to save the data to our database
                    if (response.AmountInCentsRefunded.HasValue && response.AmountInCentsRefunded.Value > 0)
                    {
                        PaymentGateway pg = new PaymentGateway();
                        var voice = pg.GetDisplayInvoice(invoice.InvoiceId);
                        if (voice.Refunds.Sum(x => x.RefundAmount) + invoice.FinancialData.RefundAmount == voice.TotalIncludingTax)
                            pg.UpdateInvoiceForRefund(invoice.InvoiceId, InvoiceStatus.Refunded, invoice.FinancialData.RefundAmount, invoice.AdminNote);
                        else
                            pg.UpdateInvoiceForRefund(invoice.InvoiceId, InvoiceStatus.Partially_Refunded, invoice.FinancialData.RefundAmount, invoice.AdminNote);

                        voice.RefundAmount = invoice.FinancialData.RefundAmount;
                        Paywall.Paywall pw = new Paywall.Paywall();
                        pw.HandlePaywallRefund(voice);
                        output.Status = InvoiceStatus.Refunded;
                    }
                    else
                    {
                        // Could not save to our database
                        output.Error = "Failed to save to RDN database";
                        output.Status = InvoiceStatus.Failed;
                    }
                }
                else
                    output.Status = InvoiceStatus.Failed;
            }
            else if (invoice.ChargeType == ChargeTypeEnum.Subscription)
            {
                CompleteNewStripeSubscription(output);
            }
            else if (invoice.ChargeType == ChargeTypeEnum.Paywall)
            {
                CalculateRDNationFeesForPaywallPurchasesStripe();
                // Create the Stripe Request and get the data back.
                var response = PerformStripePaywallPurchaseCheckout();
                // If it was successful we will now have a redirect link
                if (response != null)
                {
                    // Try to save the data to our database
                    var result = AddInvoiceToDatabase();

                    if (result)
                    {
                        output.InvoiceId = invoice.InvoiceId;
                        output.Status = InvoiceStatus.Payment_Successful;

                        PaymentGateway pg = new PaymentGateway();
                        var voice = pg.GetDisplayInvoice(invoice.InvoiceId);
                        Paywall.Paywall pw = new Paywall.Paywall();
                        pw.HandlePaywallPayments(voice);
                    }
                    else
                    {
                        // Could not save to our database
                        output.Error = "Failed to save to RDN database";
                        output.Status = InvoiceStatus.Failed;
                    }
                }
                else
                    output.Status = InvoiceStatus.Failed;
            }
            else if (invoice.ChargeType == ChargeTypeEnum.Cancel_Subscription)
            {
                CancelStripeSubscription(output);
            }
            else if (invoice.ChargeType == ChargeTypeEnum.SubscriptionUpdated)
            {
                CompleteStripeSubscriptionUpdated(output);
            }
            else if (invoice.ChargeType == ChargeTypeEnum.InStorePurchase)
            {
                CalculateRDNationFeesForInStorePurchasesStripe();
                // Create the Stripe Request and get the data back.
                var response = PerformStripeInStorePurchaseCheckout();
                // If it was successful we will now have a redirect link
                if (response != null)
                {
                    // Try to save the data to our database
                    var result = AddInvoiceToDatabase();

                    if (result)
                    {
                        output.InvoiceId = invoice.InvoiceId;
                        output.Status = InvoiceStatus.Payment_Successful;

                        PaymentGateway pg = new PaymentGateway();
                        var voice = pg.GetDisplayInvoice(invoice.InvoiceId);
                        Store.StoreGateway sg = new Store.StoreGateway();
                        sg.HandleStoreItemPayments(voice);
                    }
                    else
                    {
                        // Could not save to our database
                        output.Error = "Failed to save to RDN database";
                        output.Status = InvoiceStatus.Failed;
                    }
                }
                else
                {
                    // Could not create a google link
                    //output.Error = response.Error;
                    output.Status = InvoiceStatus.Failed;
                }
            }
            else if (invoice.ChargeType == ChargeTypeEnum.Stripe_Checkout)
            {

                // Create the Stripe Request and get the data back.
                var response = ChargeStripeCheckoutPayment();
                // If it was successful we will now have a redirect link
                if (response != null)
                {
                    // Try to save the data to our database
                    var result = AddInvoiceToDatabase();

                    if (result)
                    {
                        output.InvoiceId = invoice.InvoiceId;
                        output.Status = InvoiceStatus.Payment_Successful;

                        var emailData = new Dictionary<string, string>
                                        {
                                            { "Why: ", invoice.Note }, 
                                            { "invoiceId",invoice.InvoiceId.ToString().Replace("-","") },
                                            { "Paid",invoice.FinancialData.TotalIncludingTax.ToString("N2")}
                                        };
                        EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_ADMIN_EMAIL_ADMIN, EmailServer.EmailServer.DEFAULT_SUBJECT + " Receipt For League Subscription", emailData, EmailServer.EmailServerLayoutsEnum.Default);
                        EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_KRIS_WORLIDGE_EMAIL_ADMIN, EmailServer.EmailServer.DEFAULT_SUBJECT + " New Payment Made", emailData, EmailServer.EmailServerLayoutsEnum.Default);

                    }
                    else
                    {
                        // Could not save to our database
                        output.Error = "Failed to save to RDN database";
                        output.Status = InvoiceStatus.Failed;
                    }
                }
                else
                {
                    // Could not create a google link
                    //output.Error = response.Error;
                    output.Status = InvoiceStatus.Failed;
                }
            }
        }
        private void CancelStripeSubscription(CreateInvoiceReturn output)
        {
            try
            {
                // Create the Stripe Request and get the data back.
                output.InvoiceId = invoice.InvoiceId;
                var response = PerformStripeSubscriptionCancellation(output);
                // If it was successful we will now have a redirect link
                if (response == true)
                {
                    ManagementContext dc = new ManagementContext();
                    var invoiceDb = dc.Invoices.Include("Items")
                        .Include("Payments").Include("Logs")
                        .Include("Subscription").Include("InvoiceShipping")
                        .Include("InvoiceBilling").Include("Merchant").Where(x => x.InvoiceId == invoice.InvoiceId).FirstOrDefault();


                    output.InvoiceId = invoice.InvoiceId;
                    output.Status = InvoiceStatus.Cancelled;

                    EmailLeagueAboutCancelledSubscription(invoiceDb.Subscription.InternalObject, invoice.InvoiceId, invoiceDb.Subscription.ValidUntil, invoiceDb.InvoiceBilling.Email);

                }
                else
                {
                    output.Status = InvoiceStatus.Failed;
                }
            }
            catch (Exception exception)
            {
                ErrorDatabaseManager.AddException(exception, exception.GetType());
            }
        }
        /// <summary>
        /// Creates the invoice in the system and makes it ready to be processed
        /// </summary>
        /// <returns>Return object containing details needed for the user to continue with the process</returns>
        public CreateInvoiceReturn FinalizeInvoice()
        {
            var output = new CreateInvoiceReturn();
            try
            {
                //if (invoice.ItemsInvoice.Count == 0 && invoice.Subscription == null && invoice.ItemsDues.Count == 0 && invoice.Paywall == null)
                //{
                //    output.Error = "No items, no subscription and no paywall present in the invoice";
                //    return output;
                //}
                //remove when we added a paywall.

                if (invoice.PaymentProvider == PaymentProvider.Stripe)
                {
                    HandleStripePayments(output);
                }
                else if (invoice.PaymentProvider == PaymentProvider.Paypal)
                {
                    HandlePaypalPayments(output);
                    ///add the paypal to the DB.
                    //but don't add if we are just paying out writers.
                    if (invoice.ChargeType != ChargeTypeEnum.RollinNewsWriterPayouts)
                        AddInvoiceToDatabase();
                }
            }
            catch (Exception exception)
            {
                ErrorDatabaseManager.AddException(exception, exception.GetType());
            }
            return output;
        }
        private void HandlePaypalPayments(CreateInvoiceReturn output)
        {
            if (invoice.ChargeType == ChargeTypeEnum.Subscription)
            {
                output.RedirectLink = PerformPaypalSubscriptionCheckout();
                output.Status = InvoiceStatus.Pending_Payment_From_Paypal;
            }
            else if (invoice.ChargeType == ChargeTypeEnum.DuesItem)
            {
                //performs checkout, along with describing the output status.
                PerformPaypalDuesPaymentCheckout(output);
            }
            else if (invoice.ChargeType == ChargeTypeEnum.RollinNewsWriterPrePayout)
            {
                //performs checkout, along with describing the output status.
                PerformPaypalPrePayoutWriterContent(output);
            }
            else if (invoice.ChargeType == ChargeTypeEnum.RollinNewsWriterPayouts)
            {
                //performs checkout, along with describing the output status.
                PerformPaypalRollinNewsWritersPayment(output);
            }
            else if (invoice.ChargeType == ChargeTypeEnum.Paywall)
            {
                CalculateRDNationFeesForPaywallPurchasesPaypal();
                invoice.InvoiceStatus = InvoiceStatus.Awaiting_Payment;
                // If it was successful we will now have a redirect link
                output.RedirectLink = PerformPaypalPaywallPayment();
                if (output.RedirectLink != String.Empty)
                    output.Status = InvoiceStatus.Pending_Payment_From_Paypal;
                else
                    output.Status = InvoiceStatus.Failed;
            }
            //else if (invoice.ChargeType == ChargeTypeEnum.Refund_Paywall)
            //{

            //    invoice.InvoiceStatus = InvoiceStatus.Refund_Started;
            //    // If it was successful we will now have a redirect link
            //    output.RedirectLink = PerformPaypalPaywallRefund();

            //}
            else if (invoice.ChargeType == ChargeTypeEnum.InStorePurchase)
            {
                CalculateRDNationFeesForInStorePurchasesPaypal();
                output.RedirectLink = PerformPaypalInStorePaymentCheckout();
                if (output.RedirectLink != String.Empty)
                    output.Status = InvoiceStatus.Pending_Payment_From_Paypal;
                else
                    output.Status = InvoiceStatus.Failed;
            }
        }
        private void PerformPaypalDuesPaymentCheckout(CreateInvoiceReturn output)
        {
            try
            {
                var duesItem = invoice.ItemsDues.FirstOrDefault();

                if (duesItem != null)
                {
                    var memberPaying = MemberCache.GetMemberDisplay(duesItem.MemberPaidId);
                    var leagueSettings = Dues.DuesFactory.GetDuesSettings(duesItem.DuesId);
                    if (leagueSettings != null)
                    {
                        ReceiverList receiverList = new ReceiverList();
                        //RDNation as a reciever
                        Receiver recRDNation = new Receiver(duesItem.PriceAfterFees);
                        if (invoice.Mode == PaymentMode.Live)
                            recRDNation.email = ServerConfig.DEFAULT_ADMIN_EMAIL_ADMIN;
                        else if (invoice.Mode == PaymentMode.Test)
                            recRDNation.email = ServerConfig.PAYPAL_SELLER_DEBUG_ADDRESS;
                        recRDNation.primary = true;

                        //if we modify this invoiceID, 
                        //you need to modify this code here: 
                        recRDNation.invoiceId = invoice.InvoiceId.ToString().Replace("-", "") + ": " + leagueSettings.LeagueOwnerName + " Dues Payment";
                        recRDNation.paymentType = PaymentTypeEnum.SERVICE.ToString();
                        receiverList.receiver.Add(recRDNation);

                        Receiver recLeague = new Receiver(duesItem.BasePrice);
                        recLeague.amount = duesItem.BasePrice;
                        if (invoice.Mode == PaymentMode.Live)
                            recLeague.email = leagueSettings.PayPalEmailAddress;
                        else if (invoice.Mode == PaymentMode.Test)
                            recLeague.email = "*****@*****.**";

                        recLeague.primary = false;
                        //if we modify this invoiceID, 
                        //you need to modify this code here: 
                        recLeague.invoiceId = invoice.InvoiceId.ToString().Replace("-", "") + ": " + leagueSettings.LeagueOwnerName + " Dues Payment";
                        recLeague.paymentType = PaymentTypeEnum.SERVICE.ToString();
                        receiverList.receiver.Add(recLeague);

                        PayRequest req = new PayRequest(new RequestEnvelope("en_US"), ActionTypeEnum.PAY.ToString(), ServerConfig.LEAGUE_DUES_MANAGEMENT_URL + leagueSettings.LeagueOwnerId.ToString().Replace("-", ""), invoice.Currency, receiverList, ServerConfig.LEAGUE_DUES_RECEIPT_URL + invoice.InvoiceId.ToString().Replace("-", ""));
                        req.feesPayer = FeesPayerEnum.PRIMARYRECEIVER.ToString();
                        req.memo = "Dues payment for " + leagueSettings.LeagueOwnerName + " from " + memberPaying.DerbyName + " for " + duesItem.PaidForDate.ToShortDateString();
                        req.reverseAllParallelPaymentsOnError = false;
                        req.trackingId = invoice.InvoiceId.ToString().Replace("-", "");
                        if (invoice.Mode == PaymentMode.Live)
                            req.ipnNotificationUrl = ServerConfig.PAYPAL_IPN_HANDLER;
                        else if (invoice.Mode == PaymentMode.Test)
                            req.ipnNotificationUrl = ServerConfig.PAYPAL_IPN_HANDLER_DEBUG;

                        // All set. Fire the request            
                        AdaptivePaymentsService service = new AdaptivePaymentsService();
                        PayResponse resp = service.Pay(req);



                        // Display response values. 
                        Dictionary<string, string> keyResponseParams = new Dictionary<string, string>();
                        string redirectUrl = null;
                        if (!(resp.responseEnvelope.ack == AckCode.FAILURE) &&
                            !(resp.responseEnvelope.ack == AckCode.FAILUREWITHWARNING))
                        {
                            //EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_ADMIN_EMAIL_ADMIN, "Paypal Dues Payment Waiting To be Finished", invoice.InvoiceId + " Amount:" + duesItem.PriceAfterFees + ":" + leagueSettings.PayPalEmailAddress);

                            if (invoice.Mode == PaymentMode.Live)
                                redirectUrl = PaypalPaymentFactory.GetBaseUrl(PaypalPaymentFactory.PaypalMode.live);
                            else if (invoice.Mode == PaymentMode.Test)
                                redirectUrl = PaypalPaymentFactory.GetBaseUrl(PaypalPaymentFactory.PaypalMode.test);

                            redirectUrl += "?cmd=_ap-payment&paykey=" + resp.payKey;
                            keyResponseParams.Add("Pay key", resp.payKey);
                            keyResponseParams.Add("Payment execution status", resp.paymentExecStatus);
                            if (resp.defaultFundingPlan != null && resp.defaultFundingPlan.senderFees != null)
                            {
                                keyResponseParams.Add("Sender fees", resp.defaultFundingPlan.senderFees.amount +
                                                            resp.defaultFundingPlan.senderFees.code);
                            }

                            //Selenium Test Case
                            keyResponseParams.Add("Acknowledgement", resp.responseEnvelope.ack.ToString());
                            output.RedirectLink = redirectUrl;
                            output.Status = InvoiceStatus.Pending_Payment_From_Paypal;
                        }
                        else
                        {
                            if (resp.error.FirstOrDefault().message.Contains(ServerConfig.DEFAULT_ADMIN_EMAIL_ADMIN + " is restricted"))
                            {
                                output.Status = InvoiceStatus.Paypal_Email_Not_Confirmed;

                                var emailData = new Dictionary<string, string>
                                        {
                                            { "confirmPaypalAccountLink",ServerConfig.WIKI_URL_FOR_CONFIRMED_PAYPAL_ACCOUNT},
                                            { "paypalEmailAccount", leagueSettings.PayPalEmailAddress},
                                            { "duesSettingsLink", ServerConfig.LEAGUE_DUES_SETTINGS_URL +leagueSettings.LeagueOwnerId.ToString().Replace("-", "") + "/" + leagueSettings.DuesId.ToString().Replace("-", "")}
                                                                                    };

                                EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_EMAIL, EmailServer.EmailServer.DEFAULT_SUBJECT + " Paypal Email Is Restricted: " + resp.error.FirstOrDefault().message, emailData, EmailServer.EmailServerLayoutsEnum.PaypalEmailIsRestricted);

                            }
                            //paypal account hasn't been confirmed by the league.
                            else if (resp.error.FirstOrDefault().message.Contains("isn't confirmed by PayPal") || resp.error.FirstOrDefault().message.Contains("is restricted") || resp.error.FirstOrDefault().message.Contains("fields are specified to identify a receiver"))
                            {
                                //if the paypal account hasn't been confirmed, we send the league an email
                                //and disable their paypal account for dues.
                                output.Status = InvoiceStatus.Paypal_Email_Not_Confirmed;

                                var emailData = new Dictionary<string, string>
                                        {
                                            { "confirmPaypalAccountLink",ServerConfig.WIKI_URL_FOR_CONFIRMED_PAYPAL_ACCOUNT},
                                            { "paypalEmailAccount", leagueSettings.PayPalEmailAddress},
                                            { "duesSettingsLink", ServerConfig.LEAGUE_DUES_SETTINGS_URL +leagueSettings.LeagueOwnerId.ToString().Replace("-", "") + "/" + leagueSettings.DuesId.ToString().Replace("-", "")}
                                                                                    };
                                if (resp.error.FirstOrDefault().message.Contains("isn't confirmed by PayPal"))
                                {
                                    if (!String.IsNullOrEmpty(leagueSettings.PayPalEmailAddress))
                                        EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, leagueSettings.PayPalEmailAddress, EmailServer.EmailServer.DEFAULT_SUBJECT + " Paypal Email Isn't Confirmed", emailData, EmailServer.EmailServerLayoutsEnum.PayPalEmailIsNotConfirmed);
                                    if (!String.IsNullOrEmpty(leagueSettings.LeagueEmailAddress))
                                        EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, leagueSettings.LeagueEmailAddress, EmailServer.EmailServer.DEFAULT_SUBJECT + " Paypal Email Isn't Confirmed", emailData, EmailServer.EmailServerLayoutsEnum.PayPalEmailIsNotConfirmed);
                                    EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_EMAIL, EmailServer.EmailServer.DEFAULT_SUBJECT + " Paypal Email Isn't Confirmed: " + resp.error.FirstOrDefault().message, emailData, EmailServer.EmailServerLayoutsEnum.PayPalEmailIsNotConfirmed);
                                }
                                if (resp.error.FirstOrDefault().message.Contains("is restricted"))
                                {
                                    if (!String.IsNullOrEmpty(leagueSettings.PayPalEmailAddress))
                                        EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, leagueSettings.PayPalEmailAddress, EmailServer.EmailServer.DEFAULT_SUBJECT + " Paypal Email Is Restricted", emailData, EmailServer.EmailServerLayoutsEnum.PaypalEmailIsRestricted);
                                    if (!String.IsNullOrEmpty(leagueSettings.LeagueEmailAddress))
                                        EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, leagueSettings.LeagueEmailAddress, EmailServer.EmailServer.DEFAULT_SUBJECT + " Paypal Email Is Restricted", emailData, EmailServer.EmailServerLayoutsEnum.PaypalEmailIsRestricted);
                                    EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_EMAIL, EmailServer.EmailServer.DEFAULT_SUBJECT + " Paypal Email Is Restricted: " + resp.error.FirstOrDefault().message, emailData, EmailServer.EmailServerLayoutsEnum.PaypalEmailIsRestricted);
                                }
                                if (resp.error.FirstOrDefault().message.Contains("specified to identify a receiver"))
                                {
                                    if (!String.IsNullOrEmpty(leagueSettings.PayPalEmailAddress))
                                        EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, leagueSettings.PayPalEmailAddress, EmailServer.EmailServer.DEFAULT_SUBJECT + " Paypal Email Not Specified", emailData, EmailServer.EmailServerLayoutsEnum.PaypalEmailIsRestricted);
                                    if (!String.IsNullOrEmpty(leagueSettings.LeagueEmailAddress))
                                        EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, leagueSettings.LeagueEmailAddress, EmailServer.EmailServer.DEFAULT_SUBJECT + " Paypal Email Not Specified", emailData, EmailServer.EmailServerLayoutsEnum.PaypalEmailIsRestricted);
                                    EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_EMAIL, EmailServer.EmailServer.DEFAULT_SUBJECT + " Paypal Email Not Specified: " + resp.error.FirstOrDefault().message, emailData, EmailServer.EmailServerLayoutsEnum.PaypalEmailIsRestricted);
                                }
                                Dues.DuesFactory.DisablePaypalDuesAccountForLeague(leagueSettings.DuesId);

                            }
                            else
                            {
                                output.Status = InvoiceStatus.Failed;
                                throw new Exception("Failure Payment " + leagueSettings.PayPalEmailAddress + ":" + resp.error.FirstOrDefault().message + ":" + Newtonsoft.Json.JsonConvert.SerializeObject(req));
                            }
                        }

                    }
                }
            }
            catch (Exception exception)
            {
                ErrorDatabaseManager.AddException(exception, exception.GetType());
            }
        }
        /// <summary>
        /// perform any prepayout writers content
        /// </summary>
        /// <param name="output"></param>
        private void PerformPaypalPrePayoutWriterContent(CreateInvoiceReturn output)
        {
            try
            {
                var payout = invoice.RNWriterPayouts.FirstOrDefault();

                var fundInfo = Fund.GetCurrentFundsInformation(payout.UserPaidId);

                var emailData = new Dictionary<string, string>
                                        {
                                            { "emailForPayment",fundInfo.PaypalAddress},
                                            { "amountForPayment", payout.BasePrice.ToString()},
                                            { "amountForPaymentAfterFee", invoice.FinancialData.BasePriceForItems.ToString()},
                                        };

                EmailServer.EmailServer.SendEmail(RollinNewsConfig.DEFAULT_EMAIL, RollinNewsConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_ADMIN_EMAIL_ADMIN, EmailServer.EmailServer.DEFAULT_SUBJECT_ROLLIN_NEWS + " Payment Requested", emailData, EmailServer.EmailServerLayoutsEnum.RNPaymentRequested);
                EmailServer.EmailServer.SendEmail(RollinNewsConfig.DEFAULT_EMAIL, RollinNewsConfig.DEFAULT_EMAIL_FROM_NAME, RollinNewsConfig.DEFAULT_MRX_EMAIL_ADMIN, EmailServer.EmailServer.DEFAULT_SUBJECT_ROLLIN_NEWS + " Payment Requested", emailData, EmailServer.EmailServerLayoutsEnum.RNPaymentRequested);

                invoice.InvoiceStatus = InvoiceStatus.Payment_Awaiting_For_Mass_Payout;
            }
            catch (Exception exception)
            {
                ErrorDatabaseManager.AddException(exception, exception.GetType());
            }
        }
        private static void SendErrorsOfMassPayToAdmins(CreateInvoiceReturn output, MassPayResponseType massPayResponse)
        {
            if (massPayResponse.Errors != null && massPayResponse.Errors.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                foreach (var error in massPayResponse.Errors)
                {
                    sb.Append("code:" + error.ErrorCode);
                    sb.Append(",long:" + error.LongMessage);
                    sb.Append(",severity:" + error.SeverityCode);
                    sb.Append(",shortMessage:" + error.ShortMessage);
                    foreach (var item in error.ErrorParameters)
                    {
                        sb.Append(",param:" + item.ParamID + ";" + item.Value);
                    }
                    sb.Append("________");
                }

                output.Status = InvoiceStatus.Paypal_Email_Not_Confirmed;

                var emailData = new Dictionary<string, string> { { "body", sb.ToString() } };
                EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_EMAIL, ServerConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_ADMIN_EMAIL_ADMIN, " Mass Pay Problem", emailData, EmailServer.EmailServerLayoutsEnum.Blank);
            }
            else
            {
                output.Status = InvoiceStatus.Failed;
                throw new Exception("Failure MASS Payment ");
            }
        }
        private void PerformPaypalRollinNewsWritersPayment(CreateInvoiceReturn output)
        {
            try
            {
                var status = (byte)InvoiceStatus.Payment_Awaiting_For_Mass_Payout;
                var dc = new ManagementContext();
                var invoices = dc.Invoices.Include("InvoiceBilling").Include("WriterPayouts").Where(x => x.InvoiceStatus == status).ToList();


                // Create request object
                List<Fund> tempFundsBeingPaid = new List<Fund>();
                MassPayRequestType request = new MassPayRequestType();
                ReceiverInfoCodeType receiverInfoType = ReceiverInfoCodeType.EMAILADDRESS;

                request.ReceiverType = receiverInfoType;
                // (Optional) The subject line of the email that PayPal sends when the transaction completes. The subject line is the same for all recipients.
                request.EmailSubject = "Payment For Rollin News Content " + DateTime.UtcNow.ToString("yyyy/MM/dd");

                foreach (var invoice in invoices)
                {
                    var payout = invoice.WriterPayouts.FirstOrDefault();

                    //gotta check if we are already paying this user.
                    var f = tempFundsBeingPaid.Where(x => x.UserId == payout.UserPaidId).FirstOrDefault();
                    if (f != null)
                    {
                        if (f.ActiveInUserAccount >= (f.AmountToWithdraw + (double)invoice.BasePriceForItems))
                        {
                            f.AmountToWithdraw += (double)payout.PriceAfterFees;
                            f.AmountToDeductFromTotal += (double)invoice.BasePriceForItems;

                        }
                    }
                    else
                    {
                        var fundSettings = Fund.GetCurrentFundsInformation(payout.UserPaidId);
                        if ((double)invoice.BasePriceForItems <= fundSettings.ActiveInUserAccount)
                        {
                            fundSettings.AmountToWithdraw += (double)payout.PriceAfterFees;
                            fundSettings.AmountToDeductFromTotal += (double)invoice.BasePriceForItems;
                            tempFundsBeingPaid.Add(fundSettings);
                        }
                    }

                }
                for (int i = 0; i < tempFundsBeingPaid.Count; i++)
                {
                    // (Required) Details of each payment.
                    // Note:
                    // A single MassPayRequest can include up to 250 MassPayItems.
                    MassPayRequestItemType massPayItem = new MassPayRequestItemType();
                    CurrencyCodeType currency = CurrencyCodeType.USD;
                    massPayItem.Amount = new BasicAmountType(currency, tempFundsBeingPaid[i].AmountToWithdraw.ToString("N2"));
                    massPayItem.ReceiverEmail = tempFundsBeingPaid[i].PaypalAddress;
                    massPayItem.Note = "Thanks for writing for Rollin News!  We appreciate your content. ID:" + invoice.InvoiceId.ToString().Replace("-", "");
                    if (!String.IsNullOrEmpty(tempFundsBeingPaid[i].PaypalAddress))
                        request.MassPayItem.Add(massPayItem);

                }

                // Invoke the API
                MassPayReq wrapper = new MassPayReq();
                wrapper.MassPayRequest = request;


                // Create the PayPalAPIInterfaceServiceService service object to make the API call
                PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService();

                // # API call 
                // Invoke the MassPay method in service wrapper object  
                MassPayResponseType massPayResponse = service.MassPay(wrapper);

                // Display response values. 
                Dictionary<string, string> keyResponseParams = new Dictionary<string, string>();
                if (!(massPayResponse.Ack == AckCodeType.FAILURE) &&
                    !(massPayResponse.Ack == AckCodeType.FAILUREWITHWARNING))
                {


                    if (!(massPayResponse.Ack == AckCodeType.SUCCESS))
                    {

                        SendErrorsOfMassPayToAdmins(output, massPayResponse);
                        ErrorDatabaseManager.AddException(new Exception("MASSPAYERROR"), GetType(), additionalInformation: Newtonsoft.Json.JsonConvert.SerializeObject(tempFundsBeingPaid) + "______" + Newtonsoft.Json.JsonConvert.SerializeObject(massPayResponse));

                    }

                    for (int i = 0; i < tempFundsBeingPaid.Count; i++)
                    {
                        try
                        {
                            var user = SiteCache.GetPublicMemberFullWithUserId(tempFundsBeingPaid[i].UserId);
                            bool success = Fund.UpdateAmounts(tempFundsBeingPaid[i].UserId, tempFundsBeingPaid[i].TotalPaidToUser);

                            var emailData = new Dictionary<string, string> 
                            { 
                            { "derbyName", user.DerbyName},
                            {"amountPaid", tempFundsBeingPaid[i].AmountToDeductFromTotal.ToString("N2")}};
                            EmailServer.EmailServer.SendEmail(RollinNewsConfig.DEFAULT_EMAIL, RollinNewsConfig.DEFAULT_EMAIL_FROM_NAME, user.UserName, EmailServer.EmailServer.DEFAULT_SUBJECT_ROLLIN_NEWS + " You Were Just Paid!", emailData, EmailServer.EmailServerLayoutsEnum.RNPaymentJustPaid);
                        }
                        catch (Exception exception)
                        {
                            ErrorDatabaseManager.AddException(exception, exception.GetType());
                        }
                    }
                    var emailDataComplete = new Dictionary<string, string> { { "totalPaid", tempFundsBeingPaid.Sum(x=>x.AmountToDeductFromTotal).ToString("N2") },
                    {"totalUsersPaid", tempFundsBeingPaid.Count.ToString()}};
                    EmailServer.EmailServer.SendEmail(ServerConfig.DEFAULT_ADMIN_EMAIL_ADMIN, RollinNewsConfig.DEFAULT_EMAIL_FROM_NAME, ServerConfig.DEFAULT_ADMIN_EMAIL_ADMIN, EmailServer.EmailServer.DEFAULT_SUBJECT_ROLLIN_NEWS + " Mass Pay Completed!", emailDataComplete, EmailServer.EmailServerLayoutsEnum.RNPaymentJustCompleted);

                    for (int i = 0; i < invoices.Count; i++)
                    {
                        Payment.PaymentGateway pg = new PaymentGateway();
                        pg.SetInvoiceStatus(invoices[i].InvoiceId, InvoiceStatus.Payment_Successful);
                    }
                }
                else
                {
                    SendErrorsOfMassPayToAdmins(output, massPayResponse);
                }


            }
            catch (Exception exception)
            {
                ErrorDatabaseManager.AddException(exception, exception.GetType());
            }
        }
        private CreateInvoiceReturn ChargeStripeCheckoutPayment()
        {
            // Create the Stripe Request and get the data back.
            CreateInvoiceReturn output = new CreateInvoiceReturn();

            var myCustomer = new StripeCustomerCreateOptions();
            if (invoice.InvoiceBilling != null)
            {
                myCustomer.CardAddressCity = invoice.InvoiceBilling.City;
                myCustomer.CardAddressCountry = invoice.InvoiceBilling.Country;
                myCustomer.CardAddressLine1 = invoice.InvoiceBilling.Street;
                myCustomer.CardAddressState = invoice.InvoiceBilling.State;
                myCustomer.CardAddressZip = invoice.InvoiceBilling.Zip;
                myCustomer.Email = invoice.InvoiceBilling.Email;
            }

            myCustomer.TokenId = invoice.StripeToken;

            var myCharge = new StripeChargeCreateOptions();

            var customerService = new StripeCustomerService();

            StripeCustomer stripeCustomer = customerService.Create(myCustomer);

            // always set these properties
            //need to convert to cents because thats what stripe uses.
            myCharge.AmountInCents = (int)(invoice.FinancialData.TotalIncludingTax * 100);
            myCharge.Currency = invoice.Currency.ToString();

            // set this if you want to
            myCharge.Description = invoice.Note;

            // set this property if using a token
            myCharge.CustomerId = stripeCustomer.Id;
            myCharge.Capture = true;

            var chargeService = new StripeChargeService();
            StripeCharge stripeCharge = chargeService.Create(myCharge);

            output.InvoiceId = invoice.InvoiceId;
            output.Status = InvoiceStatus.Stripe_Customer_Created_And_Charged;
            invoice.InvoiceStatus = InvoiceStatus.Stripe_Customer_Created_And_Charged;
            return output;
        }
        private bool PerformStripeSubscriptionCancellation(CreateInvoiceReturn invoiceReturn)
        {
            try
            {
                ManagementContext dc = new ManagementContext();
                var invoice = dc.Invoices.Include("Items")
                    .Include("Payments").Include("Logs")
                    .Include("Subscription").Include("InvoiceShipping")
                    .Include("InvoiceBilling").Include("Merchant").Where(x => x.InvoiceId == invoiceReturn.InvoiceId).FirstOrDefault();

                if (invoice != null)
                {
                    invoice.InvoiceStatus = (byte)InvoiceStatus.Cancelled;
                    invoice.PaymentProvider = invoice.PaymentProvider;
                    invoice.BasePriceForItems = invoice.BasePriceForItems;
                    invoice.Merchant = invoice.Merchant;
                    var customerService = new StripeCustomerService();
                    StripeSubscription subscription = customerService.CancelSubscription(invoice.PaymentProviderCustomerId);
                    int c = dc.SaveChanges();
                    return c > 0;
                }
            }
            catch (Exception exception)
            {
                ErrorDatabaseManager.AddException(exception, exception.GetType());
                if (exception.Message.Contains("Your card was declined"))
                    invoiceReturn.Status = InvoiceStatus.Card_Was_Declined;
            }
            return false;
        }
        private StripeCustomer PerformStripeSubscriptionCheckout(CreateInvoiceReturn invoiceReturn)
        {
            try
            {
                var myCustomer = new StripeCustomerCreateOptions();
                if (invoice.InvoiceBilling != null)
                {
                    myCustomer.CardAddressCity = invoice.InvoiceBilling.City;
                    myCustomer.CardAddressCountry = invoice.InvoiceBilling.Country;
                    myCustomer.CardAddressLine1 = invoice.InvoiceBilling.Street;
                    myCustomer.CardAddressState = invoice.InvoiceBilling.State;
                    myCustomer.CardAddressZip = invoice.InvoiceBilling.Zip;
                    myCustomer.Email = invoice.InvoiceBilling.Email;
                }
                if (invoice.Subscription != null)
                {
                    myCustomer.TokenId = invoice.Subscription.ArticleNumber;
                    if (invoice.Subscription.SubscriptionPeriodStripe == SubscriptionPeriodStripe.Monthly)
                    {
                        myCustomer.PlanId = StripePlanNames.Monthly_Plan.ToString();
                    }
                    else if (invoice.Subscription.SubscriptionPeriodStripe == SubscriptionPeriodStripe.Six_Months)
                    {
                        myCustomer.PlanId = StripePlanNames.Six_Month_League_Subscription.ToString();
                    }
                    else if (invoice.Subscription.SubscriptionPeriodStripe == SubscriptionPeriodStripe.Three_Months)
                    {
                        myCustomer.PlanId = StripePlanNames.Three_Month_League_Subscription.ToString();
                    }
                    else if (invoice.Subscription.SubscriptionPeriodStripe == SubscriptionPeriodStripe.Yearly)
                    {
                        myCustomer.PlanId = StripePlanNames.Yearly_League_Subscription.ToString();
                    }
                    else if (invoice.Subscription.SubscriptionPeriodStripe == SubscriptionPeriodStripe.Monthly_RN_Sponsor)
                    {
                        myCustomer.PlanId = StripePlanNames.Monthly_RN_Sponsor.ToString();
                    }
                }
                //creates the customer
                //adds the subscription
                //charges the customer.
                var customerService = new StripeCustomerService();
                StripeCustomer stripeCustomer = customerService.Create(myCustomer);
                invoice.PaymentProviderCustomerId = stripeCustomer.Id;

                return stripeCustomer;
            }
            catch (Exception exception)
            {
                ErrorDatabaseManager.AddException(exception, exception.GetType());
                if (exception.Message.Contains("Your card was declined"))
                    invoiceReturn.Status = InvoiceStatus.Card_Was_Declined;
            }
            return null;
        }