protected override void BuildPostForm(Order order, IndividualOrderCollection indOrders, decimal price, decimal shipping, Customer customer)
        {
            var remotePostHelper = new RemotePost { FormName = "AssistForm", Url = GetPaymentServiceUrl() };
            remotePostHelper.Add("Merchant_ID", "706403");
            remotePostHelper.Add("OrderNumber", order.OrderID.ToString());
            remotePostHelper.Add("OrderAmount", Math.Round(price + shipping).ToString());
            remotePostHelper.Add("OrderCurrency", ConvertToUsd ? "USD" : CurrencyId);
            remotePostHelper.Add("TestMode", IsTestMode? "1": "0");
            if (!String.IsNullOrEmpty(customer.BillingAddress.LastName))
            {
                remotePostHelper.Add("Lastname", customer.BillingAddress.LastName);
            }
            if (!String.IsNullOrEmpty(customer.BillingAddress.FirstName))
            {
                remotePostHelper.Add("Firstname", customer.BillingAddress.FirstName);
            }
            if (!String.IsNullOrEmpty(customer.BillingAddress.Email))
            {
                remotePostHelper.Add("Email", customer.BillingAddress.Email);
            }

            remotePostHelper.Add("URL_RETURN_OK", SettingManager.GetSettingValue("PaymentMethod.Assist.OkUrl"));
            remotePostHelper.Add("URL_RETURN_NO", SettingManager.GetSettingValue("PaymentMethod.Assist.NoUrl"));

            remotePostHelper.Post();
        }
Example #2
0
        /// <summary>
        /// Gets a value indicating whether tax is free
        /// </summary>
        /// <param name="productVariant">Product variant</param>
        /// <param name="customer">Customer</param>
        /// <returns>A value indicating whether tax is free</returns>
        protected static bool IsFreeTax(ProductVariant productVariant, Customer customer)
        {
            if (customer != null)
            {
                if (customer.IsTaxExempt)
                    return true;

                CustomerRoleCollection customerRoles = customer.CustomerRoles;
                foreach (CustomerRole customerRole in customerRoles)
                    if (customerRole.TaxExempt)
                        return true;
            }
            
            if (productVariant == null)
            {
                return false;
            }

            if (productVariant.IsTaxExempt)
            {
                return true;
            }

            return false;
        }
Example #3
0
 protected void Page_Load(object sender, EventArgs e)
 {
     customer = CustomerManager.GetCustomerById(this.CustomerId);
     if (!Page.IsPostBack)
     {              
         this.BindData();
     }
 }
Example #4
0
        /// <summary>
        /// Create request for tax calculation
        /// </summary>
        /// <param name="productVariant">Product variant</param>
        /// <param name="TaxClassID">Tax class identifier</param>
        /// <param name="customer">Customer</param>
        /// <returns>Package for tax calculation</returns>
        protected static CalculateTaxRequest CreateCalculateTaxRequest(ProductVariant productVariant, int TaxClassID, Customer customer)
        {
            CalculateTaxRequest calculateTaxRequest = new CalculateTaxRequest();
            calculateTaxRequest.Customer = customer;
            calculateTaxRequest.Item = productVariant;
            calculateTaxRequest.TaxClassID = TaxClassID;

            TaxBasedOnEnum basedOn = TaxManager.TaxBasedOn;

            if (basedOn == TaxBasedOnEnum.BillingAddress)
            {
                if (customer == null || customer.BillingAddress == null)
                {
                    basedOn = TaxBasedOnEnum.DefaultAddress;
                }
            }
            if (basedOn == TaxBasedOnEnum.ShippingAddress)
            {
                if (customer == null || customer.ShippingAddress == null)
                {
                    basedOn = TaxBasedOnEnum.DefaultAddress;
                }
            }

            Address address = null;

            switch (basedOn)
            {
                case TaxBasedOnEnum.BillingAddress:
                    {
                        address = customer.BillingAddress;
                    }
                    break;
                case TaxBasedOnEnum.ShippingAddress:
                    {
                        address = customer.ShippingAddress;
                    }
                    break;
                case TaxBasedOnEnum.DefaultAddress:
                    {
                        address = TaxManager.DefaultTaxAddress;
                    }
                    break;
                case TaxBasedOnEnum.ShippingOrigin:
                    {
                        address = ShippingManager.ShippingOrigin;
                    }
                    break;
            }

            calculateTaxRequest.Address = address;
            return calculateTaxRequest;
        }
Example #5
0
 /// <summary>
 /// Checks discount limitations for customer
 /// </summary>
 /// <param name="discount">Discount</param>
 /// <param name="customer">Customer</param>
 /// <returns>Value indicating whether discount can be used</returns>
 public static bool CheckDiscountLimitations(this Discount discount, Customer customer)
 {
     switch (discount.DiscountLimitation)
     {
         case DiscountLimitationEnum.Unlimited:
             {
                 return true;
             }
         case DiscountLimitationEnum.OneTimeOnly:
             {
                 var usageHistory = IoC.Resolve<IDiscountService>().GetAllDiscountUsageHistoryEntries(discount.DiscountId, null, null);
                 return usageHistory.Count < 1;
             }
         case DiscountLimitationEnum.NTimesOnly:
             {
                 var usageHistory = IoC.Resolve<IDiscountService>().GetAllDiscountUsageHistoryEntries(discount.DiscountId, null, null);
                 return usageHistory.Count < discount.LimitationTimes;
             }
         case DiscountLimitationEnum.OneTimePerCustomer:
             {
                 if (customer != null && !customer.IsGuest)
                 {
                     //registered customer
                     var usageHistory = IoC.Resolve<IDiscountService>().GetAllDiscountUsageHistoryEntries(discount.DiscountId, customer.CustomerId, null);
                     return usageHistory.Count < 1;
                 }
                 else
                 {
                     //guest
                     return true;
                 }
             }
         case DiscountLimitationEnum.NTimesPerCustomer:
             {
                 if (customer != null && !customer.IsGuest)
                 {
                     //registered customer
                     var usageHistory = IoC.Resolve<IDiscountService>().GetAllDiscountUsageHistoryEntries(discount.DiscountId, customer.CustomerId, null);
                     return usageHistory.Count < discount.LimitationTimes;
                 }
                 else
                 {
                     //guest
                     return true;
                 }
             }
         default:
             break;
     }
     return false;
 }
 protected string GetCustomerInfo(Customer customer)
 {
     string customerInfo = string.Empty;
     if (customer != null)
     {
         if (customer.IsGuest)
         {
             customerInfo = Server.HtmlEncode(GetLocaleResourceString("Admin.Customers.Guest"));
         }
         else
         {
             customerInfo = Server.HtmlEncode(customer.Email);
         }
     }
     return customerInfo;
 }
 /// <summary>
 /// Process payment
 /// </summary>
 /// <param name="paymentInfo">Payment info required for an order processing</param>
 /// <param name="customer">Customer</param>
 /// <param name="OrderGuid">Unique order identifier</param>
 /// <param name="processPaymentResult">Process payment result</param>
 public static void ProcessPayment(PaymentInfo paymentInfo, Customer customer, Guid OrderGuid, ref ProcessPaymentResult processPaymentResult)
 {
     if (paymentInfo.OrderTotal == decimal.Zero)
     {
         processPaymentResult.Error = string.Empty;
         processPaymentResult.FullError = string.Empty;
         processPaymentResult.PaymentStatus = PaymentStatusEnum.Paid;
     }
     else
     {
         PaymentMethod paymentMethod = PaymentMethodManager.GetPaymentMethodByID(paymentInfo.PaymentMethodID);
         if (paymentMethod == null)
             throw new NopException("Payment method couldn't be loaded");
         IPaymentMethod iPaymentMethod = Activator.CreateInstance(Type.GetType(paymentMethod.ClassName)) as IPaymentMethod;
         iPaymentMethod.ProcessPayment(paymentInfo, customer, OrderGuid, ref processPaymentResult);
     }
 }
        protected List<Address> GetAllowedShippingAddresses(Customer customer)
        {
            var addresses = new List<Address>();
            if (customer == null)
                return addresses;

            foreach (var address in customer.ShippingAddresses)
            {
                var country = address.Country;
                if (country != null && country.AllowsShipping)
                {
                    addresses.Add(address);
                }
            }

            return addresses;
        }
        protected List<Address> GetAllowedBillingAddresses(Customer customer)
        {
            var addresses = new List<Address>();
            if (customer == null)
                return addresses;

            foreach (var address in customer.BillingAddresses)
            {
                var country = address.Country;
                if (country != null && country.AllowsBilling)
                {
                    if (address.AddressId == customer.BillingAddressId)
                    {
                        addresses.Add(address);
                        break;
                    }
                }
            }

            return addresses;
        }
Example #10
0
        /// <summary>
        /// Gets a shipping discount
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <param name="shippingTotal">Shipping total</param>
        /// <param name="appliedDiscount">Applied discount</param>
        /// <returns>Shipping discount</returns>
        public static decimal GetShippingDiscount(Customer customer, 
            decimal shippingTotal, out Discount appliedDiscount)
        {
            decimal shippingDiscountAmount = decimal.Zero;

            string customerCouponCode = string.Empty;
            if (customer != null)
                customerCouponCode = customer.LastAppliedCouponCode;

            var allDiscounts = DiscountManager.GetAllDiscounts(DiscountTypeEnum.AssignedToShipping);
            var allowedDiscounts = new List<Discount>();
            foreach (var _discount in allDiscounts)
            {
                if (_discount.IsActive(customerCouponCode) &&
                    _discount.DiscountType == DiscountTypeEnum.AssignedToShipping &&
                    !allowedDiscounts.ContainsDiscount(_discount.Name))
                {
                    //discount requirements
                    if (_discount.CheckDiscountRequirements(customer)
                        && _discount.CheckDiscountLimitations(customer))
                    {
                        allowedDiscounts.Add(_discount);
                    }
                }
            }

            appliedDiscount = DiscountManager.GetPreferredDiscount(allowedDiscounts, shippingTotal);
            if (appliedDiscount != null)
            {
                shippingDiscountAmount = appliedDiscount.GetDiscountAmount(shippingTotal);
            }

            if (shippingDiscountAmount < decimal.Zero)
                shippingDiscountAmount = decimal.Zero;

            shippingDiscountAmount = Math.Round(shippingDiscountAmount, 2);

            return shippingDiscountAmount;
        }
Example #11
0
        /// <summary>
        /// Replaces a message template tokens
        /// </summary>
        /// <param name="customer">Customer instance</param>
        /// <param name="forumPost">Forum post</param>
        /// <param name="forumTopic">Forum topic</param>
        /// <param name="forum">Forum</param>
        /// <param name="template">Template</param>
        /// <returns>New template</returns>
        private string ReplaceMessageTemplateTokens(Customer customer,
            ForumPost forumPost, ForumTopic forumTopic, Forum forum, string template)
        {
            var tokens = new NameValueCollection();
            tokens.Add("Store.Name", IoC.Resolve<ISettingManager>().StoreName);
            tokens.Add("Store.URL", IoC.Resolve<ISettingManager>().StoreUrl);
            tokens.Add("Store.Email", this.DefaultEmailAccount.Email);

            tokens.Add("Customer.Email", HttpUtility.HtmlEncode(customer.Email));
            tokens.Add("Customer.Username", HttpUtility.HtmlEncode(customer.Username));
            tokens.Add("Customer.FullName", HttpUtility.HtmlEncode(customer.FullName));
            tokens.Add("Customer.VatNumber", HttpUtility.HtmlEncode(customer.VatNumber));
            tokens.Add("Customer.VatNumberStatus", HttpUtility.HtmlEncode(customer.VatNumberStatus.ToString()));

            if (forumPost != null)
            {
                tokens.Add("Forums.PostAuthor", HttpUtility.HtmlEncode(forumPost.User.FormatUserName()));
                tokens.Add("Forums.PostBody", forumPost.FormatPostText());
            }
            if (forumTopic != null)
            {
                tokens.Add("Forums.TopicURL", SEOHelper.GetForumTopicUrl(forumTopic));
                tokens.Add("Forums.TopicName", HttpUtility.HtmlEncode(forumTopic.Subject));
            }
            if (forum != null)
            {
                tokens.Add("Forums.ForumURL", SEOHelper.GetForumUrl(forum));
                tokens.Add("Forums.ForumName", HttpUtility.HtmlEncode(forum.Name));
            }
            foreach (string token in tokens.Keys)
            {
                template = Replace(template, String.Format(@"%{0}%", token), tokens[token]);
            }

            return template;
        }
Example #12
0
        /// <summary>
        /// Replaces a message template tokens
        /// </summary>
        /// <param name="customer">Customer instance</param>
        /// <param name="product">Product instance</param>
        /// <param name="template">Template</param>
        /// <param name="additinalKeys">Additinal keys</param>
        /// <returns>New template</returns>
        private string ReplaceMessageTemplateTokens(Customer customer, Product product,
            string template, NameValueCollection additinalKeys)
        {
            var tokens = new NameValueCollection();
            tokens.Add("Store.Name", IoC.Resolve<ISettingManager>().StoreName);
            tokens.Add("Store.URL", IoC.Resolve<ISettingManager>().StoreUrl);
            tokens.Add("Store.Email", this.DefaultEmailAccount.Email);

            tokens.Add("Customer.Email", HttpUtility.HtmlEncode(customer.Email));
            tokens.Add("Customer.Username", HttpUtility.HtmlEncode(customer.Username));
            tokens.Add("Customer.FullName", HttpUtility.HtmlEncode(customer.FullName));
            tokens.Add("Customer.VatNumber", HttpUtility.HtmlEncode(customer.VatNumber));
            tokens.Add("Customer.VatNumberStatus", HttpUtility.HtmlEncode(customer.VatNumberStatus.ToString()));

            tokens.Add("Product.Name", HttpUtility.HtmlEncode(product.Name));
            tokens.Add("Product.ShortDescription", product.ShortDescription);
            tokens.Add("Product.ProductURLForCustomer", SEOHelper.GetProductUrl(product));

            foreach (string token in tokens.Keys)
            {
                template = Replace(template, String.Format(@"%{0}%", token), tokens[token]);
            }

            if (additinalKeys != null)
            {
                foreach (string token in additinalKeys.Keys)
                {
                    template = Replace(template, String.Format(@"%{0}%", token), additinalKeys[token]);
                }
            }

            return template;
        }
Example #13
0
        /// <summary>
        /// Replaces a message template tokens
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <param name="cart">Shopping cart</param>
        /// <param name="template">Template</param>
        /// <param name="additinalKeys">Additinal keys</param>
        /// <returns>New template</returns>
        private string ReplaceMessageTemplateTokens(Customer customer,
            ShoppingCart cart, string template, NameValueCollection additinalKeys)
        {
            var tokens = new NameValueCollection();
            tokens.Add("Store.Name", IoC.Resolve<ISettingManager>().StoreName);
            tokens.Add("Store.URL", IoC.Resolve<ISettingManager>().StoreUrl);
            tokens.Add("Store.Email", this.DefaultEmailAccount.Email);

            tokens.Add("Customer.Email", HttpUtility.HtmlEncode(customer.Email));
            tokens.Add("Customer.Username", HttpUtility.HtmlEncode(customer.Username));
            tokens.Add("Customer.FullName", HttpUtility.HtmlEncode(customer.FullName));
            tokens.Add("Customer.VatNumber", HttpUtility.HtmlEncode(customer.VatNumber));
            tokens.Add("Customer.VatNumberStatus", HttpUtility.HtmlEncode(customer.VatNumberStatus.ToString()));

            tokens.Add("Wishlist.URLForCustomer", SEOHelper.GetWishlistUrl(customer.CustomerGuid));
            //UNDONE add a wishlist content token

            foreach (string token in tokens.Keys)
            {
                template = Replace(template, String.Format(@"%{0}%", token), tokens[token]);
            }

            if (additinalKeys != null)
            {
                foreach (string token in additinalKeys.Keys)
                {
                    template = Replace(template, String.Format(@"%{0}%", token), additinalKeys[token]);
                }
            }

            return template;
        }
Example #14
0
 /// <summary>
 /// Replaces a message template tokens
 /// </summary>
 /// <param name="customer">Customer instance</param>
 /// <param name="template">Template</param>
 /// <returns>New template</returns>
 private string ReplaceMessageTemplateTokens(Customer customer,
     string template)
 {
     return ReplaceMessageTemplateTokens(customer, template, null);
 }
Example #15
0
        /// <summary>
        /// Replaces a message template tokens
        /// </summary>
        /// <param name="customer">Customer instance</param>
        /// <param name="template">Template</param>
        /// <param name="additinalKeys">Additinal keys</param>
        /// <returns>New template</returns>
        private string ReplaceMessageTemplateTokens(Customer customer,
            string template, NameValueCollection additinalKeys)
        {
            var tokens = new NameValueCollection();
            tokens.Add("Store.Name", IoC.Resolve<ISettingManager>().StoreName);
            tokens.Add("Store.URL", IoC.Resolve<ISettingManager>().StoreUrl);
            tokens.Add("Store.Email", this.DefaultEmailAccount.Email);

            tokens.Add("Customer.Email", HttpUtility.HtmlEncode(customer.Email));
            tokens.Add("Customer.Username", HttpUtility.HtmlEncode(customer.Username));
            tokens.Add("Customer.FullName", HttpUtility.HtmlEncode(customer.FullName));
            tokens.Add("Customer.VatNumber", HttpUtility.HtmlEncode(customer.VatNumber));
            tokens.Add("Customer.VatNumberStatus", HttpUtility.HtmlEncode(customer.VatNumberStatus.ToString()));

            string passwordRecoveryUrl = string.Empty;
            passwordRecoveryUrl = string.Format("{0}passwordrecovery.aspx?prt={1}&email={2}", IoC.Resolve<ISettingManager>().StoreUrl, customer.PasswordRecoveryToken, customer.Email);
            tokens.Add("Customer.PasswordRecoveryURL", passwordRecoveryUrl);

            string accountActivationUrl = string.Empty;
            accountActivationUrl = string.Format("{0}accountactivation.aspx?act={1}&email={2}", IoC.Resolve<ISettingManager>().StoreUrl, customer.AccountActivationToken, customer.Email);
            tokens.Add("Customer.AccountActivationURL", accountActivationUrl);

            foreach (string token in tokens.Keys)
            {
                template = Replace(template, String.Format(@"%{0}%", token), tokens[token]);
            }

            if (additinalKeys != null)
            {
                foreach (string token in additinalKeys.Keys)
                {
                    template = Replace(template, String.Format(@"%{0}%", token), additinalKeys[token]);
                }
            }

            return template;
        }
Example #16
0
        /// <summary>
        /// Sends a "new VAT sumitted" notification to a store owner
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <param name="vatName">Received VAT name</param>
        /// <param name="vatAddress">Received VAT address</param>
        /// <param name="languageId">Message language identifier</param>
        /// <returns>Queued email identifier</returns>
        public int SendNewVATSubmittedStoreOwnerNotification(Customer customer, 
            string vatName, string vatAddress, int languageId)
        {
            if (customer == null)
                throw new ArgumentNullException("customer");

            string templateName = "NewVATSubmitted.StoreOwnerNotification";
            LocalizedMessageTemplate localizedMessageTemplate = this.GetLocalizedMessageTemplate(templateName, languageId);
            if (localizedMessageTemplate == null || !localizedMessageTemplate.IsActive)
                return 0;

            var emailAccount = localizedMessageTemplate.EmailAccount;
            var additinalKeys = new NameValueCollection();
            additinalKeys.Add("VatValidationResult.Name", vatName);
            additinalKeys.Add("VatValidationResult.Address", vatAddress);
            string subject = ReplaceMessageTemplateTokens(customer, localizedMessageTemplate.Subject, additinalKeys);
            string body = ReplaceMessageTemplateTokens(customer, localizedMessageTemplate.Body, additinalKeys);
            string bcc = localizedMessageTemplate.BccEmailAddresses;
            var from = new MailAddress(emailAccount.Email, emailAccount.DisplayName);
            var to = new MailAddress(emailAccount.Email, emailAccount.DisplayName);
            var queuedEmail = InsertQueuedEmail(5, from, to, string.Empty, bcc, subject, body,
                DateTime.UtcNow, 0, null, emailAccount.EmailAccountId);
            return queuedEmail.QueuedEmailId;
        }
Example #17
0
        /// <summary>
        /// Sends wishlist "email a friend" message
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <param name="cart">Shopping cart</param>
        /// <param name="languageId">Message language identifier</param>
        /// <param name="friendsEmail">Friend's email</param>
        /// <param name="personalMessage">Personal message</param>
        /// <returns>Queued email identifier</returns>
        public int SendWishlistEmailAFriendMessage(Customer customer, 
            ShoppingCart cart, int languageId,
            string friendsEmail, string personalMessage)
        {
            if (customer == null)
                throw new ArgumentNullException("customer");
            if (cart == null)
                throw new ArgumentNullException("cart");

            string templateName = "Wishlist.EmailAFriend";
            var localizedMessageTemplate = this.GetLocalizedMessageTemplate(templateName, languageId);
            if (localizedMessageTemplate == null || !localizedMessageTemplate.IsActive)
                return 0;

            var emailAccount = localizedMessageTemplate.EmailAccount;

            var additinalKeys = new NameValueCollection();
            additinalKeys.Add("EmailAFriend.PersonalMessage", personalMessage);
            string subject = ReplaceMessageTemplateTokens(customer, cart, localizedMessageTemplate.Subject, additinalKeys);
            string body = ReplaceMessageTemplateTokens(customer, cart, localizedMessageTemplate.Body, additinalKeys);
            string bcc = localizedMessageTemplate.BccEmailAddresses;
            var from = new MailAddress(emailAccount.Email, emailAccount.DisplayName);
            var to = new MailAddress(friendsEmail);
            var queuedEmail = InsertQueuedEmail(5, from, to, string.Empty, bcc, subject, body,
                DateTime.UtcNow, 0, null, emailAccount.EmailAccountId);
            return queuedEmail.QueuedEmailId;
        }
 /// <summary>
 /// Process recurring payment
 /// </summary>
 /// <param name="paymentInfo">Payment info required for an order processing</param>
 /// <param name="customer">Customer</param>
 /// <param name="orderGuid">Unique order identifier</param>
 /// <param name="processPaymentResult">Process payment result</param>
 public void ProcessRecurringPayment(PaymentInfo paymentInfo, Customer customer, Guid orderGuid, ref ProcessPaymentResult processPaymentResult)
 {
     throw new NopException("Recurring payments not supported");
 }
Example #19
0
        /// <summary>
        /// Get active gift cards
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <returns>Active gift cards</returns>
        public static List<GiftCard> GetActiveGiftCards(Customer customer)
        {
            var result = new List<GiftCard>();
            if (customer == null)
                return result;

            string[] couponCodes = GetCouponCodes(customer.GiftCardCouponCodes);
            foreach (var couponCode in couponCodes)
            {
                var _gcCollection = OrderManager.GetAllGiftCards(null, null,
                    null, null, null, null, null, true, couponCode);
                foreach (var _gc in _gcCollection)
                {
                    if (IsGiftCardValid(_gc))
                        result.Add(_gc);
                }
            }

            return result;
        }
Example #20
0
        /// <summary>
        /// Sends a welcome message to a customer
        /// </summary>
        /// <param name="customer">Customer instance</param>
        /// <param name="languageId">Message language identifier</param>
        /// <returns>Queued email identifier</returns>
        public int SendCustomerWelcomeMessage(Customer customer, int languageId)
        {
            if (customer == null)
                throw new ArgumentNullException("customer");

            string templateName = "Customer.WelcomeMessage";
            var localizedMessageTemplate = this.GetLocalizedMessageTemplate(templateName, languageId);
            if(localizedMessageTemplate == null || !localizedMessageTemplate.IsActive)
                return 0;

            var emailAccount = localizedMessageTemplate.EmailAccount;

            string subject = ReplaceMessageTemplateTokens(customer, localizedMessageTemplate.Subject);
            string body = ReplaceMessageTemplateTokens(customer, localizedMessageTemplate.Body);
            string bcc = localizedMessageTemplate.BccEmailAddresses;
            var from = new MailAddress(emailAccount.Email, emailAccount.DisplayName);
            var to = new MailAddress(customer.Email, customer.FullName);
            var queuedEmail = InsertQueuedEmail(5, from, to, string.Empty, bcc, subject, body,
                DateTime.UtcNow, 0, null, emailAccount.EmailAccountId);
            return queuedEmail.QueuedEmailId;
        }
Example #21
0
        /// <summary>
        /// Places an order
        /// </summary>
        /// <param name="paymentInfo">Payment info</param>
        /// <param name="customer">Customer</param>
        /// <param name="orderGuid">Order GUID to use</param>
        /// <param name="orderId">Order identifier</param>
        /// <returns>The error status, or String.Empty if no errors</returns>
        public string PlaceOrder(PaymentInfo paymentInfo, Customer customer, 
            Guid orderGuid, out int orderId)
        {
            orderId = 0;
            var processPaymentResult = new ProcessPaymentResult();

            var customerService = IoC.Resolve<ICustomerService>();
            var shoppingCartService = IoC.Resolve<IShoppingCartService>();
            var taxService = IoC.Resolve<ITaxService>();
            var currencyService = IoC.Resolve<ICurrencyService>();
            var shippingService= IoC.Resolve<IShippingService>();
            var paymentService = IoC.Resolve<IPaymentService>();
            var productService = IoC.Resolve<IProductService>();
            var discountService = IoC.Resolve<IDiscountService>();
            var localizationManager = IoC.Resolve<ILocalizationManager>();
            var messageService = IoC.Resolve<IMessageService>();
            var customerActivityService = IoC.Resolve<ICustomerActivityService>();
            var smsService = IoC.Resolve<ISMSService>();
            var logService = IoC.Resolve<ILogService>();

            try
            {
                if (customer == null)
                    throw new ArgumentNullException("customer");

                if (customer.IsGuest && !customerService.AnonymousCheckoutAllowed)
                    throw new NopException("Anonymous checkout is not allowed");

                // This is a check to customer email address which is important to be valid.
                if (!CommonHelper.IsValidEmail(customer.Email)) {
                    throw new NopException("Email is not valid");
                }

                if (paymentInfo == null)
                    throw new ArgumentNullException("paymentInfo");

                Order initialOrder = null;
                if (paymentInfo.IsRecurringPayment)
                {
                    initialOrder = GetOrderById(paymentInfo.InitialOrderId);
                    if (initialOrder == null)
                        throw new NopException("Initial order could not be loaded");
                }

                if (!paymentInfo.IsRecurringPayment)
                {
                    if (paymentInfo.BillingAddress == null)
                        throw new NopException("Billing address not provided");

                    // Billing address email is never asked in the first place, so system must not check its validity
                    //if (!CommonHelper.IsValidEmail(paymentInfo.BillingAddress.Email))
                    //{
                    //    throw new NopException("Email is not valid");
                    //}
                }

                if (paymentInfo.IsRecurringPayment)
                {
                    paymentInfo.PaymentMethodId = initialOrder.PaymentMethodId;
                }

                paymentInfo.CreditCardType = CommonHelper.EnsureNotNull(paymentInfo.CreditCardType);
                paymentInfo.CreditCardName = CommonHelper.EnsureNotNull(paymentInfo.CreditCardName);
                paymentInfo.CreditCardName = CommonHelper.EnsureMaximumLength(paymentInfo.CreditCardName, 100);
                paymentInfo.CreditCardName = paymentInfo.CreditCardName.Trim();
                paymentInfo.CreditCardNumber = CommonHelper.EnsureNotNull(paymentInfo.CreditCardNumber);
                paymentInfo.CreditCardNumber = paymentInfo.CreditCardNumber.Trim();
                paymentInfo.CreditCardCvv2 = CommonHelper.EnsureNotNull(paymentInfo.CreditCardCvv2);
                paymentInfo.CreditCardCvv2 = paymentInfo.CreditCardCvv2.Trim();
                paymentInfo.PaypalToken = CommonHelper.EnsureNotNull(paymentInfo.PaypalToken);
                paymentInfo.PaypalPayerId = CommonHelper.EnsureNotNull(paymentInfo.PaypalPayerId);
                paymentInfo.GoogleOrderNumber = CommonHelper.EnsureNotNull(paymentInfo.GoogleOrderNumber);
                paymentInfo.PurchaseOrderNumber = CommonHelper.EnsureNotNull(paymentInfo.PurchaseOrderNumber);

                ShoppingCart cart = null;
                if (!paymentInfo.IsRecurringPayment)
                {
                    cart = shoppingCartService.GetCustomerShoppingCart(customer.CustomerId, ShoppingCartTypeEnum.ShoppingCart);

                    //validate cart
                    var warnings = shoppingCartService.GetShoppingCartWarnings(cart, customer.CheckoutAttributes, true);
                    if (warnings.Count > 0)
                    {
                        StringBuilder warningsSb = new StringBuilder();
                        foreach (string warning in warnings)
                        {
                            warningsSb.Append(warning);
                            warningsSb.Append(";");
                        }
                        throw new NopException(warningsSb.ToString());
                    }

                    //validate individual cart items
                    foreach (var sci in cart)
                    {
                        var sciWarnings = shoppingCartService.GetShoppingCartItemWarnings(sci.ShoppingCartType,
                            sci.ProductVariantId, sci.AttributesXml,
                            sci.CustomerEnteredPrice, sci.Quantity);

                        if (sciWarnings.Count > 0)
                        {
                            var warningsSb = new StringBuilder();
                            foreach (string warning in sciWarnings)
                            {
                                warningsSb.Append(warning);
                                warningsSb.Append(";");
                            }
                            throw new NopException(warningsSb.ToString());
                        }
                    }
                }

                //tax type
                var customerTaxDisplayType = TaxDisplayTypeEnum.IncludingTax;
                if (!paymentInfo.IsRecurringPayment)
                {
                    if (taxService.AllowCustomersToSelectTaxDisplayType)
                        customerTaxDisplayType = customer.TaxDisplayType;
                    else
                        customerTaxDisplayType = taxService.TaxDisplayType;
                }
                else
                {
                    customerTaxDisplayType = initialOrder.CustomerTaxDisplayType;
                }

                //discount usage history
                var appliedDiscounts = new List<Discount>();

                //checkout attributes
                string checkoutAttributeDescription = string.Empty;
                string checkoutAttributesXml = string.Empty;
                if (!paymentInfo.IsRecurringPayment)
                {
                    checkoutAttributeDescription = CheckoutAttributeHelper.FormatAttributes(customer.CheckoutAttributes, customer, "<br />");
                    checkoutAttributesXml = customer.CheckoutAttributes;
                }
                else
                {
                    checkoutAttributeDescription = initialOrder.CheckoutAttributeDescription;
                    checkoutAttributesXml = initialOrder.CheckoutAttributesXml;
                }

                //sub total
                decimal orderSubTotalInclTax = decimal.Zero;
                decimal orderSubTotalExclTax = decimal.Zero;
                decimal orderSubtotalInclTaxInCustomerCurrency = decimal.Zero;
                decimal orderSubtotalExclTaxInCustomerCurrency = decimal.Zero;
                decimal orderSubTotalDiscountInclTax = decimal.Zero;
                decimal orderSubTotalDiscountExclTax = decimal.Zero;
                decimal orderSubTotalDiscountInclTaxInCustomerCurrency = decimal.Zero;
                decimal orderSubTotalDiscountExclTaxInCustomerCurrency = decimal.Zero;
                if (!paymentInfo.IsRecurringPayment)
                {
                    //sub total (incl tax)
                    decimal orderSubTotalDiscountAmount1 = decimal.Zero;
                    Discount orderSubTotalAppliedDiscount1 = null;
                    decimal subTotalWithoutDiscountBase1 = decimal.Zero;
                    decimal subTotalWithDiscountBase1 = decimal.Zero;
                    string subTotalError1 = shoppingCartService.GetShoppingCartSubTotal(cart, customer,
                        true, out orderSubTotalDiscountAmount1, out orderSubTotalAppliedDiscount1,
                        out subTotalWithoutDiscountBase1, out subTotalWithDiscountBase1);
                    orderSubTotalInclTax = subTotalWithoutDiscountBase1;
                    orderSubTotalDiscountInclTax =orderSubTotalDiscountAmount1;

                    //discount history
                    if (orderSubTotalAppliedDiscount1 != null && !appliedDiscounts.ContainsDiscount(orderSubTotalAppliedDiscount1.Name))
                        appliedDiscounts.Add(orderSubTotalAppliedDiscount1);

                    //sub total (excl tax)
                    decimal orderSubTotalDiscountAmount2 = decimal.Zero;
                    Discount orderSubTotalAppliedDiscount2 = null;
                    decimal subTotalWithoutDiscountBase2 = decimal.Zero;
                    decimal subTotalWithDiscountBase2 = decimal.Zero;
                    string subTotalError2 = shoppingCartService.GetShoppingCartSubTotal(cart, customer,
                        false, out orderSubTotalDiscountAmount2, out orderSubTotalAppliedDiscount2,
                        out subTotalWithoutDiscountBase2, out subTotalWithDiscountBase2);
                    orderSubTotalExclTax = subTotalWithoutDiscountBase2;
                    orderSubTotalDiscountExclTax = orderSubTotalDiscountAmount2;

                    if (!String.IsNullOrEmpty(subTotalError1) || !String.IsNullOrEmpty(subTotalError2))
                        throw new NopException("Sub total couldn't be calculated");

                    //in customer currency
                    orderSubtotalInclTaxInCustomerCurrency = currencyService.ConvertCurrency(orderSubTotalInclTax, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                    orderSubtotalExclTaxInCustomerCurrency = currencyService.ConvertCurrency(orderSubTotalExclTax, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                    orderSubTotalDiscountInclTaxInCustomerCurrency = currencyService.ConvertCurrency(orderSubTotalDiscountInclTax, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                    orderSubTotalDiscountExclTaxInCustomerCurrency = currencyService.ConvertCurrency(orderSubTotalDiscountExclTax, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                }
                else
                {
                    orderSubTotalInclTax = initialOrder.OrderSubtotalInclTax;
                    orderSubTotalExclTax = initialOrder.OrderSubtotalExclTax;

                    //in customer currency
                    orderSubtotalInclTaxInCustomerCurrency = initialOrder.OrderSubtotalInclTaxInCustomerCurrency;
                    orderSubtotalExclTaxInCustomerCurrency = initialOrder.OrderSubtotalExclTaxInCustomerCurrency;
                }

                //shipping info
                decimal orderWeight = decimal.Zero;
                bool shoppingCartRequiresShipping = false;
                if (!paymentInfo.IsRecurringPayment)
                {
                    orderWeight = shippingService.GetShoppingCartTotalWeight(cart, customer);
                    shoppingCartRequiresShipping = shippingService.ShoppingCartRequiresShipping(cart);
                    if (shoppingCartRequiresShipping)
                    {
                        if (paymentInfo.ShippingAddress == null)
                            throw new NopException("Shipping address is not provided");

                        // Billing address email is never asked in the first place, so system must not check its validity
                        //if (!CommonHelper.IsValidEmail(paymentInfo.ShippingAddress.Email))
                        //{
                        //    throw new NopException("Email is not valid");
                        //}
                    }
                }
                else
                {
                    orderWeight = initialOrder.OrderWeight;
                    if (initialOrder.ShippingStatus != ShippingStatusEnum.ShippingNotRequired)
                        shoppingCartRequiresShipping = true;
                }

                //shipping total
                decimal? orderShippingTotalInclTax = null;
                decimal? orderShippingTotalExclTax = null;
                decimal orderShippingInclTaxInCustomerCurrency = decimal.Zero;
                decimal orderShippingExclTaxInCustomerCurrency = decimal.Zero;
                if (!paymentInfo.IsRecurringPayment)
                {
                    decimal taxRate = decimal.Zero;
                    string shippingTotalError1 = string.Empty;
                    string shippingTotalError2 = string.Empty;
                    Discount shippingTotalDiscount = null;
                    orderShippingTotalInclTax = shippingService.GetShoppingCartShippingTotal(cart, customer, true, out taxRate, out shippingTotalDiscount, ref shippingTotalError1);
                    orderShippingTotalExclTax = shippingService.GetShoppingCartShippingTotal(cart, customer, false, ref shippingTotalError2);
                    if (!orderShippingTotalInclTax.HasValue || !orderShippingTotalExclTax.HasValue)
                        throw new NopException("Shipping total couldn't be calculated");
                    if (shippingTotalDiscount != null && !appliedDiscounts.ContainsDiscount(shippingTotalDiscount.Name))
                        appliedDiscounts.Add(shippingTotalDiscount);

                    //in customer currency
                    orderShippingInclTaxInCustomerCurrency = currencyService.ConvertCurrency(orderShippingTotalInclTax.Value, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                    orderShippingExclTaxInCustomerCurrency = currencyService.ConvertCurrency(orderShippingTotalExclTax.Value, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);

                }
                else
                {
                    orderShippingTotalInclTax = initialOrder.OrderShippingInclTax;
                    orderShippingTotalExclTax = initialOrder.OrderShippingExclTax;
                    orderShippingInclTaxInCustomerCurrency = initialOrder.OrderShippingInclTaxInCustomerCurrency;
                    orderShippingExclTaxInCustomerCurrency = initialOrder.OrderShippingExclTaxInCustomerCurrency;
                }

                //payment total
                decimal paymentAdditionalFeeInclTax = decimal.Zero;
                decimal paymentAdditionalFeeExclTax = decimal.Zero;
                decimal paymentAdditionalFeeInclTaxInCustomerCurrency = decimal.Zero;
                decimal paymentAdditionalFeeExclTaxInCustomerCurrency = decimal.Zero;
                if (!paymentInfo.IsRecurringPayment)
                {
                    string paymentAdditionalFeeError1 = string.Empty;
                    string paymentAdditionalFeeError2 = string.Empty;
                    decimal paymentAdditionalFee = paymentService.GetAdditionalHandlingFee(paymentInfo.PaymentMethodId);
                    paymentAdditionalFeeInclTax = taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, true, customer, ref paymentAdditionalFeeError1);
                    paymentAdditionalFeeExclTax = taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, false, customer, ref paymentAdditionalFeeError2);
                    if (!String.IsNullOrEmpty(paymentAdditionalFeeError1))
                        throw new NopException("Payment method fee couldn't be calculated");
                    if (!String.IsNullOrEmpty(paymentAdditionalFeeError2))
                        throw new NopException("Payment method fee couldn't be calculated");

                    //in customer currency
                    paymentAdditionalFeeInclTaxInCustomerCurrency = currencyService.ConvertCurrency(paymentAdditionalFeeInclTax, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                    paymentAdditionalFeeExclTaxInCustomerCurrency = currencyService.ConvertCurrency(paymentAdditionalFeeExclTax, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                }
                else
                {
                    paymentAdditionalFeeInclTax = initialOrder.PaymentMethodAdditionalFeeInclTax;
                    paymentAdditionalFeeExclTax = initialOrder.PaymentMethodAdditionalFeeExclTax;
                    paymentAdditionalFeeInclTaxInCustomerCurrency = initialOrder.PaymentMethodAdditionalFeeInclTaxInCustomerCurrency;
                    paymentAdditionalFeeExclTaxInCustomerCurrency = initialOrder.PaymentMethodAdditionalFeeExclTaxInCustomerCurrency;
                }

                //tax total
                decimal orderTaxTotal = decimal.Zero;
                decimal orderTaxInCustomerCurrency = decimal.Zero;
                string vatNumber = string.Empty;
                string taxRates = string.Empty;
                string taxRatesInCustomerCurrency = string.Empty;
                if (!paymentInfo.IsRecurringPayment)
                {
                    //tax amount
                    SortedDictionary<decimal, decimal> taxRatesDictionary = null;
                    string taxError = string.Empty;
                    orderTaxTotal = taxService.GetTaxTotal(cart,
                        paymentInfo.PaymentMethodId, customer, out taxRatesDictionary, ref taxError);
                    if (!String.IsNullOrEmpty(taxError))
                        throw new NopException("Tax total couldn't be calculated");

                    //in customer currency
                    orderTaxInCustomerCurrency = currencyService.ConvertCurrency(orderTaxTotal, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);

                    //VAT number
                    if (taxService.EUVatEnabled && customer.VatNumberStatus == VatNumberStatusEnum.Valid)
                    {
                        vatNumber = customer.VatNumber;
                    }

                    //tax rates
                    foreach (var kvp in taxRatesDictionary)
                    {
                        var taxRate = kvp.Key;
                        var taxValue = kvp.Value;

                        var taxValueInCustomerCurrency = currencyService.ConvertCurrency(taxValue, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);

                        taxRates += string.Format("{0}:{1};   ", taxRate.ToString(new CultureInfo("en-US")), taxValue.ToString(new CultureInfo("en-US")));
                        taxRatesInCustomerCurrency += string.Format("{0}:{1};   ", taxRate.ToString(new CultureInfo("en-US")), taxValueInCustomerCurrency.ToString(new CultureInfo("en-US")));
                    }
                }
                else
                {
                    orderTaxTotal = initialOrder.OrderTax;
                    orderTaxInCustomerCurrency = initialOrder.OrderTaxInCustomerCurrency;

                    //VAT number
                    //TODO: Possible BUG: VAT number status may have changed since original order was placed, probably best to recalculate tax or do some checks?
                    vatNumber = initialOrder.VatNumber;
                }

                //order total (and applied discounts, gift cards, reward points)
                decimal? orderTotal = null;
                decimal orderTotalInCustomerCurrency = decimal.Zero;
                decimal orderDiscountAmount = decimal.Zero;
                decimal orderDiscountInCustomerCurrency = decimal.Zero;
                List<AppliedGiftCard> appliedGiftCards = null;
                int redeemedRewardPoints = 0;
                decimal redeemedRewardPointsAmount = decimal.Zero;
                if (!paymentInfo.IsRecurringPayment)
                {
                    Discount orderAppliedDiscount = null;

                    bool useRewardPoints = customer.UseRewardPointsDuringCheckout;

                    orderTotal = shoppingCartService.GetShoppingCartTotal(cart,
                        paymentInfo.PaymentMethodId, customer,
                        out orderDiscountAmount, out orderAppliedDiscount,
                        out appliedGiftCards, useRewardPoints,
                        out redeemedRewardPoints, out redeemedRewardPointsAmount);
                    if (!orderTotal.HasValue)
                        throw new NopException("Order total couldn't be calculated");

                    //discount history
                    if (orderAppliedDiscount != null && !appliedDiscounts.ContainsDiscount(orderAppliedDiscount.Name))
                        appliedDiscounts.Add(orderAppliedDiscount);

                    //in customer currency
                    orderDiscountInCustomerCurrency = currencyService.ConvertCurrency(orderDiscountAmount, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                    orderTotalInCustomerCurrency = currencyService.ConvertCurrency(orderTotal.Value, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                }
                else
                {
                    orderDiscountAmount = initialOrder.OrderDiscount;
                    orderTotal = initialOrder.OrderTotal;

                    orderDiscountInCustomerCurrency = initialOrder.OrderDiscountInCustomerCurrency;
                    orderTotalInCustomerCurrency = initialOrder.OrderTotalInCustomerCurrency;
                }
                paymentInfo.OrderTotal = orderTotal.Value;

                //skip payment workflow if order total equals zero
                bool skipPaymentWorkflow = false;
                if (orderTotal.Value == decimal.Zero)
                {
                    skipPaymentWorkflow = true;
                }
                PaymentMethod paymentMethod = null;
                string paymentMethodName = string.Empty;
                if (!skipPaymentWorkflow)
                {
                    paymentMethod = paymentService.GetPaymentMethodById(paymentInfo.PaymentMethodId);
                    if (paymentMethod == null)
                        throw new NopException("Payment method couldn't be loaded");

                    if (!paymentMethod.IsActive)
                        throw new NopException("Payment method is not active");

                    paymentMethodName = paymentMethod.Name;
                }
                else
                {
                    paymentInfo.PaymentMethodId = 0;
                }

                string customerCurrencyCode = string.Empty;
                if (!paymentInfo.IsRecurringPayment)
                {
                    customerCurrencyCode = paymentInfo.CustomerCurrency.CurrencyCode;
                }
                else
                {
                    customerCurrencyCode = initialOrder.CustomerCurrencyCode;
                }

                //billing info
                string billingFirstName = string.Empty;
                string billingLastName = string.Empty;
                string billingPhoneNumber = string.Empty;
                string billingEmail = string.Empty;
                string billingFaxNumber = string.Empty;
                string billingCompany = string.Empty;
                string billingAddress1 = string.Empty;
                string billingAddress2 = string.Empty;
                string billingCity = string.Empty;
                string billingStateProvince = string.Empty;
                int billingStateProvinceId = 0;
                string billingZipPostalCode = string.Empty;
                string billingCountry = string.Empty;
                int billingCountryId = 0;
                if (!paymentInfo.IsRecurringPayment)
                {
                    var billingAddress = paymentInfo.BillingAddress;
                    billingFirstName = billingAddress.FirstName;
                    billingLastName = billingAddress.LastName;
                    billingPhoneNumber = billingAddress.PhoneNumber;
                    billingEmail = billingAddress.Email;
                    billingFaxNumber = billingAddress.FaxNumber;
                    billingCompany = billingAddress.Company;
                    billingAddress1 = billingAddress.Address1;
                    billingAddress2 = billingAddress.Address2;
                    billingCity = billingAddress.City;
                    if (billingAddress.StateProvince != null)
                    {
                        billingStateProvince = billingAddress.StateProvince.Name;
                        billingStateProvinceId = billingAddress.StateProvince.StateProvinceId;
                    }
                    billingZipPostalCode = billingAddress.ZipPostalCode;
                    if (billingAddress.Country != null)
                    {
                        billingCountry = billingAddress.Country.Name;
                        billingCountryId = billingAddress.Country.CountryId;

                        if (!billingAddress.Country.AllowsBilling)
                        {
                            throw new NopException(string.Format("{0} is not allowed for billing", billingCountry));
                        }
                    }
                }
                else
                {
                    billingFirstName = initialOrder.BillingFirstName;
                    billingLastName = initialOrder.BillingLastName;
                    billingPhoneNumber = initialOrder.BillingPhoneNumber;
                    billingEmail = initialOrder.BillingEmail;
                    billingFaxNumber = initialOrder.BillingFaxNumber;
                    billingCompany = initialOrder.BillingCompany;
                    billingAddress1 = initialOrder.BillingAddress1;
                    billingAddress2 = initialOrder.BillingAddress2;
                    billingCity = initialOrder.BillingCity;
                    billingStateProvince = initialOrder.BillingStateProvince;
                    billingStateProvinceId = initialOrder.BillingStateProvinceId;
                    billingZipPostalCode = initialOrder.BillingZipPostalCode;
                    billingCountry = initialOrder.BillingCountry;
                    billingCountryId = initialOrder.BillingCountryId;
                }

                //shipping info
                string shippingFirstName = string.Empty;
                string shippingLastName = string.Empty;
                string shippingPhoneNumber = string.Empty;
                string shippingEmail = string.Empty;
                string shippingFaxNumber = string.Empty;
                string shippingCompany = string.Empty;
                string shippingAddress1 = string.Empty;
                string shippingAddress2 = string.Empty;
                string shippingCity = string.Empty;
                string shippingStateProvince = string.Empty;
                int shippingStateProvinceId = 0;
                string shippingZipPostalCode = string.Empty;
                string shippingCountry = string.Empty;
                int shippingCountryId = 0;
                string shippingMethodName = string.Empty;
                int shippingRateComputationMethodId = 0;
                if (shoppingCartRequiresShipping)
                {
                    if (!paymentInfo.IsRecurringPayment)
                    {
                        var shippingAddress = paymentInfo.ShippingAddress;
                        if (shippingAddress != null)
                        {
                            shippingFirstName = shippingAddress.FirstName;
                            shippingLastName = shippingAddress.LastName;
                            shippingPhoneNumber = shippingAddress.PhoneNumber;
                            shippingEmail = shippingAddress.Email;
                            shippingFaxNumber = shippingAddress.FaxNumber;
                            shippingCompany = shippingAddress.Company;
                            shippingAddress1 = shippingAddress.Address1;
                            shippingAddress2 = shippingAddress.Address2;
                            shippingCity = shippingAddress.City;
                            if (shippingAddress.StateProvince != null)
                            {
                                shippingStateProvince = shippingAddress.StateProvince.Name;
                                shippingStateProvinceId = shippingAddress.StateProvince.StateProvinceId;
                            }
                            shippingZipPostalCode = shippingAddress.ZipPostalCode;
                            if (shippingAddress.Country != null)
                            {
                                shippingCountry = shippingAddress.Country.Name;
                                shippingCountryId = shippingAddress.Country.CountryId;

                                if (!shippingAddress.Country.AllowsShipping)
                                {
                                    throw new NopException(string.Format("{0} is not allowed for shipping", shippingCountry));
                                }
                            }
                            shippingMethodName = string.Empty;
                            var shippingOption = customer.LastShippingOption;
                            if (shippingOption != null)
                            {
                                shippingMethodName = shippingOption.Name;
                                shippingRateComputationMethodId = shippingOption.ShippingRateComputationMethodId;
                            }
                        }
                    }
                    else
                    {
                        shippingFirstName = initialOrder.ShippingFirstName;
                        shippingLastName = initialOrder.ShippingLastName;
                        shippingPhoneNumber = initialOrder.ShippingPhoneNumber;
                        shippingEmail = initialOrder.ShippingEmail;
                        shippingFaxNumber = initialOrder.ShippingFaxNumber;
                        shippingCompany = initialOrder.ShippingCompany;
                        shippingAddress1 = initialOrder.ShippingAddress1;
                        shippingAddress2 = initialOrder.ShippingAddress2;
                        shippingCity = initialOrder.ShippingCity;
                        shippingStateProvince = initialOrder.ShippingStateProvince;
                        shippingStateProvinceId = initialOrder.ShippingStateProvinceId;
                        shippingZipPostalCode = initialOrder.ShippingZipPostalCode;
                        shippingCountry = initialOrder.ShippingCountry;
                        shippingCountryId = initialOrder.ShippingCountryId;
                        shippingMethodName = initialOrder.ShippingMethod;
                        shippingRateComputationMethodId = initialOrder.ShippingRateComputationMethodId;
                    }
                }

                //customer language
                int customerLanguageId = 0;
                if (!paymentInfo.IsRecurringPayment)
                {
                    customerLanguageId = paymentInfo.CustomerLanguage.LanguageId;
                }
                else
                {
                    customerLanguageId = initialOrder.CustomerLanguageId;
                }

                //recurring or standard shopping cart
                bool isRecurringShoppingCart = false;
                if (!paymentInfo.IsRecurringPayment)
                {
                    isRecurringShoppingCart = cart.IsRecurring;
                    if (isRecurringShoppingCart)
                    {
                        int recurringCycleLength = 0;
                        int recurringCyclePeriod = 0;
                        int recurringTotalCycles = 0;
                        string recurringCyclesError = shoppingCartService.GetReccuringCycleInfo(cart, out recurringCycleLength, out recurringCyclePeriod, out recurringTotalCycles);
                        if (!string.IsNullOrEmpty(recurringCyclesError))
                        {
                            throw new NopException(recurringCyclesError);
                        }
                        paymentInfo.RecurringCycleLength = recurringCycleLength;
                        paymentInfo.RecurringCyclePeriod = recurringCyclePeriod;
                        paymentInfo.RecurringTotalCycles = recurringTotalCycles;
                    }
                }
                else
                {
                    isRecurringShoppingCart = true;
                }

                if (!skipPaymentWorkflow)
                {
                    //process payment
                    if (!paymentInfo.IsRecurringPayment)
                    {
                        if (isRecurringShoppingCart)
                        {
                            //recurring cart
                            var recurringPaymentType = paymentService.SupportRecurringPayments(paymentInfo.PaymentMethodId);
                            switch (recurringPaymentType)
                            {
                                case RecurringPaymentTypeEnum.NotSupported:
                                    throw new NopException("Recurring payments are not supported by selected payment method");
                                case RecurringPaymentTypeEnum.Manual:
                                case RecurringPaymentTypeEnum.Automatic:
                                    paymentService.ProcessRecurringPayment(paymentInfo, customer, orderGuid, ref processPaymentResult);
                                    break;
                                default:
                                    throw new NopException("Not supported recurring payment type");
                            }
                        }
                        else
                        {
                            //standard cart
                            paymentService.ProcessPayment(paymentInfo, customer, orderGuid, ref processPaymentResult);
                        }
                    }
                    else
                    {
                        if (isRecurringShoppingCart)
                        {
                            var recurringPaymentType = paymentService.SupportRecurringPayments(paymentInfo.PaymentMethodId);
                            switch (recurringPaymentType)
                            {
                                case RecurringPaymentTypeEnum.NotSupported:
                                    throw new NopException("Recurring payments are not supported by selected payment method");
                                case RecurringPaymentTypeEnum.Manual:
                                    paymentService.ProcessRecurringPayment(paymentInfo, customer, orderGuid, ref processPaymentResult);
                                    break;
                                case RecurringPaymentTypeEnum.Automatic:
                                    //payment is processed on payment gateway site
                                    break;
                                default:
                                    throw new NopException("Not supported recurring payment type");
                            }
                        }
                        else
                        {
                            throw new NopException("No recurring products");
                        }
                    }
                }
                else
                {
                    processPaymentResult.PaymentStatus = PaymentStatusEnum.Paid;
                }

                //process order
                if (String.IsNullOrEmpty(processPaymentResult.Error))
                {
                    var shippingStatusEnum = ShippingStatusEnum.NotYetShipped;
                    if (!shoppingCartRequiresShipping)
                        shippingStatusEnum = ShippingStatusEnum.ShippingNotRequired;

                    //save order in data storage
                    //uncomment this line to support transactions
                    //using (var scope = new System.Transactions.TransactionScope())
                    {
                        var order = new Order()
                        {
                            OrderGuid = orderGuid,
                            CustomerId = customer.CustomerId,
                            CustomerLanguageId = customerLanguageId,
                            CustomerTaxDisplayTypeId = (int)customerTaxDisplayType,
                            CustomerIP = NopContext.Current.UserHostAddress,
                            OrderSubtotalInclTax = orderSubTotalInclTax,
                            OrderSubtotalExclTax = orderSubTotalExclTax,
                            OrderSubTotalDiscountInclTax = orderSubTotalDiscountInclTax,
                            OrderSubTotalDiscountExclTax = orderSubTotalDiscountExclTax,
                            OrderShippingInclTax = orderShippingTotalInclTax.Value,
                            OrderShippingExclTax = orderShippingTotalExclTax.Value,
                            PaymentMethodAdditionalFeeInclTax = paymentAdditionalFeeInclTax,
                            PaymentMethodAdditionalFeeExclTax = paymentAdditionalFeeExclTax,
                            TaxRates = taxRates,
                            OrderTax = orderTaxTotal,
                            OrderTotal = orderTotal.Value,
                            RefundedAmount = decimal.Zero,
                            OrderDiscount = orderDiscountAmount,
                            OrderSubtotalInclTaxInCustomerCurrency = orderSubtotalInclTaxInCustomerCurrency,
                            OrderSubtotalExclTaxInCustomerCurrency = orderSubtotalExclTaxInCustomerCurrency,
                            OrderSubTotalDiscountInclTaxInCustomerCurrency = orderSubTotalDiscountInclTaxInCustomerCurrency,
                            OrderSubTotalDiscountExclTaxInCustomerCurrency = orderSubTotalDiscountExclTaxInCustomerCurrency,
                            OrderShippingInclTaxInCustomerCurrency = orderShippingInclTaxInCustomerCurrency,
                            OrderShippingExclTaxInCustomerCurrency = orderShippingExclTaxInCustomerCurrency,
                            PaymentMethodAdditionalFeeInclTaxInCustomerCurrency = paymentAdditionalFeeInclTaxInCustomerCurrency,
                            PaymentMethodAdditionalFeeExclTaxInCustomerCurrency = paymentAdditionalFeeExclTaxInCustomerCurrency,
                            TaxRatesInCustomerCurrency = taxRatesInCustomerCurrency,
                            OrderTaxInCustomerCurrency = orderTaxInCustomerCurrency,
                            OrderTotalInCustomerCurrency = orderTotalInCustomerCurrency,
                            OrderDiscountInCustomerCurrency = orderDiscountInCustomerCurrency,
                            CheckoutAttributeDescription = checkoutAttributeDescription,
                            CheckoutAttributesXml = checkoutAttributesXml,
                            CustomerCurrencyCode = customerCurrencyCode,
                            OrderWeight = orderWeight,
                            AffiliateId = customer.AffiliateId,
                            OrderStatusId = (int)OrderStatusEnum.Pending,
                            AllowStoringCreditCardNumber = processPaymentResult.AllowStoringCreditCardNumber,
                            CardType = processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Encrypt(paymentInfo.CreditCardType) : string.Empty,
                            CardName = processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Encrypt(paymentInfo.CreditCardName) : string.Empty,
                            CardNumber = processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Encrypt(paymentInfo.CreditCardNumber) : string.Empty,
                            MaskedCreditCardNumber = SecurityHelper.Encrypt(paymentService.GetMaskedCreditCardNumber(paymentInfo.CreditCardNumber)),
                            CardCvv2 = processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Encrypt(paymentInfo.CreditCardCvv2) : string.Empty,
                            CardExpirationMonth = processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Encrypt(paymentInfo.CreditCardExpireMonth.ToString()) : string.Empty,
                            CardExpirationYear = processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Encrypt(paymentInfo.CreditCardExpireYear.ToString()) : string.Empty,
                            PaymentMethodId = paymentInfo.PaymentMethodId,
                            PaymentMethodName = paymentMethodName,
                            AuthorizationTransactionId = processPaymentResult.AuthorizationTransactionId,
                            AuthorizationTransactionCode = processPaymentResult.AuthorizationTransactionCode,
                            AuthorizationTransactionResult = processPaymentResult.AuthorizationTransactionResult,
                            CaptureTransactionId = processPaymentResult.CaptureTransactionId,
                            CaptureTransactionResult = processPaymentResult.CaptureTransactionResult,
                            SubscriptionTransactionId = processPaymentResult.SubscriptionTransactionId,
                            PurchaseOrderNumber = paymentInfo.PurchaseOrderNumber,
                            PaymentStatusId = (int)processPaymentResult.PaymentStatus,
                            PaidDate = null,
                            BillingFirstName = billingFirstName,
                            BillingLastName = billingLastName,
                            BillingPhoneNumber = billingPhoneNumber,
                            BillingEmail = billingEmail,
                            BillingFaxNumber = billingFaxNumber,
                            BillingCompany = billingCompany,
                            BillingAddress1 = billingAddress1,
                            BillingAddress2 = billingAddress2,
                            BillingCity = billingCity,
                            BillingStateProvince = billingStateProvince,
                            BillingStateProvinceId = billingStateProvinceId,
                            BillingZipPostalCode = billingZipPostalCode,
                            BillingCountry = billingCountry,
                            BillingCountryId = billingCountryId,
                            ShippingStatusId = (int)shippingStatusEnum,
                            ShippingFirstName = shippingFirstName,
                            ShippingLastName = shippingLastName,
                            ShippingPhoneNumber = shippingPhoneNumber,
                            ShippingEmail = shippingEmail,
                            ShippingFaxNumber = shippingFaxNumber,
                            ShippingCompany = shippingCompany,
                            ShippingAddress1 = shippingAddress1,
                            ShippingAddress2 = shippingAddress2,
                            ShippingCity = shippingCity,
                            ShippingStateProvince = shippingStateProvince,
                            ShippingStateProvinceId = shippingStateProvinceId,
                            ShippingZipPostalCode = shippingZipPostalCode,
                            ShippingCountry = shippingCountry,
                            ShippingCountryId = shippingCountryId,
                            ShippingMethod = shippingMethodName,
                            ShippingRateComputationMethodId = shippingRateComputationMethodId,
                            ShippedDate = null,
                            DeliveryDate = null,
                            TrackingNumber = string.Empty,
                            VatNumber = vatNumber,
                            Deleted = false,
                            CreatedOn = DateTime.UtcNow
                        };
                        InsertOrder(order);

                        orderId = order.OrderId;

                        if (!paymentInfo.IsRecurringPayment)
                        {
                            //move shopping cart items to order product variants
                            foreach (var sc in cart)
                            {
                                //prices
                                decimal taxRate = decimal.Zero;
                                decimal scUnitPrice = PriceHelper.GetUnitPrice(sc, customer, true);
                                decimal scSubTotal = PriceHelper.GetSubTotal(sc, customer, true);
                                decimal scUnitPriceInclTax = taxService.GetPrice(sc.ProductVariant, scUnitPrice, true, customer, out taxRate);
                                decimal scUnitPriceExclTax = taxService.GetPrice(sc.ProductVariant, scUnitPrice, false, customer, out taxRate);
                                decimal scSubTotalInclTax = taxService.GetPrice(sc.ProductVariant, scSubTotal, true, customer, out taxRate);
                                decimal scSubTotalExclTax = taxService.GetPrice(sc.ProductVariant, scSubTotal, false, customer, out taxRate);
                                decimal scUnitPriceInclTaxInCustomerCurrency = currencyService.ConvertCurrency(scUnitPriceInclTax, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                                decimal scUnitPriceExclTaxInCustomerCurrency = currencyService.ConvertCurrency(scUnitPriceExclTax, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                                decimal scSubTotalInclTaxInCustomerCurrency = currencyService.ConvertCurrency(scSubTotalInclTax, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                                decimal scSubTotalExclTaxInCustomerCurrency = currencyService.ConvertCurrency(scSubTotalExclTax, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);

                                //discounts
                                Discount scDiscount = null;
                                decimal discountAmount = PriceHelper.GetDiscountAmount(sc, customer, out scDiscount);
                                decimal discountAmountInclTax = taxService.GetPrice(sc.ProductVariant, discountAmount, true, customer, out taxRate);
                                decimal discountAmountExclTax = taxService.GetPrice(sc.ProductVariant, discountAmount, false, customer, out taxRate);
                                if (scDiscount != null && !appliedDiscounts.ContainsDiscount(scDiscount.Name))
                                    appliedDiscounts.Add(scDiscount);

                                //attributes
                                string attributeDescription = ProductAttributeHelper.FormatAttributes(sc.ProductVariant, sc.AttributesXml, customer, "<br />");

                                //save item
                                var opv = new OrderProductVariant()
                                {
                                    OrderProductVariantGuid = Guid.NewGuid(),
                                    OrderId = order.OrderId,
                                    ProductVariantId = sc.ProductVariantId,
                                    UnitPriceInclTax = scUnitPriceInclTax,
                                    UnitPriceExclTax = scUnitPriceExclTax,
                                    PriceInclTax = scSubTotalInclTax,
                                    PriceExclTax = scSubTotalExclTax,
                                    UnitPriceInclTaxInCustomerCurrency = scUnitPriceInclTaxInCustomerCurrency,
                                    UnitPriceExclTaxInCustomerCurrency = scUnitPriceExclTaxInCustomerCurrency,
                                    PriceInclTaxInCustomerCurrency = scSubTotalInclTaxInCustomerCurrency,
                                    PriceExclTaxInCustomerCurrency = scSubTotalExclTaxInCustomerCurrency,
                                    AttributeDescription = attributeDescription,
                                    AttributesXml = sc.AttributesXml,
                                    Quantity = sc.Quantity,
                                    DiscountAmountInclTax = discountAmountInclTax,
                                    DiscountAmountExclTax = discountAmountExclTax,
                                    DownloadCount = 0,
                                    IsDownloadActivated = false,
                                    LicenseDownloadId = 0
                                };
                                InsertOrderProductVariant(opv);

                                //gift cards
                                if (sc.ProductVariant.IsGiftCard)
                                {
                                    string giftCardRecipientName = string.Empty;
                                    string giftCardRecipientEmail = string.Empty;
                                    string giftCardSenderName = string.Empty;
                                    string giftCardSenderEmail = string.Empty;
                                    string giftCardMessage = string.Empty;
                                    ProductAttributeHelper.GetGiftCardAttribute(sc.AttributesXml,
                                        out giftCardRecipientName, out giftCardRecipientEmail,
                                        out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage);

                                    for (int i = 0; i < sc.Quantity; i++)
                                    {
                                        var gc = new GiftCard()
                                        {
                                            PurchasedOrderProductVariantId = opv.OrderProductVariantId,
                                            Amount = scUnitPriceExclTax,
                                            IsGiftCardActivated = false,
                                            GiftCardCouponCode = GiftCardHelper.GenerateGiftCardCode(),
                                            RecipientName = giftCardRecipientName,
                                            RecipientEmail = giftCardRecipientEmail,
                                            SenderName = giftCardSenderName,
                                            SenderEmail = giftCardSenderEmail,
                                            Message = giftCardMessage,
                                            IsRecipientNotified = false,
                                            CreatedOn = DateTime.UtcNow
                                        };
                                        InsertGiftCard(gc);
                                    }
                                }

                                //inventory
                                productService.AdjustInventory(sc.ProductVariantId, true, sc.Quantity, sc.AttributesXml);
                            }

                            //clear shopping cart
                            foreach (var sc in cart)
                            {
                                shoppingCartService.DeleteShoppingCartItem(sc.ShoppingCartItemId, false);
                            }
                        }
                        else
                        {
                            var initialOrderProductVariants = initialOrder.OrderProductVariants;
                            foreach (var opv in initialOrderProductVariants)
                            {
                                //save item
                                var newOpv = new OrderProductVariant()
                                {
                                    OrderProductVariantGuid = Guid.NewGuid(),
                                    OrderId = order.OrderId,
                                    ProductVariantId = opv.ProductVariantId,
                                    UnitPriceInclTax = opv.UnitPriceInclTax,
                                    UnitPriceExclTax = opv.UnitPriceExclTax,
                                    PriceInclTax = opv.PriceInclTax,
                                    PriceExclTax = opv.PriceExclTax,
                                    UnitPriceInclTaxInCustomerCurrency = opv.UnitPriceInclTaxInCustomerCurrency,
                                    UnitPriceExclTaxInCustomerCurrency = opv.UnitPriceExclTaxInCustomerCurrency,
                                    PriceInclTaxInCustomerCurrency =  opv.PriceInclTaxInCustomerCurrency,
                                    PriceExclTaxInCustomerCurrency = opv.PriceExclTaxInCustomerCurrency,
                                    AttributeDescription = opv.AttributeDescription,
                                    AttributesXml = opv.AttributesXml,
                                    Quantity = opv.Quantity,
                                    DiscountAmountInclTax = opv.DiscountAmountInclTax,
                                    DiscountAmountExclTax =  opv.DiscountAmountExclTax,
                                    DownloadCount = 0,
                                    IsDownloadActivated = false,
                                    LicenseDownloadId = 0
                                };

                                InsertOrderProductVariant(newOpv);

                                //gift cards
                                if (opv.ProductVariant.IsGiftCard)
                                {
                                    string giftCardRecipientName = string.Empty;
                                    string giftCardRecipientEmail = string.Empty;
                                    string giftCardSenderName = string.Empty;
                                    string giftCardSenderEmail = string.Empty;
                                    string giftCardMessage = string.Empty;
                                    ProductAttributeHelper.GetGiftCardAttribute(opv.AttributesXml,
                                        out giftCardRecipientName, out giftCardRecipientEmail,
                                        out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage);

                                    for (int i = 0; i < opv.Quantity; i++)
                                    {
                                        var gc = new GiftCard()
                                        {
                                            PurchasedOrderProductVariantId = newOpv.OrderProductVariantId,
                                            Amount = opv.UnitPriceExclTax,
                                            IsGiftCardActivated = false,
                                            GiftCardCouponCode = GiftCardHelper.GenerateGiftCardCode(),
                                            RecipientName = giftCardRecipientName,
                                            RecipientEmail = giftCardRecipientEmail,
                                            SenderName = giftCardSenderName,
                                            SenderEmail = giftCardSenderEmail,
                                            Message = giftCardMessage,
                                            IsRecipientNotified = false,
                                            CreatedOn = DateTime.UtcNow
                                        };
                                        InsertGiftCard(gc);
                                    }
                                }

                                //inventory
                                productService.AdjustInventory(opv.ProductVariantId, true, opv.Quantity, opv.AttributesXml);
                            }
                        }

                        //discount usage history
                        if (!paymentInfo.IsRecurringPayment)
                        {
                            foreach (var discount in appliedDiscounts)
                            {
                                var duh = new DiscountUsageHistory()
                                {
                                    DiscountId = discount.DiscountId,
                                    CustomerId = customer.CustomerId,
                                    OrderId = order.OrderId,
                                    CreatedOn = DateTime.UtcNow
                                };
                                discountService.InsertDiscountUsageHistory(duh);
                            }
                        }

                        //gift card usage history
                        if (!paymentInfo.IsRecurringPayment)
                        {
                            if (appliedGiftCards != null)
                            {
                                foreach (var agc in appliedGiftCards)
                                {
                                    decimal amountUsed = agc.AmountCanBeUsed;
                                    decimal amountUsedInCustomerCurrency = currencyService.ConvertCurrency(amountUsed, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                                    var gcuh = new GiftCardUsageHistory()
                                    {
                                        GiftCardId = agc.GiftCardId,
                                        CustomerId = customer.CustomerId,
                                        OrderId = order.OrderId,
                                        UsedValue = amountUsed,
                                        UsedValueInCustomerCurrency = amountUsedInCustomerCurrency,
                                        CreatedOn = DateTime.UtcNow
                                    };
                                    InsertGiftCardUsageHistory(gcuh);
                                }
                            }
                        }

                        //reward points history
                        if (redeemedRewardPointsAmount > decimal.Zero)
                        {
                            decimal redeemedRewardPointsAmountInCustomerCurrency = currencyService.ConvertCurrency(redeemedRewardPointsAmount, currencyService.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
                            string message = string.Format(localizationManager.GetLocaleResourceString("RewardPoints.Message.RedeemedForOrder", order.CustomerLanguageId), order.OrderId);

                            RewardPointsHistory rph = this.InsertRewardPointsHistory(customer.CustomerId,
                                order.OrderId, -redeemedRewardPoints,
                                redeemedRewardPointsAmount,
                                redeemedRewardPointsAmountInCustomerCurrency,
                                customerCurrencyCode,
                                message,
                                DateTime.UtcNow);
                        }

                        //recurring orders
                        if (!paymentInfo.IsRecurringPayment)
                        {
                            if (isRecurringShoppingCart)
                            {
                                //create recurring payment
                                var rp = new RecurringPayment()
                                {
                                    InitialOrderId = order.OrderId,
                                    CycleLength = paymentInfo.RecurringCycleLength,
                                    CyclePeriod = paymentInfo.RecurringCyclePeriod,
                                    TotalCycles = paymentInfo.RecurringTotalCycles,
                                    StartDate = DateTime.UtcNow,
                                    IsActive = true,
                                    Deleted = false,
                                    CreatedOn = DateTime.UtcNow
                                };
                                InsertRecurringPayment(rp);

                                var recurringPaymentType = paymentService.SupportRecurringPayments(paymentInfo.PaymentMethodId);
                                switch (recurringPaymentType)
                                {
                                    case RecurringPaymentTypeEnum.NotSupported:
                                        {
                                            //not supported
                                        }
                                        break;
                                    case RecurringPaymentTypeEnum.Manual:
                                        {
                                            //first payment
                                            var rph = new RecurringPaymentHistory()
                                            {
                                                RecurringPaymentId = rp.RecurringPaymentId,
                                                OrderId = order.OrderId,
                                                CreatedOn = DateTime.UtcNow
                                            };
                                            InsertRecurringPaymentHistory(rph);
                                        }
                                        break;
                                    case RecurringPaymentTypeEnum.Automatic:
                                        {
                                            //will be created later (process is automated)
                                        }
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }

                        //notes, messages
                        InsertOrderNote(order.OrderId, string.Format("Order placed"), false, DateTime.UtcNow);

                        int orderPlacedStoreOwnerNotificationQueuedEmailId = messageService.SendOrderPlacedStoreOwnerNotification(order, localizationManager.DefaultAdminLanguage.LanguageId);
                        if (orderPlacedStoreOwnerNotificationQueuedEmailId > 0)
                        {
                            InsertOrderNote(order.OrderId, string.Format("\"Order placed\" email (to store owner) has been queued. Queued email identifier: {0}.", orderPlacedStoreOwnerNotificationQueuedEmailId), false, DateTime.UtcNow);
                        }

                        int orderPlacedCustomerNotificationQueuedEmailId = messageService.SendOrderPlacedCustomerNotification(order, order.CustomerLanguageId);
                        if (orderPlacedCustomerNotificationQueuedEmailId > 0)
                        {
                            InsertOrderNote(order.OrderId, string.Format("\"Order placed\" email (to customer) has been queued. Queued email identifier: {0}.", orderPlacedCustomerNotificationQueuedEmailId), false, DateTime.UtcNow);
                        }

                        smsService.SendOrderPlacedNotification(order);

                        //order status
                        order = CheckOrderStatus(order.OrderId);

                        //reset checkout data
                        if (!paymentInfo.IsRecurringPayment)
                        {
                            customerService.ResetCheckoutData(customer.CustomerId, true);
                        }

                        //log
                        if (!paymentInfo.IsRecurringPayment)
                        {
                            customerActivityService.InsertActivity(
                                "PlaceOrder",
                                localizationManager.GetLocaleResourceString("ActivityLog.PlaceOrder"),
                                order.OrderId);
                        }

                        //uncomment this line to support transactions
                        //scope.Complete();

                        //raise event
                        EventContext.Current.OnOrderPlaced(null,
                            new OrderEventArgs() { Order = order });

                        //raise event
                        if (order.PaymentStatus == PaymentStatusEnum.Paid)
                        {
                            EventContext.Current.OnOrderPaid(null,
                                new OrderEventArgs() { Order = order });
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                processPaymentResult.Error = exc.Message;
                processPaymentResult.FullError = exc.ToString();
            }

            if (!String.IsNullOrEmpty(processPaymentResult.Error))
            {
                logService.InsertLog(LogTypeEnum.OrderError, string.Format("Error while placing order. {0}", processPaymentResult.Error), processPaymentResult.FullError);
            }
            return processPaymentResult.Error;
        }
 /// <summary>
 /// Process payment
 /// </summary>
 /// <param name="paymentInfo">Payment info required for an order processing</param>
 /// <param name="customer">Customer</param>
 /// <param name="orderGuid">Unique order identifier</param>
 /// <param name="processPaymentResult">Process payment result</param>
 public void ProcessPayment(PaymentInfo paymentInfo, Customer customer, Guid orderGuid, ref ProcessPaymentResult processPaymentResult)
 {
     processPaymentResult.AllowStoringCreditCardNumber = true;
     TransactMode transactionMode = GetCurrentTransactionMode();
     switch (transactionMode)
     {
         case TransactMode.Pending:
             processPaymentResult.PaymentStatus = PaymentStatusEnum.Pending;
             break;
         case TransactMode.Authorize:
             processPaymentResult.PaymentStatus = PaymentStatusEnum.Authorized;
             break;
         case TransactMode.AuthorizeAndCapture:
             processPaymentResult.PaymentStatus = PaymentStatusEnum.Paid;
             break;
         default:
             throw new NopException("Not supported transact type");
     }
 }
Example #23
0
		/// <summary>
		/// Places an order
		/// </summary>
		/// <param name="paymentInfo">Payment info</param>
		/// <param name="customer">Customer</param>
		/// <param name="OrderID">Order identifier</param>
		/// <returns>The error status, or String.Empty if no errors</returns>
		public static string PlaceOrder(PaymentInfo paymentInfo, Customer customer, out int OrderID)
		{
			Guid OrderGuid = Guid.NewGuid();
			return PlaceOrder(paymentInfo, customer, OrderGuid, out OrderID);
		}
Example #24
0
        /// <summary>
        /// Valdiate minimum order total amount
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="customer">Customer</param>
        /// <returns>true - OK; false - minimum order total amount is not reached</returns>
        public bool ValidateMinOrderTotalAmount(ShoppingCart cart, Customer customer)
        {
            bool result = true;
            //min order amount validation
            if (cart.Count > 0 && this.MinOrderTotalAmount > decimal.Zero)
            {
                int paymentMethodId = 0;
                if (customer != null)
                    paymentMethodId = customer.LastPaymentMethodId;

                decimal discountAmountBase = decimal.Zero;
                Discount appliedDiscount = null;
                List<AppliedGiftCard> appliedGiftCards = null;
                int redeemedRewardPoints = 0;
                decimal redeemedRewardPointsAmount = decimal.Zero;
                bool useRewardPoints = false;
                if (customer != null)
                    useRewardPoints = customer.UseRewardPointsDuringCheckout;
                decimal? shoppingCartTotalBase = IoC.Resolve<IShoppingCartService>().GetShoppingCartTotal(cart,
                    paymentMethodId, customer,
                    out discountAmountBase, out appliedDiscount,
                    out appliedGiftCards, useRewardPoints,
                    out redeemedRewardPoints, out redeemedRewardPointsAmount);
                if (shoppingCartTotalBase.HasValue)
                {
                    if (shoppingCartTotalBase.Value < this.MinOrderTotalAmount)
                    {
                        result = false;
                    }
                }
            }

            return result;
        }
Example #25
0
        /// <summary>
        /// Valdiate minimum order sub-total amount
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="customer">Customer</param>
        /// <returns>true - OK; false - minimum order sub-total amount is not reached</returns>
        public bool ValidateMinOrderSubtotalAmount(ShoppingCart cart, Customer customer)
        {
            bool result = true;
            //min order amount sub-total validation
            if (cart.Count > 0 &&
                this.MinOrderSubtotalAmount > decimal.Zero)
            {
                //subtotal
                decimal subtotalBase = decimal.Zero;
                decimal orderSubTotalDiscountAmountBase = decimal.Zero;
                Discount orderSubTotalAppliedDiscount = null;
                decimal subTotalWithoutDiscountBase = decimal.Zero;
                decimal subTotalWithDiscountBase = decimal.Zero;
                string subTotalError = IoC.Resolve<IShoppingCartService>().GetShoppingCartSubTotal(cart,
                    customer, out orderSubTotalDiscountAmountBase, out orderSubTotalAppliedDiscount,
                out subTotalWithoutDiscountBase, out subTotalWithDiscountBase);
                subtotalBase = subTotalWithoutDiscountBase;
                if (String.IsNullOrEmpty(subTotalError))
                {
                    if (subtotalBase < this.MinOrderSubtotalAmount)
                    {
                        result = false;
                    }
                }
                else
                {
                    //do nothing (subtotal could not be calculated)
                    //result = false;
                }
            }

            return result;
        }
Example #26
0
        /// <summary>
        /// Gets a value indicating whether a customer can cancel recurring payment
        /// </summary>
        /// <param name="customerToValidate">Customer</param>
        /// <param name="recurringPayment">Recurring Payment</param>
        /// <returns>value indicating whether a customer can cancel recurring payment</returns>
        public bool CanCancelRecurringPayment(Customer customerToValidate, RecurringPayment recurringPayment)
        {
            if (recurringPayment == null)
                return false;

            if (customerToValidate == null)
                return false;

            var initialOrder = recurringPayment.InitialOrder;
            if (initialOrder == null)
                return false;

            var customer = recurringPayment.Customer;
            if (customer == null)
                return false;

            if (initialOrder.OrderStatus == OrderStatusEnum.Cancelled)
                return false;

            if (!customerToValidate.IsAdmin)
            {
                if (customer.CustomerId != customerToValidate.CustomerId)
                    return false;
            }

            if (!recurringPayment.NextPaymentDate.HasValue)
                return false;

            return true;
        }
Example #27
0
		/// <summary>
		/// Places an order
		/// </summary>
		/// <param name="paymentInfo">Payment info</param>
		/// <param name="customer">Customer</param>
		/// <param name="OrderGuid">Order GUID to use</param>
		/// <param name="OrderID">Order identifier</param>
		/// <returns>The error status, or String.Empty if no errors</returns>
		public static string PlaceOrder(PaymentInfo paymentInfo, Customer customer, Guid OrderGuid,
			out int OrderID)
		{
			OrderID = 0;
			ProcessPaymentResult processPaymentResult = new ProcessPaymentResult();
			try
			{
				if (customer == null)
					throw new ArgumentNullException("customer");

				if (customer.IsGuest && !CustomerManager.AnonymousCheckoutAllowed)
					throw new NopException("Anonymous checkout is not allowed");


				paymentInfo.BillingAddress.Email = customer.Email;

				//if (!CommonHelper.IsValidEmail(customer.Email))
				//{
				//    throw new NopException("Email is not valid");
				//}

				if (paymentInfo == null)
					throw new ArgumentNullException("paymentInfo");

				if (paymentInfo.BillingAddress == null)
					throw new NopException("Billing address not provided");

				//if (!CommonHelper.IsValidEmail(paymentInfo.BillingAddress.Email))
				//{
				//    throw new NopException("Email is not valid");
				//}

                PaymentMethod paymentMethod = PaymentMethodManager.GetPaymentMethodByID(paymentInfo.PaymentMethodID);
                if (paymentMethod == null)
                    throw new NopException("Payment method couldn't be loaded");

                if (!paymentMethod.IsActive)
                    throw new NopException("Payment method is not active");

				if (paymentInfo.CreditCardCVV2 == null)
					paymentInfo.CreditCardCVV2 = string.Empty;

				if (paymentInfo.CreditCardName == null)
					paymentInfo.CreditCardName = string.Empty;

				if (paymentInfo.CreditCardNumber == null)
					paymentInfo.CreditCardNumber = string.Empty;

				if (paymentInfo.CreditCardType == null)
					paymentInfo.CreditCardType = string.Empty;

				if (paymentInfo.PurchaseOrderNumber == null)
					paymentInfo.PurchaseOrderNumber = string.Empty;

				ShoppingCart cart = ShoppingCartManager.GetCustomerShoppingCart(customer.CustomerID, ShoppingCartTypeEnum.ShoppingCart);

				foreach (ShoppingCartItem sci in cart)
				{
					List<string> sciWarnings = ShoppingCartManager.GetShoppingCartItemWarnings(sci.ShoppingCartType,
						sci.ProductVariantID, sci.AttributesXML, sci.Quantity);

					if (sciWarnings.Count > 0)
					{
						StringBuilder warningsSb = new StringBuilder();
						foreach (string warning in sciWarnings)
						{
							warningsSb.Append(warning);
							warningsSb.Append(";");
						}
						throw new NopException(warningsSb.ToString());
					}
				}

				TaxDisplayTypeEnum customerTaxDisplayType = TaxDisplayTypeEnum.IncludingTax;
				if (TaxManager.AllowCustomersToSelectTaxDisplayType)
					customerTaxDisplayType = customer.TaxDisplayType;
				else
					customerTaxDisplayType = TaxManager.TaxDisplayType;

				decimal orderSubTotalDiscount;
				string SubTotalError1 = string.Empty;
				string SubTotalError2 = string.Empty;
				decimal orderSubTotalInclTax = ShoppingCartManager.GetShoppingCartSubTotal(cart, customer, out orderSubTotalDiscount, true, ref SubTotalError1);
				decimal orderSubTotalExclTax = ShoppingCartManager.GetShoppingCartSubTotal(cart, customer, out orderSubTotalDiscount, false, ref SubTotalError2);
				if (!String.IsNullOrEmpty(SubTotalError1) || !String.IsNullOrEmpty(SubTotalError2))
					throw new NopException("Sub total couldn't be calculated");

				decimal orderWeight = ShippingManager.GetShoppingCartTotalWeigth(cart);
				bool shoppingCartRequiresShipping = ShippingManager.ShoppingCartRequiresShipping(cart);
				//if (shoppingCartRequiresShipping)
				//{
				//    if (paymentInfo.ShippingAddress == null)
				//        throw new NopException("Shipping address is not provided");

				//    if (!CommonHelper.IsValidEmail(paymentInfo.ShippingAddress.Email))
				//    {
				//        throw new NopException("Email is not valid");
				//    }
				//}

				string ShippingTotalError1 = string.Empty;
				string ShippingTotalError2 = string.Empty;
				decimal? orderShippingTotalInclTax = ShippingManager.GetShoppingCartShippingTotal(cart, customer, true, ref ShippingTotalError1);
				decimal? orderShippingTotalExclTax = ShippingManager.GetShoppingCartShippingTotal(cart, customer, false, ref ShippingTotalError2);
				if (!orderShippingTotalInclTax.HasValue || !orderShippingTotalExclTax.HasValue)
					throw new NopException("Shipping total couldn't be calculated");

				string PaymentAdditionalFeeError1 = string.Empty;
				string PaymentAdditionalFeeError2 = string.Empty;
				decimal paymentAdditionalFee = PaymentManager.GetAdditionalHandlingFee(paymentInfo.PaymentMethodID);
				decimal paymentAdditionalFeeInclTax = TaxManager.GetPaymentMethodAdditionalFee(paymentAdditionalFee, true, customer, ref PaymentAdditionalFeeError1);
				decimal paymentAdditionalFeeExclTax = TaxManager.GetPaymentMethodAdditionalFee(paymentAdditionalFee, false, customer, ref PaymentAdditionalFeeError2);
				if (!String.IsNullOrEmpty(PaymentAdditionalFeeError1))
					throw new NopException("Payment method fee couldn't be calculated");
				if (!String.IsNullOrEmpty(PaymentAdditionalFeeError2))
					throw new NopException("Payment method fee couldn't be calculated");

				string TaxError = string.Empty;
				decimal orderTaxTotal = TaxManager.GetTaxTotal(cart, paymentInfo.PaymentMethodID, customer, ref TaxError);
				if (!String.IsNullOrEmpty(TaxError))
					throw new NopException("Tax total couldn't be calculated");

				decimal? orderTotal = ShoppingCartManager.GetShoppingCartTotal(cart, paymentInfo.PaymentMethodID, customer);
				if (!orderTotal.HasValue)
					throw new NopException("Order total couldn't be calculated");
				paymentInfo.OrderTotal = orderTotal.Value;

				decimal orderSubtotalInclTaxInCustomerCurrency = CurrencyManager.ConvertCurrency(orderSubTotalInclTax, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
				decimal orderSubtotalExclTaxInCustomerCurrency = CurrencyManager.ConvertCurrency(orderSubTotalExclTax, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
				decimal orderShippingInclTaxInCustomerCurrency = CurrencyManager.ConvertCurrency(orderShippingTotalInclTax.Value, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
				decimal orderShippingExclTaxInCustomerCurrency = CurrencyManager.ConvertCurrency(orderShippingTotalExclTax.Value, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
				decimal paymentAdditionalFeeInclTaxInCustomerCurrency = CurrencyManager.ConvertCurrency(paymentAdditionalFeeInclTax, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
				decimal paymentAdditionalFeeExclTaxInCustomerCurrency = CurrencyManager.ConvertCurrency(paymentAdditionalFeeExclTax, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
				decimal orderTaxInCustomerCurrency = CurrencyManager.ConvertCurrency(orderTaxTotal, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
				decimal orderTotalInCustomerCurrency = CurrencyManager.ConvertCurrency(orderTotal.Value, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
				string customerCurrencyCode = paymentInfo.CustomerCurrency.CurrencyCode;

				string billingStateProvince = string.Empty;
				int billingStateProvinceID = 0;
				string billingCountry = string.Empty;
				int billingCountryID = 0;
				if (paymentInfo.BillingAddress.StateProvince != null)
				{
					billingStateProvince = paymentInfo.BillingAddress.StateProvince.Name;
					billingStateProvinceID = paymentInfo.BillingAddress.StateProvince.StateProvinceID;
				}
				if (paymentInfo.BillingAddress.Country != null)
				{
					billingCountry = paymentInfo.BillingAddress.Country.Name;
					billingCountryID = paymentInfo.BillingAddress.Country.CountryID;

					if (!paymentInfo.BillingAddress.Country.AllowsBilling)
					{
						throw new NopException(string.Format("{0} is not allowed for billing", billingCountry));
					}
				}
				string shippingFirstName = string.Empty;
				string shippingLastName = string.Empty;
				string shippingPhoneNumber = string.Empty;
				string shippingEmail = string.Empty;
				string shippingFaxNumber = string.Empty;
				string shippingCompany = string.Empty;
				string shippingAddress1 = string.Empty;
				string shippingAddress2 = string.Empty;
				string shippingCity = string.Empty;
				string shippingStateProvince = string.Empty;
				int shippingStateProvinceID = 0;
				string shippingZipPostalCode = string.Empty;
				string shippingCountry = string.Empty;
				int shippingCountryID = 0;
				string shippingMethodName = string.Empty;
				if (shoppingCartRequiresShipping)
				{
					Address shippingAddress = paymentInfo.ShippingAddress;
					if (shippingAddress != null)
					{
						shippingFirstName = shippingAddress.FirstName;
						shippingLastName = shippingAddress.LastName;
						shippingPhoneNumber = shippingAddress.PhoneNumber;
						shippingEmail = shippingAddress.Email;
						shippingFaxNumber = shippingAddress.FaxNumber;
						shippingCompany = shippingAddress.Company;
						shippingAddress1 = shippingAddress.Address1;
						shippingAddress2 = shippingAddress.Address2;
						shippingCity = shippingAddress.City;
						if (shippingAddress.StateProvince != null)
						{
							shippingStateProvince = shippingAddress.StateProvince.Name;
							shippingStateProvinceID = shippingAddress.StateProvince.StateProvinceID;
						}
						shippingZipPostalCode = shippingAddress.ZipPostalCode;
						if (shippingAddress.Country != null)
						{
							shippingCountry = shippingAddress.Country.Name;
							shippingCountryID = shippingAddress.Country.CountryID;

							if (!shippingAddress.Country.AllowsShipping)
							{
								throw new NopException(string.Format("{0} is not allowed for shipping", shippingCountry));
							}
						}
						shippingMethodName = string.Empty;
						ShippingOption shippingOption = customer.LastShippingOption;
						if (shippingOption != null)
							shippingMethodName = shippingOption.Name;
					}
				}

				int activeShippingRateComputationMethodID = 0;
				ShippingRateComputationMethod activeShippingRateComputationMethod = ShippingManager.ActiveShippingRateComputationMethod;
				if (activeShippingRateComputationMethod != null)
				{
					activeShippingRateComputationMethodID = activeShippingRateComputationMethod.ShippingRateComputationMethodID;
				}

				//PaymentManager.ProcessPayment(paymentInfo, customer, OrderGuid, ref processPaymentResult);

				int customerLanguageID = paymentInfo.CustomerLanguage.LanguageID;
				if (String.IsNullOrEmpty(processPaymentResult.Error))
				{
					ShippingStatusEnum shippingStatusEnum = ShippingStatusEnum.NotYetShipped;
					if (!shoppingCartRequiresShipping)
						shippingStatusEnum = ShippingStatusEnum.ShippingNotRequired;

					Order order = InsertOrder(OrderGuid,
						 customer.CustomerID,
						 customerLanguageID,
						 customerTaxDisplayType,
						 orderSubTotalInclTax,
						 orderSubTotalExclTax,
						 orderShippingTotalInclTax.Value,
						 orderShippingTotalExclTax.Value,
						 paymentAdditionalFeeInclTax,
						 paymentAdditionalFeeExclTax,
						 orderTaxTotal,
						 orderTotal.Value,
						 orderSubTotalDiscount,
						 orderSubtotalInclTaxInCustomerCurrency,
						 orderSubtotalExclTaxInCustomerCurrency,
						 orderShippingInclTaxInCustomerCurrency,
						 orderShippingExclTaxInCustomerCurrency,
						 paymentAdditionalFeeInclTaxInCustomerCurrency,
						 paymentAdditionalFeeExclTaxInCustomerCurrency,
						 orderTaxInCustomerCurrency,
						 orderTotalInCustomerCurrency,
						 customerCurrencyCode,
						 orderWeight,
						 customer.AffiliateID,
						 OrderStatusEnum.Pending,
						 processPaymentResult.AllowStoringCreditCardNumber,
						 SecurityHelper.Encrypt(paymentInfo.CreditCardType),
						 SecurityHelper.Encrypt(paymentInfo.CreditCardName),
						 SecurityHelper.Encrypt(paymentInfo.CreditCardNumber),
						 SecurityHelper.Encrypt(PaymentManager.GetMaskedCreditCardNumber(paymentInfo.CreditCardNumber)),
						 processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Encrypt(paymentInfo.CreditCardCVV2) : string.Empty,
						 SecurityHelper.Encrypt(paymentInfo.CreditCardExpireMonth.ToString()),
						 SecurityHelper.Encrypt(paymentInfo.CreditCardExpireYear.ToString()),
						 paymentMethod.PaymentMethodID,
						 paymentMethod.Name,
						 processPaymentResult.AuthorizationTransactionID,
						 processPaymentResult.AuthorizationTransactionCode,
						 processPaymentResult.AuthorizationTransactionResult,
						 processPaymentResult.CaptureTransactionID,
						 processPaymentResult.CaptureTransactionResult,
						 paymentInfo.PurchaseOrderNumber,
						 processPaymentResult.PaymentStatus,
						 paymentInfo.BillingAddress.FirstName,
						 paymentInfo.BillingAddress.LastName,
						 paymentInfo.BillingAddress.PhoneNumber,
						 paymentInfo.BillingAddress.Email,
						 paymentInfo.BillingAddress.FaxNumber,
						 paymentInfo.BillingAddress.Company,
						 paymentInfo.BillingAddress.Address1,
						 paymentInfo.BillingAddress.Address2,
						 paymentInfo.BillingAddress.City,
						 billingStateProvince,
						 billingStateProvinceID,
						 paymentInfo.BillingAddress.ZipPostalCode,
						 billingCountry,
						 billingCountryID,
						 shippingStatusEnum,
						 shippingFirstName,
						 shippingLastName,
						 shippingPhoneNumber,
						 shippingEmail,
						 shippingFaxNumber,
						 shippingCompany,
						 shippingAddress1,
						 shippingAddress2,
						 shippingCity,
						 shippingStateProvince,
						 shippingStateProvinceID,
						 shippingZipPostalCode,
						 shippingCountry,
						 shippingCountryID,
						 shippingMethodName,
						 activeShippingRateComputationMethodID,
						 null,
						 false,
						 DateTime.Now);

					OrderID = order.OrderID;

					foreach (ShoppingCartItem sc in cart)
					{
						decimal scUnitPriceInclTax = TaxManager.GetPrice(sc.ProductVariant, PriceHelper.GetUnitPrice(sc, customer, true), true, customer);
						decimal scUnitPriceExclTax = TaxManager.GetPrice(sc.ProductVariant, PriceHelper.GetUnitPrice(sc, customer, true), false, customer);
						decimal scSubTotalInclTax = TaxManager.GetPrice(sc.ProductVariant, PriceHelper.GetSubTotal(sc, customer, true), true, customer);
						decimal scSubTotalExclTax = TaxManager.GetPrice(sc.ProductVariant, PriceHelper.GetSubTotal(sc, customer, true), false, customer);
						decimal scUnitPriceInclTaxInCustomerCurrency = CurrencyManager.ConvertCurrency(scUnitPriceInclTax, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
						decimal scUnitPriceExclTaxInCustomerCurrency = CurrencyManager.ConvertCurrency(scUnitPriceExclTax, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
						decimal scSubTotalInclTaxInCustomerCurrency = CurrencyManager.ConvertCurrency(scSubTotalInclTax, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);
						decimal scSubTotalExclTaxInCustomerCurrency = CurrencyManager.ConvertCurrency(scSubTotalExclTax, CurrencyManager.PrimaryStoreCurrency, paymentInfo.CustomerCurrency);

						decimal discountAmountInclTax = TaxManager.GetPrice(sc.ProductVariant, PriceHelper.GetDiscountAmount(sc, customer), true, customer);
						decimal discountAmountExclTax = TaxManager.GetPrice(sc.ProductVariant, PriceHelper.GetDiscountAmount(sc, customer), false, customer);

						string attributeDescription = ProductAttributeHelper.FormatAttributes(sc.ProductVariant, sc.AttributesXML);

						InsertOrderProductVariant(order.OrderID,
							sc.ProductVariantID, scUnitPriceInclTax, scUnitPriceExclTax, scSubTotalInclTax, scSubTotalExclTax,
							scUnitPriceInclTaxInCustomerCurrency, scUnitPriceExclTaxInCustomerCurrency,
							scSubTotalInclTaxInCustomerCurrency, scSubTotalExclTaxInCustomerCurrency,
							attributeDescription, sc.Quantity, discountAmountInclTax, discountAmountExclTax, 0);

						ProductManager.AdjustInventory(sc.ProductVariantID, true, sc.Quantity);
					}

					InsertOrderNote(OrderID, string.Format("Order placed"), DateTime.Now);

					//int orderPlacedStoreOwnerNotificationQueuedEmailID = MessageManager.SendOrderPlacedStoreOwnerNotification(order, LocalizationManager.DefaultAdminLanguage.LanguageID);
					//InsertOrderNote(OrderID, string.Format("\"Order placed\" email (to store owner) has been queued. Queued email identifier: {0}.", orderPlacedStoreOwnerNotificationQueuedEmailID), DateTime.Now);

					//int orderPlacedCustomerNotificationQueuedEmailID = MessageManager.SendOrderPlacedCustomerNotification(order, order.CustomerLanguageID);
					//InsertOrderNote(OrderID, string.Format("\"Order placed\" email (to customer) has been queued. Queued email identifier: {0}.", orderPlacedCustomerNotificationQueuedEmailID), DateTime.Now);

					order = CheckOrderStatus(order.OrderID);

					CustomerManager.ResetCheckoutData(customer.CustomerID, true);
				}
			}
			catch (Exception exc)
			{
				processPaymentResult.Error = exc.Message;
				processPaymentResult.FullError = exc.ToString();
			}

			if (!String.IsNullOrEmpty(processPaymentResult.Error))
			{
				LogManager.InsertLog(LogTypeEnum.OrderError, string.Format("Error while placing order. {0}", processPaymentResult.Error), processPaymentResult.FullError);
			}
			return processPaymentResult.Error;
		}
 /// <summary>
 /// Process payment
 /// </summary>
 /// <param name="paymentInfo">Payment info required for an order processing</param>
 /// <param name="customer">Customer</param>
 /// <param name="orderGuid">Unique order identifier</param>
 /// <param name="processPaymentResult">Process payment result</param>
 public void ProcessPayment(PaymentInfo paymentInfo, Customer customer, Guid orderGuid, ref ProcessPaymentResult processPaymentResult)
 {
     processPaymentResult.PaymentStatus = PaymentStatusEnum.Pending;
 }
        /// <summary>
        /// Process recurring payment
        /// </summary>
        /// <param name="paymentInfo">Payment info required for an order processing</param>
        /// <param name="customer">Customer</param>
        /// <param name="orderGuid">Unique order identifier</param>
        /// <param name="processPaymentResult">Process payment result</param>
        public void ProcessRecurringPayment(PaymentInfo paymentInfo, Customer customer, Guid orderGuid, ref ProcessPaymentResult processPaymentResult)
        {
            processPaymentResult.AllowStoringCreditCardNumber = true;
            TransactMode transactionMode = GetCurrentTransactionMode();
            switch (transactionMode)
            {
                case TransactMode.Pending:
                    processPaymentResult.PaymentStatus = PaymentStatusEnum.Pending;
                    break;
                case TransactMode.Authorize:
                    processPaymentResult.PaymentStatus = PaymentStatusEnum.Authorized;
                    break;
                case TransactMode.AuthorizeAndCapture:
                    processPaymentResult.PaymentStatus = PaymentStatusEnum.Paid;
                    break;
                default:
                    throw new NopException("Not supported transact type");
            }

            //restore credit cart info
            if (paymentInfo.IsRecurringPayment)
            {
                Order initialOrder = OrderManager.GetOrderById(paymentInfo.InitialOrderId);
                if (initialOrder != null)
                {
                    paymentInfo.CreditCardType = processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Decrypt(initialOrder.CardType) : string.Empty;
                    paymentInfo.CreditCardName = processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Decrypt(initialOrder.CardName) : string.Empty;
                    paymentInfo.CreditCardNumber = processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Decrypt(initialOrder.CardNumber) : string.Empty;
                    paymentInfo.CreditCardCvv2 = processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Decrypt(initialOrder.CardCvv2) : string.Empty;
                    try
                    {
                        paymentInfo.CreditCardExpireMonth = Convert.ToInt32(processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Decrypt(initialOrder.CardExpirationMonth) : "0");
                        paymentInfo.CreditCardExpireYear = Convert.ToInt32(processPaymentResult.AllowStoringCreditCardNumber ? SecurityHelper.Decrypt(initialOrder.CardExpirationYear) : "0");
                    }
                    catch
                    {
                    }
                }
            }
        }
 /// <summary>
 /// Process payment
 /// </summary>
 /// <param name="paymentInfo">Payment info required for an order processing</param>
 /// <param name="customer">Customer</param>
 /// <param name="orderGuid">Unique order identifier</param>
 /// <param name="processPaymentResult">Process payment result</param>
 public void ProcessPayment(PaymentInfo paymentInfo, Customer customer, Guid orderGuid, ref ProcessPaymentResult processPaymentResult)
 {
     DoExpressCheckout(paymentInfo, orderGuid, processPaymentResult);
 }