public ActionResult SubmitEnrollment()
        {
            var isRedirectPayment = PropertyBag.IsRedirectPayment;

            try
            {
                // Start creating the API requests
                var apiRequests = new List<ApiRequest>();

                // Create the customer
                var customerRequest = new CreateCustomerRequest(PropertyBag.Customer);
                customerRequest.InsertEnrollerTree = true;
                customerRequest.InsertUnilevelTree = true;
                customerRequest.CustomerType = CustomerTypes.BrandPartner;
                customerRequest.EnrollerID = Identity.Owner.CustomerID;
                customerRequest.SponsorID = Identity.Owner.CustomerID;
                customerRequest.EntryDate = DateTime.Now;
                customerRequest.CustomerStatus = CustomerStatuses.Active;
                customerRequest.CanLogin = true;
                customerRequest.LoginName = PropertyBag.Customer.LoginName;
                customerRequest.Company = PropertyBag.Customer.PublicName;
                customerRequest.CurrencyCode = OrderConfiguration.CurrencyCode;
                customerRequest.PayableType = PayableType.Check;
                customerRequest.LoginPassword = PropertyBag.Customer.Password;
                customerRequest.Notes = "Distributor was entered by Distributor #{0}. Created by the API Enrollment at ".FormatWith(Identity.Owner.CustomerID) + HttpContext.Request.Url.Host + HttpContext.Request.Url.LocalPath + " on " + DateTime.Now.ToString("dddd, MMMM d, yyyy h:mmtt") + " CST at IP " + Common.GlobalUtilities.GetClientIP() + " using " + HttpContext.Request.Browser.Browser + " " + HttpContext.Request.Browser.Version + " (" + HttpContext.Request.Browser.Platform + ").";
                apiRequests.Add(customerRequest);

                // Set a few variables up for our shippping address, order/auto order items and the default auto order payment type
                var shippingAddress = PropertyBag.ShippingAddress;
                shippingAddress.FirstName = PropertyBag.Customer.FirstName;
                shippingAddress.LastName = PropertyBag.Customer.LastName;
                shippingAddress.Phone = PropertyBag.Customer.PrimaryPhone;
                shippingAddress.Email = PropertyBag.Customer.Email;

                var orderItems = ShoppingCart.Items.Where(i => i.Type == ShoppingCartItemType.EnrollmentPack).ToList();

                // Create initial order
                var orderRequest = new CreateOrderRequest(OrderConfiguration, PropertyBag.ShipMethodID, orderItems, shippingAddress);

                if (isRedirectPayment)
                {
                    orderRequest.OrderStatus = OrderStatusType.Pending;
                }

                // Add the new credit card to the customer's record and charge it for the current order
                if (PropertyBag.PaymentMethod.CanBeParsedAs<CreditCard>())
                {
                    var creditCard = PropertyBag.PaymentMethod.As<CreditCard>();

                    // If we are dealing with a test credit card, then we set the order as accepted to simulate an 'Accepted' order
                    if (!creditCard.IsTestCreditCard)
                    {
                        var chargeCCRequest = new ChargeCreditCardTokenRequest(creditCard);
                        apiRequests.Add(chargeCCRequest);

                        var saveCCRequest = new SetAccountCreditCardTokenRequest(creditCard);
                        apiRequests.Add(saveCCRequest);
                    }
                    else
                    {
                        orderRequest.OrderStatus = OrderStatusType.Shipped;
                    }
                }

                // Add order request now if we need to do any testing with the accepted functionality
                apiRequests.Add(orderRequest);

                // Process the transaction
                var transaction = new TransactionalRequest { TransactionRequests = apiRequests.ToArray() };
                var response = Exigo.WebService().ProcessTransaction(transaction);

                var newcustomerid = 0;
                var neworderid = 0;

                if (response.Result.Status == ResultStatus.Success)
                {
                    foreach (var apiresponse in response.TransactionResponses)
                    {
                        if (apiresponse.CanBeParsedAs<CreateCustomerResponse>()) newcustomerid = apiresponse.As<CreateCustomerResponse>().CustomerID;

                        if (apiresponse.CanBeParsedAs<CreateOrderResponse>()) neworderid = apiresponse.As<CreateOrderResponse>().OrderID;
                    }
                }

                // Update the customer web alias
                var propertyBagCustomer = PropertyBag.Customer;
                Task.Factory.StartNew(() =>
                {
                    var customerSiteRequest = new SetCustomerSiteRequest(propertyBagCustomer);
                    customerSiteRequest.CustomerID = newcustomerid;
                    customerSiteRequest.WebAlias = newcustomerid.ToString();
                    customerSiteRequest.FirstName = propertyBagCustomer.FirstName;
                    customerSiteRequest.LastName = propertyBagCustomer.LastName;
                    customerSiteRequest.Company = propertyBagCustomer.PublicName;
                    SetCustomerSiteResponse res = Exigo.WebService().SetCustomerSite(customerSiteRequest);
                });

                var token = Security.Encrypt(new { OrderID = neworderid, CustomerID = newcustomerid });

                if (PropertyBag.Customer.IsOptedIn) {
                    Exigo.SendEmailVerification(newcustomerid, propertyBagCustomer.Email);

                }

                var selectedCountry = PropertyBag.ShippingAddress.Country;

                // handle redirect payments
                if (isRedirectPayment)
                {
                    var paymentProvider = PaymentService.GetPaymentProvider(selectedCountry);
                    var order = Exigo.GetCustomerOrders(new GetCustomerOrdersRequest()
                    {
                        CustomerID = newcustomerid,
                        OrderID = neworderid,
                        IncludeOrderDetails = true
                    }).FirstOrDefault();

                    if (paymentProvider.HandlerType == PaymentHandlerType.Remote)
                    {
                        paymentProvider.OrderConfiguration = OrderConfiguration;
                        paymentProvider.Order = order;
                        paymentProvider.Order.ShipMethodID = PropertyBag.ShipMethodID;

                    }

                    var billingAddress = new Address()
                    {
                        AddressType = AddressType.Other,
                        Address1 = order.Recipient.Address1,
                        Address2 = order.Recipient.Address2,
                        City = order.Recipient.City,
                        State = order.Recipient.State,
                        Zip = order.Recipient.Zip,
                        Country = order.Recipient.Country
                    };

                    // Get the request data
                    var paymentRequest = paymentProvider.GetPaymentRequest(new PaymentRequestArgs() { ReturnUrl = PaymentRedirectURL, BillingName = order.Recipient.FullName, BillingAddress = billingAddress, WebAlias = Identity.Owner.WebAlias });

                    // Handle the request
                    var postPaymentRequest = paymentRequest as POSTPaymentRequest;
                    if (postPaymentRequest != null)
                    {
                        return new JsonNetResult(new
                        {
                            success = true,
                            redirectForm = postPaymentRequest.RequestForm
                        });
                    }
                    else
                    {
                        return new JsonNetResult(new
                        {
                            success = false,
                        });
                    }

                    //if (paymentProvider.HandlerType == PaymentHandlerType.Remote)
                    //{
                    //    //Exigo.PropertyBags.Delete(PropertyBag);
                    //    Exigo.PropertyBags.Delete(ShoppingCart);

                    //    paymentProvider.OrderConfiguration = OrderConfiguration;
                    //    paymentProvider.Order = order;
                    //    paymentProvider.Order.ShipMethodID = PropertyBag.ShipMethodID;

                    //    // Get the request data
                    //    var paymentRequest = paymentProvider.GetPaymentRequest(new PaymentRequestArgs() { ReturnUrl = PaymentRedirectURL, WebAlias = Identity.Owner.WebAlias, BillingAddress = PropertyBag.Customer.MainAddress });

                    //    // Handle the request
                    //    var postPaymentRequest = paymentRequest as POSTPaymentRequest;
                    //    if (postPaymentRequest != null)
                    //    {
                    //        Exigo.PropertyBags.Delete(PropertyBag);

                    //        return new JsonNetResult(new
                    //        {
                    //            success = true,
                    //            redirectForm = postPaymentRequest.RequestForm
                    //        });
                    //    }
                    //}

                    //    return new JsonNetResult(new
                    //    {
                    //    success = false,
                    //    message = "redirect failed"
                    //});
                }

            //    // Enrollment complete, now delete the Property Bag
                Exigo.PropertyBags.Delete(PropertyBag);
                Exigo.PropertyBags.Delete(ShoppingCart);

                return new JsonNetResult(new { token = token, success = true });
            }
            catch (Exception ex)
            {
                return new JsonNetResult(new { message = ex.Message, success = false });
            }
        }
        public ActionResult SubmitCheckout()
        {
            // Do one final check to ensure that our logic points are met before attempting to submit
            var logicResult = LogicProvider.CheckLogic();
            if (!logicResult.IsValid)
            {
                return logicResult.NextAction;
            }

            // Set up our guest customer & testing variables
            var isGuestCheckout = Identity.Customer == null;
            var isLocal = Request.IsLocal;

            var isRedirectPayment = PropertyBag.IsRedirectPayment;

            try
            {
                // Start creating the API requests
                var details = new List<ApiRequest>();

                // Update our Retail Customer to Smart Shopper, if applicable
                if (PropertyBag.GetSmartShopperPrice)
                {
                    var address = PropertyBag.ShippingAddress;

                    var updateCustomerRequest = new UpdateCustomerRequest
                    {
                        CustomerID = Identity.Customer.CustomerID,
                        MainAddress1 = address.Address1,
                        MainAddress2 = address.Address2,
                        MainCity = address.City,
                        MainState = address.State,
                        MainZip = address.Zip,
                        MainCountry = address.Country,
                        CustomerType = CustomerTypes.SmartShopper
                    };

                    details.Add(updateCustomerRequest);

                    // Create the Replicated Site for our Smart Shopper
                    var newSite = new SetCustomerSiteRequest
                    {
                        CustomerID = Identity.Customer.CustomerID,
                        WebAlias = Identity.Customer.CustomerID.ToString(),
                        FirstName = Identity.Customer.FirstName,
                        LastName = Identity.Customer.LastName,
                        Address1 = address.Address1,
                        Address2 = address.Address2,
                        City = address.City,
                        State = address.State,
                        Zip = address.Zip,
                        Country = address.Country,
                        Email = address.Email,
                        Company = Identity.Customer.PublicName,
                        Phone = address.Phone
                    };

                    details.Add(newSite);
                }

                var orderItems = ShoppingCart.Items.Where(c => c.Type == ShoppingCartItemType.Order);
                var hasOrder = orderItems.Count() > 0;

                var autoOrderItems = ShoppingCart.Items.Where(c => c.Type == ShoppingCartItemType.AutoOrder);
                var hasAutoOrder = autoOrderItems.Count() > 0;

                // Create the order request, if applicable
                if (hasOrder)
                {
                    var orderRequest = new CreateOrderRequest(OrderConfiguration, PropertyBag.ShipMethodID, orderItems, PropertyBag.ShippingAddress);

                    if (!isGuestCheckout)
                    {
                        orderRequest.CustomerID = Identity.Customer.CustomerID;
                    }

                    if (isRedirectPayment)
                    {
                        orderRequest.OrderStatus = OrderStatusType.Pending;
                    }

                    if (Identity.Customer.CustomerTypeID == CustomerTypes.SmartShopper)
                    {
                        orderRequest.PriceType = PriceTypes.Wholesale;
                    }

                    if (hasAutoOrder)
                    {
                        orderRequest.PriceType = PriceTypes.Autoship;
                    }

                    details.Add(orderRequest);
                }

                // Create the autoorder request, if applicable
                if (hasAutoOrder)
                {
                    var autoOrderRequest = new CreateAutoOrderRequest(AutoOrderConfiguration, Exigo.GetAutoOrderPaymentType(PropertyBag.PaymentMethod), PropertyBag.AutoOrderStartDate, AutoOrderConfiguration.DefaultShipMethodID, autoOrderItems, PropertyBag.ShippingAddress);

                    autoOrderRequest.Frequency = FrequencyType.Monthly;

                    if (!isGuestCheckout)
                    {
                        autoOrderRequest.CustomerID = Identity.Customer.CustomerID;
                    }

                    details.Add(autoOrderRequest);
                }

                // Create the payment request
                if (PropertyBag.PaymentMethod is CreditCard)
                {
                    var card = PropertyBag.PaymentMethod as CreditCard;
                    if (card.Type == CreditCardType.New)
                    {
                        card = Exigo.SaveNewCustomerCreditCard(Identity.Customer.CustomerID, card);

                        if (hasAutoOrder)
                        {
                            if (!isGuestCheckout)
                            {
                                card = Exigo.SaveNewCustomerCreditCard(Identity.Customer.CustomerID, card);
                                ((CreateAutoOrderRequest)details.Where(c => c is CreateAutoOrderRequest).FirstOrDefault()).PaymentType = Exigo.GetAutoOrderPaymentType(card);
                            }
                            else
                            {
                                // Add logic if guest checkout is allowed : constructor for SetAccountCreditCardTokenRequest

                            }
                        }
                        if (hasOrder)
                        {
                            if (card.IsTestCreditCard)
                            {
                                // no need to charge card
                                ((CreateOrderRequest)details.Where(c => c is CreateOrderRequest).FirstOrDefault()).OrderStatus = OrderStatusType.Shipped;
                            }
                            else
                            {
                                if (!isLocal)
                                {
                                    details.Add(new ChargeCreditCardTokenRequest(card));
                                }
                            }
                        }
                    }
                    else
                    {
                        if (hasOrder)
                        {
                            if (card.IsTestCreditCard)
                            {
                                // no need to charge card
                            }
                            else
                            {
                                if (!isLocal)
                                {
                                    var cctype = (card.Type == CreditCardType.Primary) ? AccountCreditCardType.Primary : AccountCreditCardType.Secondary;
                                    details.Add(new ChargeCreditCardOnFileRequest { CreditCardAccountType = cctype });
                                }
                            }
                        }
                    }
                }

                // Process the transaction
                var transactionRequest = new TransactionalRequest();
                transactionRequest.TransactionRequests = details.ToArray();
                var transactionResponse = Exigo.WebService().ProcessTransaction(transactionRequest);

                var newOrderID = 1;
                var customerID = 0;
                if (transactionResponse.Result.Status == ResultStatus.Success)
                {
                    foreach (var response in transactionResponse.TransactionResponses)
                    {
                        if (response is CreateOrderResponse) newOrderID = ((CreateOrderResponse)response).OrderID;
                        if (response is CreateCustomerResponse) customerID = ((CreateCustomerResponse)response).CustomerID;
                    }
                }

                if (PropertyBag.GetSmartShopperPrice)
                {

                    Identity.Customer.Refresh();
                }

                customerID = Identity.Customer.CustomerID;
                var token = Security.Encrypt(new { OrderID = newOrderID, CustomerID = Identity.Customer.CustomerID });

                // handle redirect payments
                var selectedCountry = PropertyBag.ShippingAddress.Country;

                if (isRedirectPayment && hasOrder)
                {
                    var paymentProvider = PaymentService.GetPaymentProvider(selectedCountry);
                    var order = Exigo.GetCustomerOrders(new GetCustomerOrdersRequest()
                    {
                        CustomerID = customerID,
                        OrderID = newOrderID,
                        IncludeOrderDetails = true
                    }).FirstOrDefault();

                    if (paymentProvider.HandlerType == PaymentHandlerType.Remote)
                    {
                        //Exigo.PropertyBags.Delete(PropertyBag);
                        Exigo.PropertyBags.Delete(ShoppingCart);

                        paymentProvider.OrderConfiguration = OrderConfiguration;
                        paymentProvider.Order = order;
                        paymentProvider.Order.ShipMethodID = PropertyBag.ShipMethodID;

                    }

                    // Get the request data
                    var paymentRequest = paymentProvider.GetPaymentRequest(new PaymentRequestArgs() { ReturnUrl = PaymentRedirectURL, BillingName = order.Recipient.FullName, BillingAddress = PropertyBag.BillingAddress, WebAlias = Identity.Owner.WebAlias });

                    // Handle the request
                    var postPaymentRequest = paymentRequest as POSTPaymentRequest;
                    if (postPaymentRequest != null)
                    {

                        Exigo.PropertyBags.Delete(PropertyBag);

                        return new JsonNetResult(new
                        {
                            success = true,
                            redirectForm = postPaymentRequest.RequestForm
                        });
                    }
                    else
                    {
                        //var urlHelper = new UrlHelper(Request.RequestContext);
                        //var completeUrl = urlHelper.Action("OrderComplete", new { token = token });

                        return new JsonNetResult(new
                        {
                            success = false,
                        });
                    }
                }

                return new JsonNetResult(new
                {
                    success = true,
                    token = token
                });

            }
            catch (Exception exception)
            {
                return new JsonNetResult(new
                {
                    success = false,
                    message = exception.Message
                });
            }
        }