public void Can_serialize_and_deserialize_CustomValues()
        {
            var processPaymentRequest = new ProcessPaymentRequest();
            processPaymentRequest.CustomValues.Add("key1", "value1");
            processPaymentRequest.CustomValues.Add("key2", null);
            processPaymentRequest.CustomValues.Add("key3", 3);
            processPaymentRequest.CustomValues.Add("<test key4>", "<test value 4>");
            var serializedXml = processPaymentRequest.SerializeCustomValues();
            var deserialized = processPaymentRequest.DeserializeCustomValues(serializedXml);

            deserialized.ShouldNotBeNull();
            deserialized.Count.ShouldEqual(4);

            deserialized.ContainsKey("key1").ShouldEqual(true);
            deserialized["key1"].ShouldEqual("value1");

            deserialized.ContainsKey("key2").ShouldEqual(true);
            //deserialized["key2"].ShouldEqual(null);
            deserialized["key2"].ShouldEqual("");

            deserialized.ContainsKey("key3").ShouldEqual(true);
            deserialized["key3"].ShouldEqual("3");

            deserialized.ContainsKey("<test key4>").ShouldEqual(true);
            deserialized["<test key4>"].ShouldEqual("<test value 4>");
        }
        /// <summary>
        /// Process a payment
        /// </summary>
        /// <param name="processPaymentRequest">Payment info required for an order processing</param>
        /// <returns>Process payment result</returns>
        public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest)
        {
            var result = new ProcessPaymentResult();

            result.AllowStoringCreditCardNumber = true;
            switch (_manualPaymentSettings.TransactMode)
            {
                case TransactMode.Pending:
                    result.NewPaymentStatus = PaymentStatus.Pending;
                    break;
                case TransactMode.Authorize:
                    result.NewPaymentStatus = PaymentStatus.Authorized;
                    break;
                case TransactMode.AuthorizeAndCapture:
                    result.NewPaymentStatus = PaymentStatus.Paid;
                    break;
                default:
                    {
                        result.AddError("Not supported transaction type");
                        return result;
                    }
            }

            return result;
        }
        public void Can_deserialize_null_string()
        {
            var processPaymentRequest = new ProcessPaymentRequest();
            var deserialized = processPaymentRequest.DeserializeCustomValues(null);

            deserialized.ShouldNotBeNull();
            deserialized.Count.ShouldEqual(0);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Deerialize CustomValues of Order
        /// </summary>
        /// <param name="order">Order</param>
        /// <returns>Serialized CustomValues CustomValues</returns>
        public static Dictionary<string, object> DeserializeCustomValues(this Order order)
        {
            if (order == null)
                throw new ArgumentNullException("order");

            var request = new ProcessPaymentRequest();
            return request.DeserializeCustomValues(order.CustomValuesXml);
        }
        public void Can_serialize_and_deserialize_empty_CustomValues()
        {
            var processPaymentRequest = new ProcessPaymentRequest();
            var serializedXml = processPaymentRequest.SerializeCustomValues();
            var deserialized = processPaymentRequest.DeserializeCustomValues(serializedXml);

            deserialized.ShouldNotBeNull();
            deserialized.Count.ShouldEqual(0);
        }
 public override ProcessPaymentRequest GetPaymentInfo(FormCollection form)
 {
     var paymentInfo = new ProcessPaymentRequest();
     paymentInfo.CreditCardType = form["CreditCardType"];
     paymentInfo.CreditCardName = form["CardholderName"];
     paymentInfo.CreditCardNumber = form["CardNumber"];
     paymentInfo.CreditCardExpireMonth = int.Parse(form["ExpireMonth"]);
     paymentInfo.CreditCardExpireYear = int.Parse(form["ExpireYear"]);
     paymentInfo.CreditCardCvv2 = form["CardCode"];
     return paymentInfo;
 }
        /// <summary>
        /// Process a payment
        /// </summary>
        /// <param name="processPaymentRequest">Payment info required for an order processing</param>
        /// <returns>Process payment result</returns>
        public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest)
        {
            var result = new ProcessPaymentResult();

            var orderGuid = processPaymentRequest.OrderGuid;


            if (orderGuid == Guid.NewGuid())
            {
                result.AddError("SagePay Server transaction code does not exist!");
                return result;
            }

            var transx = _sagePayServerTransactionService.GetSagePayServerTransactionByVendorTxCode(orderGuid.ToString());

            if (transx == null)
            {
                result.AddError(String.Format("SagePay Server transaction code {0} does not exist.", orderGuid.ToString()));
                return result;
            }

            if ((transx.Status == "OK") || (transx.Status == "AUTHENTICATED") || (transx.Status == "REGISTERED"))
            {
                if (_sagePayServerPaymentSettings.TransactType == SagePayServerPaymentSettings.TransactTypeValues.PAYMENT)
                    result.NewPaymentStatus = PaymentStatus.Paid;
                else if (_sagePayServerPaymentSettings.TransactType == SagePayServerPaymentSettings.TransactTypeValues.DEFERRED)
                    result.NewPaymentStatus = PaymentStatus.Authorized;
                else
                    result.NewPaymentStatus = PaymentStatus.Pending;
                result.AuthorizationTransactionId = transx.Id.ToString();
                result.AuthorizationTransactionCode = transx.VPSTxId;
                result.AuthorizationTransactionResult = transx.ToString();
            }
            else
            {
                result.AddError(transx.StatusDetail);
            }


            return result;

        }
 /// <summary>
 /// Process a payment
 /// </summary>
 /// <param name="processPaymentRequest">Payment info required for an order processing</param>
 /// <returns>Process payment result</returns>
 public virtual ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest)
 {
     if (processPaymentRequest.OrderTotal == decimal.Zero)
     {
         var result = new ProcessPaymentResult()
         {
             NewPaymentStatus = PaymentStatus.Paid
         };
         return result;
     }
     else
     {
         //We should strip out any white space or dash in the CC number entered.
         if (!String.IsNullOrWhiteSpace(processPaymentRequest.CreditCardNumber))
         {
             processPaymentRequest.CreditCardNumber = processPaymentRequest.CreditCardNumber.Replace(" ", "");
             processPaymentRequest.CreditCardNumber = processPaymentRequest.CreditCardNumber.Replace("-", "");
         }
         var paymentMethod = LoadPaymentMethodBySystemName(processPaymentRequest.PaymentMethodSystemName);
         if (paymentMethod == null)
             throw new NopException("Payment method couldn't be loaded");
         return paymentMethod.ProcessPayment(processPaymentRequest);
     }
 }
 /// <summary>
 /// Process recurring payment
 /// </summary>
 /// <param name="processPaymentRequest">Payment info required for an order processing</param>
 /// <returns>Process payment result</returns>
 public ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest)
 {
     var result = new ProcessPaymentResult();
     result.AddError("Recurring payment not supported");
     return result;
 }
Exemplo n.º 10
0
        protected ProcessPaymentResult AuthorizeOrSale(ProcessPaymentRequest processPaymentRequest, bool authorizeOnly)
        {
            var result = new ProcessPaymentResult();

            var customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId);
            if (customer == null)
                throw new Exception("Customer cannot be loaded");

            var req = new DoDirectPaymentReq();
            req.DoDirectPaymentRequest = new DoDirectPaymentRequestType();
            req.DoDirectPaymentRequest.Version = GetApiVersion();
            var details = new DoDirectPaymentRequestDetailsType();
            req.DoDirectPaymentRequest.DoDirectPaymentRequestDetails = details;
            details.IPAddress = _webHelper.GetCurrentIpAddress() ?? "";
            if (authorizeOnly)
                details.PaymentAction = PaymentActionCodeType.AUTHORIZATION;
            else
                details.PaymentAction = PaymentActionCodeType.SALE;
            //credit card
            details.CreditCard = new CreditCardDetailsType();
            details.CreditCard.CreditCardNumber = processPaymentRequest.CreditCardNumber;
            details.CreditCard.CreditCardType = GetPaypalCreditCardType(processPaymentRequest.CreditCardType);
            details.CreditCard.ExpMonth = processPaymentRequest.CreditCardExpireMonth;
            details.CreditCard.ExpYear = processPaymentRequest.CreditCardExpireYear;
            details.CreditCard.CVV2 = processPaymentRequest.CreditCardCvv2;
            details.CreditCard.CardOwner = new PayerInfoType();
            var country = EngineContext.Current.Resolve<ICountryService>().GetCountryById(customer.BillingAddress.CountryId);
            details.CreditCard.CardOwner.PayerCountry = GetPaypalCountryCodeType(country);
            //billing address
            details.CreditCard.CardOwner.Address = new AddressType();
            details.CreditCard.CardOwner.Address.Street1 = customer.BillingAddress.Address1;
            details.CreditCard.CardOwner.Address.Street2 = customer.BillingAddress.Address2;
            details.CreditCard.CardOwner.Address.CityName = customer.BillingAddress.City;
            if (customer.BillingAddress.StateProvinceId != 0)
            {
                var state = EngineContext.Current.Resolve<IStateProvinceService>().GetStateProvinceById(customer.BillingAddress.StateProvinceId);
                details.CreditCard.CardOwner.Address.StateOrProvince = state.Abbreviation;
            }
            else
                details.CreditCard.CardOwner.Address.StateOrProvince = "CA";
            details.CreditCard.CardOwner.Address.Country = GetPaypalCountryCodeType(country);
            details.CreditCard.CardOwner.Address.PostalCode = customer.BillingAddress.ZipPostalCode;
            details.CreditCard.CardOwner.Payer = customer.BillingAddress.Email;
            details.CreditCard.CardOwner.PayerName = new PersonNameType();
            details.CreditCard.CardOwner.PayerName.FirstName = customer.BillingAddress.FirstName;
            details.CreditCard.CardOwner.PayerName.LastName = customer.BillingAddress.LastName;
            //order totals
            var payPalCurrency = PaypalHelper.GetPaypalCurrency(_currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId));
            details.PaymentDetails = new PaymentDetailsType();
            details.PaymentDetails.OrderTotal = new BasicAmountType();
            details.PaymentDetails.OrderTotal.value = Math.Round(processPaymentRequest.OrderTotal, 2).ToString("N", new CultureInfo("en-us"));
            details.PaymentDetails.OrderTotal.currencyID = payPalCurrency;
            details.PaymentDetails.Custom = processPaymentRequest.OrderGuid.ToString();
            details.PaymentDetails.ButtonSource = "nopCommerceCart";
            //shipping
            if (customer.ShippingAddress != null)
            {
                if (customer.ShippingAddress.StateProvinceId != 0 && customer.ShippingAddress.CountryId != 0)
                {
                    var state = EngineContext.Current.Resolve<IStateProvinceService>().GetStateProvinceById(customer.ShippingAddress.StateProvinceId);
                    var countryshipping = EngineContext.Current.Resolve<ICountryService>().GetCountryById(customer.ShippingAddress.CountryId);

                    var shippingAddress = new AddressType();
                    shippingAddress.Name = customer.ShippingAddress.FirstName + " " + customer.ShippingAddress.LastName;
                    shippingAddress.Street1 = customer.ShippingAddress.Address1;
                    shippingAddress.Street2 = customer.ShippingAddress.Address2;
                    shippingAddress.CityName = customer.ShippingAddress.City;
                    shippingAddress.StateOrProvince = state.Abbreviation;
                    shippingAddress.PostalCode = customer.ShippingAddress.ZipPostalCode;
                    shippingAddress.Country = (CountryCodeType)Enum.Parse(typeof(CountryCodeType), countryshipping.TwoLetterIsoCode, true);
                    details.PaymentDetails.ShipToAddress = shippingAddress;
                }
            }

            //send request
            var service = GetService();
            DoDirectPaymentResponseType response = service.DoDirectPayment(req);

            string error;
            bool success = PaypalHelper.CheckSuccess(response, out error);
            if (success)
            {
                result.AvsResult = response.AVSCode;
                result.AuthorizationTransactionCode = response.CVV2Code;
                if (authorizeOnly)
                {
                    result.AuthorizationTransactionId = response.TransactionID;
                    result.AuthorizationTransactionResult = response.Ack.ToString();

                    result.NewPaymentStatus = PaymentStatus.Authorized;
                }
                else
                {
                    result.CaptureTransactionId = response.TransactionID;
                    result.CaptureTransactionResult = response.Ack.ToString();

                    result.NewPaymentStatus = PaymentStatus.Paid;
                }
            }
            else
            {
                result.AddError(error);
            }
            return result;
        }
Exemplo n.º 11
0
        /// <summary>
        /// Process a payment
        /// </summary>
        /// <param name="processPaymentRequest">Payment info required for an order processing</param>
        /// <returns>Process payment result</returns>
        public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest)
        {
            if (_paypalDirectPaymentSettings.TransactMode == TransactMode.Authorize)
            {
                return AuthorizeOrSale(processPaymentRequest, true);
            }

            return AuthorizeOrSale(processPaymentRequest, false);
        }
        protected ProcessPaymentResult AuthorizeOrSale(ProcessPaymentRequest processPaymentRequest, bool authorizeOnly)
        {
            var result = new ProcessPaymentResult();

            var customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId);
            if (customer == null)
                throw new Exception("Customer cannot be loaded");

            var req = new DoDirectPaymentReq();
            req.DoDirectPaymentRequest = new DoDirectPaymentRequestType();
            req.DoDirectPaymentRequest.Version = GetApiVersion();
            var details = new DoDirectPaymentRequestDetailsType();
            req.DoDirectPaymentRequest.DoDirectPaymentRequestDetails = details;
            details.IPAddress = _webHelper.GetCurrentIpAddress() ?? "";
            if (authorizeOnly)
                details.PaymentAction = PaymentActionCodeType.Authorization;
            else
                details.PaymentAction = PaymentActionCodeType.Sale;
            //credit card
            details.CreditCard = new CreditCardDetailsType();
            details.CreditCard.CreditCardNumber = processPaymentRequest.CreditCardNumber;
            details.CreditCard.CreditCardType = GetPaypalCreditCardType(processPaymentRequest.CreditCardType);
            details.CreditCard.ExpMonthSpecified = true;
            details.CreditCard.ExpMonth = processPaymentRequest.CreditCardExpireMonth;
            details.CreditCard.ExpYearSpecified = true;
            details.CreditCard.ExpYear = processPaymentRequest.CreditCardExpireYear;
            details.CreditCard.CVV2 = processPaymentRequest.CreditCardCvv2;
            details.CreditCard.CardOwner = new PayerInfoType();
            details.CreditCard.CardOwner.PayerCountry = GetPaypalCountryCodeType(customer.BillingAddress.Country);
            details.CreditCard.CreditCardTypeSpecified = true;
            //billing address
            details.CreditCard.CardOwner.Address = new AddressType();
            details.CreditCard.CardOwner.Address.CountrySpecified = true;
            details.CreditCard.CardOwner.Address.Street1 = customer.BillingAddress.Address1;
            details.CreditCard.CardOwner.Address.Street2 = customer.BillingAddress.Address2;
            details.CreditCard.CardOwner.Address.CityName = customer.BillingAddress.City;
            if (customer.BillingAddress.StateProvince != null)
                details.CreditCard.CardOwner.Address.StateOrProvince = customer.BillingAddress.StateProvince.Abbreviation;
            else
                details.CreditCard.CardOwner.Address.StateOrProvince = "CA";
            details.CreditCard.CardOwner.Address.Country = GetPaypalCountryCodeType(customer.BillingAddress.Country);
            details.CreditCard.CardOwner.Address.PostalCode = customer.BillingAddress.ZipPostalCode;
            details.CreditCard.CardOwner.Payer = customer.BillingAddress.Email;
            details.CreditCard.CardOwner.PayerName = new PersonNameType();
            details.CreditCard.CardOwner.PayerName.FirstName = customer.BillingAddress.FirstName;
            details.CreditCard.CardOwner.PayerName.LastName = customer.BillingAddress.LastName;
            //order totals
            var payPalCurrency = PaypalHelper.GetPaypalCurrency(_currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId));
            details.PaymentDetails = new PaymentDetailsType();
            details.PaymentDetails.OrderTotal = new BasicAmountType();
            details.PaymentDetails.OrderTotal.Value = Math.Round(processPaymentRequest.OrderTotal, 2).ToString("N", new CultureInfo("en-us"));
            details.PaymentDetails.OrderTotal.currencyID = payPalCurrency;
            details.PaymentDetails.Custom = processPaymentRequest.OrderGuid.ToString();
            details.PaymentDetails.ButtonSource = "nopCommerceCart";
            //pass product names and totals to PayPal
            //if (_paypalDirectPaymentSettings.PassProductNamesAndTotals)
            //{
            //    //individual items
                //var cart = customer.ShoppingCartItems
                //    .Where(x=>x.ShoppingCartType == ShoppingCartType.ShoppingCart)
                //    .LimitPerStore(processPaymentRequest.StoreId)
                //    .ToList();
            //    var cartItems = new PaymentDetailsItemType[cart.Count];
            //    for (int i = 0; i < cart.Count; i++)
            //    {
            //        var sc = cart[i];
            //        decimal taxRate = decimal.Zero;
            //        var customer = processPaymentRequest.Customer;
            //        decimal scUnitPrice = _priceCalculationService.GetUnitPrice(sc, true);
            //        decimal scSubTotal = _priceCalculationService.GetSubTotal(sc, true);
            //        decimal scUnitPriceInclTax = _taxService.GetProductPrice(sc.ProductVariant, scUnitPrice, true, customer, out taxRate);
            //        decimal scUnitPriceExclTax = _taxService.GetProductPrice(sc.ProductVariant, scUnitPrice, false, customer, out taxRate);
            //        //decimal scSubTotalInclTax = _taxService.GetProductPrice(sc.ProductVariant, scSubTotal, true, customer, out taxRate);
            //        //decimal scSubTotalExclTax = _taxService.GetProductPrice(sc.ProductVariant, scSubTotal, false, customer, out taxRate);
            //        cartItems[i] = new PaymentDetailsItemType()
            //        {
            //            Name = sc.ProductVariant.FullProductName,
            //            Number = sc.ProductVariant.Id.ToString(),
            //            Quantity = sc.Quantity.ToString(),
            //            Amount = new BasicAmountType()
            //            {
            //                currencyID = payPalCurrency,
            //                Value = scUnitPriceExclTax.ToString("N", new CultureInfo("en-us")),
            //            },
            //            Tax = new BasicAmountType()
            //            {
            //                currencyID = payPalCurrency,
            //                Value = (scUnitPriceInclTax - scUnitPriceExclTax).ToString("N", new CultureInfo("en-us")),
            //            },
            //        };
            //    };
            //    details.PaymentDetails.PaymentDetailsItem = cartItems;
            //    //other totals (undone)
            //    details.PaymentDetails.ItemTotal = null;
            //    details.PaymentDetails.ShippingTotal = null;
            //    details.PaymentDetails.TaxTotal = null;
            //    details.PaymentDetails.HandlingTotal = null;
            //}
            //shipping
            if (customer.ShippingAddress != null)
            {
                if (customer.ShippingAddress.StateProvince != null && customer.ShippingAddress.Country != null)
                {
                    var shippingAddress = new AddressType();
                    shippingAddress.Name = customer.ShippingAddress.FirstName + " " + customer.ShippingAddress.LastName;
                    shippingAddress.Street1 = customer.ShippingAddress.Address1;
                    shippingAddress.CityName = customer.ShippingAddress.City;
                    shippingAddress.StateOrProvince = customer.ShippingAddress.StateProvince.Abbreviation;
                    shippingAddress.PostalCode = customer.ShippingAddress.ZipPostalCode;
                    shippingAddress.Country = (CountryCodeType)Enum.Parse(typeof(CountryCodeType), customer.ShippingAddress.Country.TwoLetterIsoCode, true);
                    shippingAddress.CountrySpecified = true;
                    details.PaymentDetails.ShipToAddress = shippingAddress;
                }
            }

            //send request
            using (var service2 = new PayPalAPIAASoapBinding())
            {
                if (!_paypalDirectPaymentSettings.UseSandbox)
                    service2.Url = "https://api-3t.paypal.com/2.0/";
                else
                    service2.Url = "https://api-3t.sandbox.paypal.com/2.0/";

                service2.RequesterCredentials = new CustomSecurityHeaderType();
                service2.RequesterCredentials.Credentials = new UserIdPasswordType();
                service2.RequesterCredentials.Credentials.Username = _paypalDirectPaymentSettings.ApiAccountName;
                service2.RequesterCredentials.Credentials.Password = _paypalDirectPaymentSettings.ApiAccountPassword;
                service2.RequesterCredentials.Credentials.Signature = _paypalDirectPaymentSettings.Signature;
                service2.RequesterCredentials.Credentials.Subject = "";

                DoDirectPaymentResponseType response = service2.DoDirectPayment(req);

                string error = "";
                bool success = PaypalHelper.CheckSuccess(response, out error);
                if (success)
                {
                    result.AvsResult = response.AVSCode;
                    result.AuthorizationTransactionCode = response.CVV2Code;
                    if (authorizeOnly)
                    {
                        result.AuthorizationTransactionId = response.TransactionID;
                        result.AuthorizationTransactionResult = response.Ack.ToString();

                        result.NewPaymentStatus = PaymentStatus.Authorized;
                    }
                    else
                    {
                        result.CaptureTransactionId = response.TransactionID;
                        result.CaptureTransactionResult = response.Ack.ToString();

                        result.NewPaymentStatus = PaymentStatus.Paid;
                    }
                }
                else
                {
                    result.AddError(error);
                }
            }
            return result;
        }
Exemplo n.º 13
0
        /// <summary>
        /// Places an order
        /// </summary>
        /// <param name="processPaymentRequest">Process payment request</param>
        /// <returns>Place order result</returns>
        public virtual PlaceOrderResult PlaceOrder(ProcessPaymentRequest processPaymentRequest)
        {
            //think about moving functionality of processing recurring orders (after the initial order was placed) to ProcessNextRecurringPayment() method
            if (processPaymentRequest == null)
                throw new ArgumentNullException("processPaymentRequest");

            if (processPaymentRequest.OrderGuid == Guid.Empty)
                processPaymentRequest.OrderGuid = Guid.NewGuid();

            var result = new PlaceOrderResult();
            try
            {
                #region Order details (customer, addresses, totals)

                //Recurring orders. Load initial order
                Order initialOrder = _orderService.GetOrderById(processPaymentRequest.InitialOrderId);
                if (processPaymentRequest.IsRecurringPayment)
                {
                    if (initialOrder == null)
                        throw new ArgumentException("Initial order is not set for recurring payment");

                    processPaymentRequest.PaymentMethodSystemName = initialOrder.PaymentMethodSystemName;
                }

                //customer
                var customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId);
                if (customer == null)
                    throw new ArgumentException("Customer is not set");

                //affilites
                int affiliateId = 0;
                var affiliate = _affiliateService.GetAffiliateById(customer.AffiliateId);
                if (affiliate != null && affiliate.Active && !affiliate.Deleted)
                    affiliateId = affiliate.Id;

                //customer currency
                string customerCurrencyCode = "";
                decimal customerCurrencyRate;
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    var currencyTmp = _currencyService.GetCurrencyById(customer.GetAttribute<int>(SystemCustomerAttributeNames.CurrencyId, processPaymentRequest.StoreId));
                    var customerCurrency = (currencyTmp != null && currencyTmp.Published) ? currencyTmp : _workContext.WorkingCurrency;
                    customerCurrencyCode = customerCurrency.CurrencyCode;
                    var primaryStoreCurrency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId);
                    customerCurrencyRate = customerCurrency.Rate / primaryStoreCurrency.Rate;
                }
                else
                {
                    customerCurrencyCode = initialOrder.CustomerCurrencyCode;
                    customerCurrencyRate = initialOrder.CurrencyRate;
                }
                //customer language
                Language customerLanguage;
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    customerLanguage = _languageService.GetLanguageById(customer.GetAttribute<int>(
                        SystemCustomerAttributeNames.LanguageId, processPaymentRequest.StoreId));
                }
                else
                {
                    customerLanguage = _languageService.GetLanguageById(initialOrder.CustomerLanguageId);
                }
                if (customerLanguage == null || !customerLanguage.Published)
                    customerLanguage = _workContext.WorkingLanguage;

                //check whether customer is guest
                if (customer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed)
                    throw new NopException("Anonymous checkout is not allowed");

                //billing address
                Address billingAddress;
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    if (customer.BillingAddress == null)
                        throw new NopException("Billing address is not provided");

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

                    //clone billing address
                    billingAddress = (Address)customer.BillingAddress.Clone();
                    if (billingAddress.Country != null && !billingAddress.Country.AllowsBilling)
                        throw new NopException(string.Format("Country '{0}' is not allowed for billing", billingAddress.Country.Name));
                }
                else
                {
                    if (initialOrder.BillingAddress == null)
                        throw new NopException("Billing address is not available");

                    //clone billing address
                    billingAddress = (Address)initialOrder.BillingAddress.Clone();
                    if (billingAddress.Country != null && !billingAddress.Country.AllowsBilling)
                        throw new NopException(string.Format("Country '{0}' is not allowed for billing", billingAddress.Country.Name));
                }

                //checkout attributes
                string checkoutAttributeDescription, checkoutAttributesXml;
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    checkoutAttributesXml = customer.GetAttribute<string>(SystemCustomerAttributeNames.CheckoutAttributes, processPaymentRequest.StoreId);
                    checkoutAttributeDescription = _checkoutAttributeFormatter.FormatAttributes(checkoutAttributesXml, customer);
                }
                else
                {
                    checkoutAttributesXml = initialOrder.CheckoutAttributesXml;
                    checkoutAttributeDescription = initialOrder.CheckoutAttributeDescription;
                }

                //load and validate customer shopping cart
                IList<ShoppingCartItem> cart = null;
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    //load shopping cart
                    cart = customer.ShoppingCartItems
                        .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
                        .LimitPerStore(processPaymentRequest.StoreId)
                        .ToList();

                    if (cart.Count == 0)
                        throw new NopException("Cart is empty");

                    //validate the entire shopping cart
                    var warnings = _shoppingCartService.GetShoppingCartWarnings(cart,
                        checkoutAttributesXml,
                        true);
                    if (warnings.Count > 0)
                    {
                        var 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(customer, sci.ShoppingCartType,
                            sci.Product, processPaymentRequest.StoreId, sci.AttributesXml,
                            sci.CustomerEnteredPrice, sci.RentalStartDateUtc, sci.RentalEndDateUtc,
                            sci.Quantity, false);
                        if (sciWarnings.Count > 0)
                        {
                            var warningsSb = new StringBuilder();
                            foreach (string warning in sciWarnings)
                            {
                                warningsSb.Append(warning);
                                warningsSb.Append(";");
                            }
                            throw new NopException(warningsSb.ToString());
                        }
                    }
                }

                //min totals validation
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    bool minOrderSubtotalAmountOk = ValidateMinOrderSubtotalAmount(cart);
                    if (!minOrderSubtotalAmountOk)
                    {
                        decimal minOrderSubtotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderSubtotalAmount, _workContext.WorkingCurrency);
                        throw new NopException(string.Format(_localizationService.GetResource("Checkout.MinOrderSubtotalAmount"), _priceFormatter.FormatPrice(minOrderSubtotalAmount, true, false)));
                    }
                    bool minOrderTotalAmountOk = ValidateMinOrderTotalAmount(cart);
                    if (!minOrderTotalAmountOk)
                    {
                        decimal minOrderTotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderTotalAmount, _workContext.WorkingCurrency);
                        throw new NopException(string.Format(_localizationService.GetResource("Checkout.MinOrderTotalAmount"), _priceFormatter.FormatPrice(minOrderTotalAmount, true, false)));
                    }
                }

                //tax display type
                var customerTaxDisplayType = TaxDisplayType.IncludingTax;
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    if (_taxSettings.AllowCustomersToSelectTaxDisplayType)
                        customerTaxDisplayType = (TaxDisplayType)customer.GetAttribute<int>(SystemCustomerAttributeNames.TaxDisplayTypeId, processPaymentRequest.StoreId);
                    else
                        customerTaxDisplayType = _taxSettings.TaxDisplayType;
                }
                else
                {
                    customerTaxDisplayType = initialOrder.CustomerTaxDisplayType;
                }

                //applied discount (used to store discount usage history)
                var appliedDiscounts = new List<Discount>();

                //sub total
                decimal orderSubTotalInclTax, orderSubTotalExclTax;
                decimal orderSubTotalDiscountInclTax = 0, orderSubTotalDiscountExclTax = 0;
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    //sub total (incl tax)
                    decimal orderSubTotalDiscountAmount1;
                    Discount orderSubTotalAppliedDiscount1;
                    decimal subTotalWithoutDiscountBase1;
                    decimal subTotalWithDiscountBase1;
                    _orderTotalCalculationService.GetShoppingCartSubTotal(cart,
                        true, out orderSubTotalDiscountAmount1, out orderSubTotalAppliedDiscount1,
                        out subTotalWithoutDiscountBase1, out subTotalWithDiscountBase1);
                    orderSubTotalInclTax = subTotalWithoutDiscountBase1;
                    orderSubTotalDiscountInclTax = orderSubTotalDiscountAmount1;

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

                    //sub total (excl tax)
                    decimal orderSubTotalDiscountAmount2;
                    Discount orderSubTotalAppliedDiscount2;
                    decimal subTotalWithoutDiscountBase2;
                    decimal subTotalWithDiscountBase2;
                    _orderTotalCalculationService.GetShoppingCartSubTotal(cart,
                        false, out orderSubTotalDiscountAmount2, out orderSubTotalAppliedDiscount2,
                        out subTotalWithoutDiscountBase2, out subTotalWithDiscountBase2);
                    orderSubTotalExclTax = subTotalWithoutDiscountBase2;
                    orderSubTotalDiscountExclTax = orderSubTotalDiscountAmount2;
                }
                else
                {
                    orderSubTotalInclTax = initialOrder.OrderSubtotalInclTax;
                    orderSubTotalExclTax = initialOrder.OrderSubtotalExclTax;
                }

                //shipping info
                bool shoppingCartRequiresShipping = false;
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    shoppingCartRequiresShipping = cart.RequiresShipping();
                }
                else
                {
                    shoppingCartRequiresShipping = initialOrder.ShippingStatus != ShippingStatus.ShippingNotRequired;
                }
                Address shippingAddress = null;
                string shippingMethodName = "", shippingRateComputationMethodSystemName = "";
                bool pickUpInStore = false;
                if (shoppingCartRequiresShipping)
                {
                    if (!processPaymentRequest.IsRecurringPayment)
                    {
                        pickUpInStore = _shippingSettings.AllowPickUpInStore &&
                            customer.GetAttribute<bool>(SystemCustomerAttributeNames.SelectedPickUpInStore, processPaymentRequest.StoreId);

                        if (!pickUpInStore)
                        {
                            if (customer.ShippingAddress == null)
                                throw new NopException("Shipping address is not provided");

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

                            //clone shipping address
                            shippingAddress = (Address) customer.ShippingAddress.Clone();
                            if (shippingAddress.Country != null && !shippingAddress.Country.AllowsShipping)
                            {
                                throw new NopException(string.Format("Country '{0}' is not allowed for shipping", shippingAddress.Country.Name));
                            }
                        }

                        var shippingOption = customer.GetAttribute<ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, processPaymentRequest.StoreId);
                        if (shippingOption != null)
                        {
                            shippingMethodName = shippingOption.Name;
                            shippingRateComputationMethodSystemName = shippingOption.ShippingRateComputationMethodSystemName;
                        }
                    }
                    else
                    {
                        pickUpInStore = initialOrder.PickUpInStore;

                        if (!pickUpInStore)
                        {
                            if (initialOrder.ShippingAddress == null)
                                throw new NopException("Shipping address is not available");

                            //clone shipping address
                            shippingAddress = (Address) initialOrder.ShippingAddress.Clone();
                            if (shippingAddress.Country != null && !shippingAddress.Country.AllowsShipping)
                            {
                                throw new NopException(string.Format("Country '{0}' is not allowed for shipping", shippingAddress.Country.Name));
                            }
                        }

                        shippingMethodName = initialOrder.ShippingMethod;
                        shippingRateComputationMethodSystemName = initialOrder.ShippingRateComputationMethodSystemName;
                    }
                }

                //shipping total
                decimal? orderShippingTotalInclTax, orderShippingTotalExclTax = null;
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    decimal taxRate;
                    Discount shippingTotalDiscount;
                    orderShippingTotalInclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(cart, true, out taxRate, out shippingTotalDiscount);
                    orderShippingTotalExclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(cart, false);
                    if (!orderShippingTotalInclTax.HasValue || !orderShippingTotalExclTax.HasValue)
                        throw new NopException("Shipping total couldn't be calculated");

                    if (shippingTotalDiscount != null && !appliedDiscounts.ContainsDiscount(shippingTotalDiscount))
                        appliedDiscounts.Add(shippingTotalDiscount);
                }
                else
                {
                    orderShippingTotalInclTax = initialOrder.OrderShippingInclTax;
                    orderShippingTotalExclTax = initialOrder.OrderShippingExclTax;
                }

                //payment total
                decimal paymentAdditionalFeeInclTax, paymentAdditionalFeeExclTax;
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    decimal paymentAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, processPaymentRequest.PaymentMethodSystemName);
                    paymentAdditionalFeeInclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, true, customer);
                    paymentAdditionalFeeExclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, false, customer);
                }
                else
                {
                    paymentAdditionalFeeInclTax = initialOrder.PaymentMethodAdditionalFeeInclTax;
                    paymentAdditionalFeeExclTax = initialOrder.PaymentMethodAdditionalFeeExclTax;
                }

                //tax total
                decimal orderTaxTotal = decimal.Zero;
                string vatNumber = "", taxRates = "";
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    //tax amount
                    SortedDictionary<decimal, decimal> taxRatesDictionary;
                    orderTaxTotal = _orderTotalCalculationService.GetTaxTotal(cart, out taxRatesDictionary);

                    //VAT number
                    var customerVatStatus = (VatNumberStatus)customer.GetAttribute<int>(SystemCustomerAttributeNames.VatNumberStatusId);
                    if (_taxSettings.EuVatEnabled && customerVatStatus == VatNumberStatus.Valid)
                        vatNumber = customer.GetAttribute<string>(SystemCustomerAttributeNames.VatNumber);

                    //tax rates
                    foreach (var kvp in taxRatesDictionary)
                    {
                        var taxRate = kvp.Key;
                        var taxValue = kvp.Value;
                        taxRates += string.Format("{0}:{1};   ", taxRate.ToString(CultureInfo.InvariantCulture), taxValue.ToString(CultureInfo.InvariantCulture));
                    }
                }
                else
                {
                    orderTaxTotal = initialOrder.OrderTax;
                    //VAT number
                    vatNumber = initialOrder.VatNumber;
                }

                //order total (and applied discounts, gift cards, reward points)
                decimal? orderTotal = null;
                decimal orderDiscountAmount = decimal.Zero;
                List<AppliedGiftCard> appliedGiftCards = null;
                int redeemedRewardPoints = 0;
                decimal redeemedRewardPointsAmount = decimal.Zero;
                if (!processPaymentRequest.IsRecurringPayment)
                {
                    Discount orderAppliedDiscount;
                    orderTotal = _orderTotalCalculationService.GetShoppingCartTotal(cart,
                        out orderDiscountAmount, out orderAppliedDiscount, out appliedGiftCards,
                        out redeemedRewardPoints, out redeemedRewardPointsAmount);
                    if (!orderTotal.HasValue)
                        throw new NopException("Order total couldn't be calculated");

                    //discount history
                    if (orderAppliedDiscount != null && !appliedDiscounts.ContainsDiscount(orderAppliedDiscount))
                        appliedDiscounts.Add(orderAppliedDiscount);
                }
                else
                {
                    orderDiscountAmount = initialOrder.OrderDiscount;
                    orderTotal = initialOrder.OrderTotal;
                }
                processPaymentRequest.OrderTotal = orderTotal.Value;

                #endregion

                #region Payment workflow

                //skip payment workflow if order total equals zero
                bool skipPaymentWorkflow = orderTotal.Value == decimal.Zero;

                //payment workflow
                if (!skipPaymentWorkflow)
                {
                    var paymentMethod = _paymentService.LoadPaymentMethodBySystemName(processPaymentRequest.PaymentMethodSystemName);
                    if (paymentMethod == null)
                        throw new NopException("Payment method couldn't be loaded");

                    //ensure that payment method is active
                    if (!paymentMethod.IsPaymentMethodActive(_paymentSettings))
                        throw new NopException("Payment method is not active");
                }
                else
                    processPaymentRequest.PaymentMethodSystemName = "";

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

                //process payment
                ProcessPaymentResult processPaymentResult = null;
                if (!skipPaymentWorkflow)
                {
                    if (!processPaymentRequest.IsRecurringPayment)
                    {
                        if (isRecurringShoppingCart)
                        {
                            //recurring cart
                            var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName);
                            switch (recurringPaymentType)
                            {
                                case RecurringPaymentType.NotSupported:
                                    throw new NopException("Recurring payments are not supported by selected payment method");
                                case RecurringPaymentType.Manual:
                                case RecurringPaymentType.Automatic:
                                    processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest);
                                    break;
                                default:
                                    throw new NopException("Not supported recurring payment type");
                            }
                        }
                        else
                        {
                            //standard cart
                            processPaymentResult = _paymentService.ProcessPayment(processPaymentRequest);
                        }
                    }
                    else
                    {
                        if (isRecurringShoppingCart)
                        {
                            //Old credit card info
                            processPaymentRequest.CreditCardType = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardType) : "";
                            processPaymentRequest.CreditCardName = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardName) : "";
                            processPaymentRequest.CreditCardNumber = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardNumber) : "";
                            //MaskedCreditCardNumber
                            processPaymentRequest.CreditCardCvv2 = initialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(initialOrder.CardCvv2) : "";
                            try
                            {
                                processPaymentRequest.CreditCardExpireMonth = initialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(initialOrder.CardExpirationMonth)) : 0;
                                processPaymentRequest.CreditCardExpireYear = initialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(initialOrder.CardExpirationYear)) : 0;
                            }
                            catch {}

                            var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName);
                            switch (recurringPaymentType)
                            {
                                case RecurringPaymentType.NotSupported:
                                    throw new NopException("Recurring payments are not supported by selected payment method");
                                case RecurringPaymentType.Manual:
                                    processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest);
                                    break;
                                case RecurringPaymentType.Automatic:
                                    //payment is processed on payment gateway site
                                    processPaymentResult = new ProcessPaymentResult();
                                    break;
                                default:
                                    throw new NopException("Not supported recurring payment type");
                            }
                        }
                        else
                        {
                            throw new NopException("No recurring products");
                        }
                    }
                }
                else
                {
                    //payment is not required
                    if (processPaymentResult == null)
                        processPaymentResult = new ProcessPaymentResult();
                    processPaymentResult.NewPaymentStatus = PaymentStatus.Paid;
                }

                if (processPaymentResult == null)
                    throw new NopException("processPaymentResult is not available");

                #endregion

                if (processPaymentResult.Success)
                {

                    //save order in data storage
                    //uncomment this line to support transactions
                    //using (var scope = new System.Transactions.TransactionScope())
                    {
                        #region Save order details

                        var shippingStatus = ShippingStatus.NotYetShipped;
                        if (!shoppingCartRequiresShipping)
                            shippingStatus = ShippingStatus.ShippingNotRequired;

                        var order = new Order
                        {
                            StoreId = processPaymentRequest.StoreId,
                            OrderGuid = processPaymentRequest.OrderGuid,
                            CustomerId = customer.Id,
                            CustomerLanguageId = customerLanguage.Id,
                            CustomerTaxDisplayType = customerTaxDisplayType,
                            CustomerIp = _webHelper.GetCurrentIpAddress(),
                            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,
                            CheckoutAttributeDescription = checkoutAttributeDescription,
                            CheckoutAttributesXml = checkoutAttributesXml,
                            CustomerCurrencyCode = customerCurrencyCode,
                            CurrencyRate = customerCurrencyRate,
                            AffiliateId = affiliateId,
                            OrderStatus = OrderStatus.Pending,
                            AllowStoringCreditCardNumber = processPaymentResult.AllowStoringCreditCardNumber,
                            CardType = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardType) : string.Empty,
                            CardName = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardName) : string.Empty,
                            CardNumber = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardNumber) : string.Empty,
                            MaskedCreditCardNumber = _encryptionService.EncryptText(_paymentService.GetMaskedCreditCardNumber(processPaymentRequest.CreditCardNumber)),
                            CardCvv2 = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardCvv2) : string.Empty,
                            CardExpirationMonth = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireMonth.ToString()) : string.Empty,
                            CardExpirationYear = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireYear.ToString()) : string.Empty,
                            PaymentMethodSystemName = processPaymentRequest.PaymentMethodSystemName,
                            AuthorizationTransactionId = processPaymentResult.AuthorizationTransactionId,
                            AuthorizationTransactionCode = processPaymentResult.AuthorizationTransactionCode,
                            AuthorizationTransactionResult = processPaymentResult.AuthorizationTransactionResult,
                            CaptureTransactionId = processPaymentResult.CaptureTransactionId,
                            CaptureTransactionResult = processPaymentResult.CaptureTransactionResult,
                            SubscriptionTransactionId = processPaymentResult.SubscriptionTransactionId,
                            PaymentStatus = processPaymentResult.NewPaymentStatus,
                            PaidDateUtc = null,
                            BillingAddress = billingAddress,
                            ShippingAddress = shippingAddress,
                            ShippingStatus = shippingStatus,
                            ShippingMethod = shippingMethodName,
                            PickUpInStore = pickUpInStore,
                            ShippingRateComputationMethodSystemName = shippingRateComputationMethodSystemName,
                            CustomValuesXml = processPaymentRequest.SerializeCustomValues(),
                            VatNumber = vatNumber,
                            CreatedOnUtc = DateTime.UtcNow
                        };
                        _orderService.InsertOrder(order);

                        result.PlacedOrder = order;

                        if (!processPaymentRequest.IsRecurringPayment)
                        {
                            //move shopping cart items to order items
                            foreach (var sc in cart)
                            {
                                //prices
                                decimal taxRate;
                                Discount scDiscount;
                                decimal discountAmount;
                                decimal scUnitPrice = _priceCalculationService.GetUnitPrice(sc);
                                decimal scSubTotal = _priceCalculationService.GetSubTotal(sc, true, out discountAmount, out scDiscount);
                                decimal scUnitPriceInclTax = _taxService.GetProductPrice(sc.Product, scUnitPrice, true, customer, out taxRate);
                                decimal scUnitPriceExclTax = _taxService.GetProductPrice(sc.Product, scUnitPrice, false, customer, out taxRate);
                                decimal scSubTotalInclTax = _taxService.GetProductPrice(sc.Product, scSubTotal, true, customer, out taxRate);
                                decimal scSubTotalExclTax = _taxService.GetProductPrice(sc.Product, scSubTotal, false, customer, out taxRate);

                                decimal discountAmountInclTax = _taxService.GetProductPrice(sc.Product, discountAmount, true, customer, out taxRate);
                                decimal discountAmountExclTax = _taxService.GetProductPrice(sc.Product, discountAmount, false, customer, out taxRate);
                                if (scDiscount != null && !appliedDiscounts.ContainsDiscount(scDiscount))
                                    appliedDiscounts.Add(scDiscount);

                                //attributes
                                string attributeDescription = _productAttributeFormatter.FormatAttributes(sc.Product, sc.AttributesXml, customer);

                                var itemWeight = _shippingService.GetShoppingCartItemWeight(sc);

                                //save order item
                                var orderItem = new OrderItem
                                {
                                    OrderItemGuid = Guid.NewGuid(),
                                    Order = order,
                                    ProductId = sc.ProductId,
                                    UnitPriceInclTax = scUnitPriceInclTax,
                                    UnitPriceExclTax = scUnitPriceExclTax,
                                    PriceInclTax = scSubTotalInclTax,
                                    PriceExclTax = scSubTotalExclTax,
                                    OriginalProductCost = _priceCalculationService.GetProductCost(sc.Product, sc.AttributesXml),
                                    AttributeDescription = attributeDescription,
                                    AttributesXml = sc.AttributesXml,
                                    Quantity = sc.Quantity,
                                    DiscountAmountInclTax = discountAmountInclTax,
                                    DiscountAmountExclTax = discountAmountExclTax,
                                    DownloadCount = 0,
                                    IsDownloadActivated = false,
                                    LicenseDownloadId = 0,
                                    ItemWeight = itemWeight,
                                    RentalStartDateUtc = sc.RentalStartDateUtc,
                                    RentalEndDateUtc = sc.RentalEndDateUtc
                                };
                                order.OrderItems.Add(orderItem);
                                _orderService.UpdateOrder(order);

                                //gift cards
                                if (sc.Product.IsGiftCard)
                                {
                                    string giftCardRecipientName, giftCardRecipientEmail,
                                        giftCardSenderName, giftCardSenderEmail, giftCardMessage;
                                    _productAttributeParser.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
                                        {
                                            GiftCardType = sc.Product.GiftCardType,
                                            PurchasedWithOrderItem = orderItem,
                                            Amount = scUnitPriceExclTax,
                                            IsGiftCardActivated = false,
                                            GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(),
                                            RecipientName = giftCardRecipientName,
                                            RecipientEmail = giftCardRecipientEmail,
                                            SenderName = giftCardSenderName,
                                            SenderEmail = giftCardSenderEmail,
                                            Message = giftCardMessage,
                                            IsRecipientNotified = false,
                                            CreatedOnUtc = DateTime.UtcNow
                                        };
                                        _giftCardService.InsertGiftCard(gc);
                                    }
                                }

                                //inventory
                                _productService.AdjustInventory(sc.Product, -sc.Quantity, sc.AttributesXml);
                            }

                            //clear shopping cart
                            cart.ToList().ForEach(sci => _shoppingCartService.DeleteShoppingCartItem(sci, false));
                        }
                        else
                        {
                            //recurring payment
                            var initialOrderItems = initialOrder.OrderItems;
                            foreach (var orderItem in initialOrderItems)
                            {
                                //save item
                                var newOrderItem = new OrderItem
                                {
                                    OrderItemGuid = Guid.NewGuid(),
                                    Order = order,
                                    ProductId = orderItem.ProductId,
                                    UnitPriceInclTax = orderItem.UnitPriceInclTax,
                                    UnitPriceExclTax = orderItem.UnitPriceExclTax,
                                    PriceInclTax = orderItem.PriceInclTax,
                                    PriceExclTax = orderItem.PriceExclTax,
                                    OriginalProductCost = orderItem.OriginalProductCost,
                                    AttributeDescription = orderItem.AttributeDescription,
                                    AttributesXml = orderItem.AttributesXml,
                                    Quantity = orderItem.Quantity,
                                    DiscountAmountInclTax = orderItem.DiscountAmountInclTax,
                                    DiscountAmountExclTax = orderItem.DiscountAmountExclTax,
                                    DownloadCount = 0,
                                    IsDownloadActivated = false,
                                    LicenseDownloadId = 0,
                                    ItemWeight = orderItem.ItemWeight,
                                    RentalStartDateUtc = orderItem.RentalStartDateUtc,
                                    RentalEndDateUtc = orderItem.RentalEndDateUtc
                                };
                                order.OrderItems.Add(newOrderItem);
                                _orderService.UpdateOrder(order);

                                //gift cards
                                if (orderItem.Product.IsGiftCard)
                                {
                                    string giftCardRecipientName, giftCardRecipientEmail,
                                        giftCardSenderName, giftCardSenderEmail, giftCardMessage;
                                    _productAttributeParser.GetGiftCardAttribute(orderItem.AttributesXml,
                                        out giftCardRecipientName, out giftCardRecipientEmail,
                                        out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage);

                                    for (int i = 0; i < orderItem.Quantity; i++)
                                    {
                                        var gc = new GiftCard
                                        {
                                            GiftCardType = orderItem.Product.GiftCardType,
                                            PurchasedWithOrderItem = newOrderItem,
                                            Amount = orderItem.UnitPriceExclTax,
                                            IsGiftCardActivated = false,
                                            GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(),
                                            RecipientName = giftCardRecipientName,
                                            RecipientEmail = giftCardRecipientEmail,
                                            SenderName = giftCardSenderName,
                                            SenderEmail = giftCardSenderEmail,
                                            Message = giftCardMessage,
                                            IsRecipientNotified = false,
                                            CreatedOnUtc = DateTime.UtcNow
                                        };
                                        _giftCardService.InsertGiftCard(gc);
                                    }
                                }

                                //inventory
                                _productService.AdjustInventory(orderItem.Product, -orderItem.Quantity, orderItem.AttributesXml);
                            }
                        }

                        //discount usage history
                        if (!processPaymentRequest.IsRecurringPayment)
                            foreach (var discount in appliedDiscounts)
                            {
                                var duh = new DiscountUsageHistory
                                {
                                    Discount = discount,
                                    Order = order,
                                    CreatedOnUtc = DateTime.UtcNow
                                };
                                _discountService.InsertDiscountUsageHistory(duh);
                            }

                        //gift card usage history
                        if (!processPaymentRequest.IsRecurringPayment)
                            if (appliedGiftCards != null)
                                foreach (var agc in appliedGiftCards)
                                {
                                    decimal amountUsed = agc.AmountCanBeUsed;
                                    var gcuh = new GiftCardUsageHistory
                                    {
                                        GiftCard = agc.GiftCard,
                                        UsedWithOrder = order,
                                        UsedValue = amountUsed,
                                        CreatedOnUtc = DateTime.UtcNow
                                    };
                                    agc.GiftCard.GiftCardUsageHistory.Add(gcuh);
                                    _giftCardService.UpdateGiftCard(agc.GiftCard);
                                }

                        //reward points history
                        if (redeemedRewardPointsAmount > decimal.Zero)
                        {
                            customer.AddRewardPointsHistoryEntry(-redeemedRewardPoints,
                                string.Format(_localizationService.GetResource("RewardPoints.Message.RedeemedForOrder", order.CustomerLanguageId), order.Id),
                                order,
                                redeemedRewardPointsAmount);
                            _customerService.UpdateCustomer(customer);
                        }

                        //recurring orders
                        if (!processPaymentRequest.IsRecurringPayment && isRecurringShoppingCart)
                        {
                            //create recurring payment (the first payment)
                            var rp = new RecurringPayment
                            {
                                CycleLength = processPaymentRequest.RecurringCycleLength,
                                CyclePeriod = processPaymentRequest.RecurringCyclePeriod,
                                TotalCycles = processPaymentRequest.RecurringTotalCycles,
                                StartDateUtc = DateTime.UtcNow,
                                IsActive = true,
                                CreatedOnUtc = DateTime.UtcNow,
                                InitialOrder = order,
                            };
                            _orderService.InsertRecurringPayment(rp);

                            var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName);
                            switch (recurringPaymentType)
                            {
                                case RecurringPaymentType.NotSupported:
                                    {
                                        //not supported
                                    }
                                    break;
                                case RecurringPaymentType.Manual:
                                    {
                                        //first payment
                                        var rph = new RecurringPaymentHistory
                                        {
                                            RecurringPayment = rp,
                                            CreatedOnUtc = DateTime.UtcNow,
                                            OrderId = order.Id,
                                        };
                                        rp.RecurringPaymentHistory.Add(rph);
                                        _orderService.UpdateRecurringPayment(rp);
                                    }
                                    break;
                                case RecurringPaymentType.Automatic:
                                    {
                                        //will be created later (process is automated)
                                    }
                                    break;
                                default:
                                    break;
                            }
                        }

                        #endregion

                        #region Notifications & notes

                        //notes, messages
                        if (_workContext.OriginalCustomerIfImpersonated != null)
                        {
                            //this order is placed by a store administrator impersonating a customer
                            order.OrderNotes.Add(new OrderNote
                            {
                                Note = string.Format( "Order placed by a store owner ('{0}'. ID = {1}) impersonating the customer.",
                                    _workContext.OriginalCustomerIfImpersonated.Email, _workContext.OriginalCustomerIfImpersonated.Id),
                                DisplayToCustomer = false,
                                CreatedOnUtc = DateTime.UtcNow
                            });
                            _orderService.UpdateOrder(order);
                        }
                        else
                        {
                            order.OrderNotes.Add(new OrderNote
                            {
                                Note = "Order placed",
                                DisplayToCustomer = false,
                                CreatedOnUtc = DateTime.UtcNow
                            });
                            _orderService.UpdateOrder(order);
                        }

                        //send email notifications
                        int orderPlacedStoreOwnerNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedStoreOwnerNotification(order, _localizationSettings.DefaultAdminLanguageId);
                        if (orderPlacedStoreOwnerNotificationQueuedEmailId > 0)
                        {
                            order.OrderNotes.Add(new OrderNote
                            {
                                Note = string.Format("\"Order placed\" email (to store owner) has been queued. Queued email identifier: {0}.", orderPlacedStoreOwnerNotificationQueuedEmailId),
                                DisplayToCustomer = false,
                                CreatedOnUtc = DateTime.UtcNow
                            });
                            _orderService.UpdateOrder(order);
                        }

                        var orderPlacedAttachmentFilePath = _orderSettings.AttachPdfInvoiceToOrderPlacedEmail ?
                            _pdfService.PrintOrderToPdf(order, 0) : null;
                        var orderPlacedAttachmentFileName = _orderSettings.AttachPdfInvoiceToOrderPlacedEmail ?
                            "order.pdf" : null;
                        int orderPlacedCustomerNotificationQueuedEmailId = _workflowMessageService
                            .SendOrderPlacedCustomerNotification(order, order.CustomerLanguageId, orderPlacedAttachmentFilePath, orderPlacedAttachmentFileName);
                        if (orderPlacedCustomerNotificationQueuedEmailId > 0)
                        {
                            order.OrderNotes.Add(new OrderNote
                            {
                                Note = string.Format("\"Order placed\" email (to customer) has been queued. Queued email identifier: {0}.", orderPlacedCustomerNotificationQueuedEmailId),
                                DisplayToCustomer = false,
                                CreatedOnUtc = DateTime.UtcNow
                            });
                            _orderService.UpdateOrder(order);
                        }

                        var vendors = GetVendorsInOrder(order);
                        foreach (var vendor in vendors)
                        {
                            int orderPlacedVendorNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedVendorNotification(order, vendor, order.CustomerLanguageId);
                            if (orderPlacedVendorNotificationQueuedEmailId > 0)
                            {
                                order.OrderNotes.Add(new OrderNote
                                {
                                    Note = string.Format("\"Order placed\" email (to vendor) has been queued. Queued email identifier: {0}.", orderPlacedVendorNotificationQueuedEmailId),
                                    DisplayToCustomer = false,
                                    CreatedOnUtc = DateTime.UtcNow
                                });
                                _orderService.UpdateOrder(order);
                            }
                        }

                        //check order status
                        CheckOrderStatus(order);

                        //reset checkout data
                        if (!processPaymentRequest.IsRecurringPayment)
                            _customerService.ResetCheckoutData(customer, processPaymentRequest.StoreId, clearCouponCodes: true, clearCheckoutAttributes: true);

                        if (!processPaymentRequest.IsRecurringPayment)
                        {
                            _customerActivityService.InsertActivity(
                                "PublicStore.PlaceOrder",
                                _localizationService.GetResource("ActivityLog.PublicStore.PlaceOrder"),
                                order.Id);
                        }

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

                        //raise event
                        _eventPublisher.Publish(new OrderPlacedEvent(order));

                        if (order.PaymentStatus == PaymentStatus.Paid)
                        {
                            ProcessOrderPaid(order);
                        }
                        #endregion
                    }
                }
                else
                {
                    foreach (var paymentError in processPaymentResult.Errors)
                        result.AddError(string.Format("Payment error: {0}", paymentError));
                }
            }
            catch (Exception exc)
            {
                _logger.Error(exc.Message, exc);
                result.AddError(exc.Message);
            }

            #region Process errors

            string error = "";
            for (int i = 0; i < result.Errors.Count; i++)
            {
                error += string.Format("Error {0}: {1}", i + 1, result.Errors[i]);
                if (i != result.Errors.Count - 1)
                    error += ". ";
            }
            if (!String.IsNullOrEmpty(error))
            {
                //log it
                string logError = string.Format("Error while placing order. {0}", error);
                _logger.Error(logError);
            }

            #endregion

            return result;
        }
        public override ProcessPaymentRequest GetPaymentInfo(FormCollection form)
        {

            var strTransactionId = _httpContext.Request.Form["transactionId"];

            Guid transactionId;

            Guid.TryParse(strTransactionId, out transactionId);


            var paymentInfo = new ProcessPaymentRequest();
            paymentInfo.OrderGuid = transactionId;

            return paymentInfo;
        }
        /// <summary>
        /// Process recurring payment
        /// </summary>
        /// <param name="processPaymentRequest">Payment info required for an order processing</param>
        /// <returns>Process payment result</returns>
        public ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest)
        {
            var result = new ProcessPaymentResult();

            if (!processPaymentRequest.IsRecurringPayment)
            {
                var customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId);

                var subscription = new ARBSubscriptionType();
                var creditCard = new net.authorize.api.CreditCardType();

                subscription.name = processPaymentRequest.OrderGuid.ToString();

                creditCard.cardNumber = processPaymentRequest.CreditCardNumber;
                creditCard.expirationDate = processPaymentRequest.CreditCardExpireYear + "-" + processPaymentRequest.CreditCardExpireMonth; // required format for API is YYYY-MM
                creditCard.cardCode = processPaymentRequest.CreditCardCvv2;

                subscription.payment = new PaymentType();
                subscription.payment.Item = creditCard;

                subscription.billTo = new NameAndAddressType();
                subscription.billTo.firstName = customer.BillingAddress.FirstName;
                subscription.billTo.lastName = customer.BillingAddress.LastName;
                subscription.billTo.address = customer.BillingAddress.Address1;
                //subscription.billTo.address = customer.BillingAddress.Address1 + " " + customer.BillingAddress.Address2;
                subscription.billTo.city = customer.BillingAddress.City;
                if (customer.BillingAddress.StateProvince != null)
                {
                    subscription.billTo.state = customer.BillingAddress.StateProvince.Abbreviation;
                }
                subscription.billTo.zip = customer.BillingAddress.ZipPostalCode;

                if (customer.ShippingAddress != null)
                {
                    subscription.shipTo = new NameAndAddressType();
                    subscription.shipTo.firstName = customer.ShippingAddress.FirstName;
                    subscription.shipTo.lastName = customer.ShippingAddress.LastName;
                    subscription.shipTo.address = customer.ShippingAddress.Address1;
                    //subscription.shipTo.address = customer.ShippingAddress.Address1 + " " + customer.ShippingAddress.Address2;
                    subscription.shipTo.city = customer.ShippingAddress.City;
                    if (customer.ShippingAddress.StateProvince != null)
                    {
                        subscription.shipTo.state = customer.ShippingAddress.StateProvince.Abbreviation;
                    }
                    subscription.shipTo.zip = customer.ShippingAddress.ZipPostalCode;

                }

                subscription.customer = new CustomerType();
                subscription.customer.email = customer.BillingAddress.Email;
                subscription.customer.phoneNumber = customer.BillingAddress.PhoneNumber;

                subscription.order = new OrderType();
                subscription.order.description = "Recurring payment";

                // Create a subscription that is leng of specified occurrences and interval is amount of days ad runs

                subscription.paymentSchedule = new PaymentScheduleType();
                DateTime dtNow = DateTime.UtcNow;
                subscription.paymentSchedule.startDate = new DateTime(dtNow.Year, dtNow.Month, dtNow.Day);
                subscription.paymentSchedule.startDateSpecified = true;

                subscription.paymentSchedule.totalOccurrences = Convert.ToInt16(processPaymentRequest.RecurringTotalCycles);
                subscription.paymentSchedule.totalOccurrencesSpecified = true;

                var orderTotal = Math.Round(processPaymentRequest.OrderTotal, 2);
                subscription.amount = orderTotal;
                subscription.amountSpecified = true;

                // Interval can't be updated once a subscription is created.
                subscription.paymentSchedule.interval = new PaymentScheduleTypeInterval();
                switch (processPaymentRequest.RecurringCyclePeriod)
                {
                    case RecurringProductCyclePeriod.Days:
                        subscription.paymentSchedule.interval.length = Convert.ToInt16(processPaymentRequest.RecurringCycleLength);
                        subscription.paymentSchedule.interval.unit = ARBSubscriptionUnitEnum.days;
                        break;
                    case RecurringProductCyclePeriod.Weeks:
                        subscription.paymentSchedule.interval.length = Convert.ToInt16(processPaymentRequest.RecurringCycleLength * 7);
                        subscription.paymentSchedule.interval.unit = ARBSubscriptionUnitEnum.days;
                        break;
                    case RecurringProductCyclePeriod.Months:
                        subscription.paymentSchedule.interval.length = Convert.ToInt16(processPaymentRequest.RecurringCycleLength);
                        subscription.paymentSchedule.interval.unit = ARBSubscriptionUnitEnum.months;
                        break;
                    case RecurringProductCyclePeriod.Years:
                        subscription.paymentSchedule.interval.length = Convert.ToInt16(processPaymentRequest.RecurringCycleLength * 12);
                        subscription.paymentSchedule.interval.unit = ARBSubscriptionUnitEnum.months;
                        break;
                    default:
                        throw new NopException("Not supported cycle period");
                }

                using (var webService = new net.authorize.api.Service())
                {
                    if (_authorizeNetPaymentSettings.UseSandbox)
                        webService.Url = "https://apitest.authorize.net/soap/v1/Service.asmx";
                    else
                        webService.Url = "https://api.authorize.net/soap/v1/Service.asmx";

                    var authentication = PopulateMerchantAuthentication();
                    var response = webService.ARBCreateSubscription(authentication, subscription);

                    if (response.resultCode == MessageTypeEnum.Ok)
                    {
                        result.SubscriptionTransactionId = response.subscriptionId.ToString();
                        result.AuthorizationTransactionCode = response.resultCode.ToString();
                        result.AuthorizationTransactionResult = string.Format("Approved ({0}: {1})", response.resultCode.ToString(), response.subscriptionId.ToString());

                        if (_authorizeNetPaymentSettings.TransactMode == TransactMode.Authorize)
                        {
                            result.NewPaymentStatus = PaymentStatus.Authorized;
                        }
                        else
                        {
                            result.NewPaymentStatus = PaymentStatus.Paid;
                        }
                    }
                    else
                    {
                        result.AddError(string.Format("Error processing recurring payment. {0}", GetErrors(response)));
                    }
                }
            }

            return result;
        }
        /// <summary>
        /// Process a payment
        /// </summary>
        /// <param name="processPaymentRequest">Payment info required for an order processing</param>
        /// <returns>Process payment result</returns>
        public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest)
        {
            var result = new ProcessPaymentResult();

            var customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId);

            var webClient = new WebClient();
            var form = new NameValueCollection();
            form.Add("x_login", _authorizeNetPaymentSettings.LoginId);
            form.Add("x_tran_key", _authorizeNetPaymentSettings.TransactionKey);

            //we should not send "x_test_request" parameter. otherwise, the transaction won't be logged in the sandbox
            //if (_authorizeNetPaymentSettings.UseSandbox)
            //    form.Add("x_test_request", "TRUE");
            //else
            //    form.Add("x_test_request", "FALSE");

            form.Add("x_delim_data", "TRUE");
            form.Add("x_delim_char", "|");
            form.Add("x_encap_char", "");
            form.Add("x_version", GetApiVersion());
            form.Add("x_relay_response", "FALSE");
            form.Add("x_method", "CC");
            form.Add("x_currency_code", _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId).CurrencyCode);
            if (_authorizeNetPaymentSettings.TransactMode == TransactMode.Authorize)
                form.Add("x_type", "AUTH_ONLY");
            else if (_authorizeNetPaymentSettings.TransactMode == TransactMode.AuthorizeAndCapture)
                form.Add("x_type", "AUTH_CAPTURE");
            else
                throw new NopException("Not supported transaction mode");

            var orderTotal = Math.Round(processPaymentRequest.OrderTotal, 2);
            form.Add("x_amount", orderTotal.ToString("0.00", CultureInfo.InvariantCulture));
            form.Add("x_card_num", processPaymentRequest.CreditCardNumber);
            form.Add("x_exp_date", processPaymentRequest.CreditCardExpireMonth.ToString("D2") + processPaymentRequest.CreditCardExpireYear.ToString());
            form.Add("x_card_code", processPaymentRequest.CreditCardCvv2);
            form.Add("x_first_name", customer.BillingAddress.FirstName);
            form.Add("x_last_name", customer.BillingAddress.LastName);
            form.Add("x_email", customer.BillingAddress.Email);
            if (!string.IsNullOrEmpty(customer.BillingAddress.Company))
                form.Add("x_company", customer.BillingAddress.Company);
            form.Add("x_address", customer.BillingAddress.Address1);
            form.Add("x_city", customer.BillingAddress.City);
            if (customer.BillingAddress.StateProvince != null)
                form.Add("x_state", customer.BillingAddress.StateProvince.Abbreviation);
            form.Add("x_zip", customer.BillingAddress.ZipPostalCode);
            if (customer.BillingAddress.Country != null)
                form.Add("x_country", customer.BillingAddress.Country.TwoLetterIsoCode);
            //x_invoice_num is 20 chars maximum. hece we also pass x_description
            form.Add("x_invoice_num", processPaymentRequest.OrderGuid.ToString().Substring(0, 20));
            form.Add("x_description", string.Format("Full order #{0}", processPaymentRequest.OrderGuid));
            form.Add("x_customer_ip", _webHelper.GetCurrentIpAddress());

            var responseData = webClient.UploadValues(GetAuthorizeNetUrl(), form);
            var reply = Encoding.ASCII.GetString(responseData);

            if (!String.IsNullOrEmpty(reply))
            {
                string[] responseFields = reply.Split('|');
                switch (responseFields[0])
                {
                    case "1":
                        result.AuthorizationTransactionCode = string.Format("{0},{1}", responseFields[6], responseFields[4]);
                        result.AuthorizationTransactionResult = string.Format("Approved ({0}: {1})", responseFields[2], responseFields[3]);
                        result.AvsResult = responseFields[5];
                        //responseFields[38];
                        if (_authorizeNetPaymentSettings.TransactMode == TransactMode.Authorize)
                        {
                            result.NewPaymentStatus = PaymentStatus.Authorized;
                        }
                        else
                        {
                            result.NewPaymentStatus = PaymentStatus.Paid;
                        }
                        break;
                    case "2":
                        result.AddError(string.Format("Declined ({0}: {1})", responseFields[2], responseFields[3]));
                        break;
                    case "3":
                        result.AddError(string.Format("Error: {0}", reply));
                        break;

                }
            }
            else
            {
                result.AddError("Authorize.NET unknown error");
            }

            return result;
        }
Exemplo n.º 17
0
        /// <summary>
        /// Process a payment
        /// </summary>
        /// <param name="processPaymentRequest">Payment info required for an order processing</param>
        /// <returns>Process payment result</returns>
        public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest)
        {
            var result = new ProcessPaymentResult();
            
            var customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId);
            //var orderTotal = Math.Round(processPaymentRequest.OrderTotal, 2);

            StripeCreditCardInfo cc = new StripeCreditCardInfo();
            cc.CVC = processPaymentRequest.CreditCardCvv2;
            cc.FullName = customer.BillingAddress.FirstName + " " + customer.BillingAddress.LastName;
            
            cc.Number = processPaymentRequest.CreditCardNumber;
            cc.ExpirationMonth = processPaymentRequest.CreditCardExpireMonth;
            cc.ExpirationYear = processPaymentRequest.CreditCardExpireYear;
            cc.AddressLine1 = customer.BillingAddress.Address1;
            cc.AddressLine2 = customer.BillingAddress.Address2;
            if (customer.BillingAddress.Country.TwoLetterIsoCode.ToLower() == "us")
            {
                cc.StateOrProvince = customer.BillingAddress.StateProvince.Abbreviation;
            }
            else
            {
                cc.StateOrProvince = "ot";
            }

            cc.ZipCode = customer.BillingAddress.ZipPostalCode;
            
            cc.Country = customer.BillingAddress.Country.TwoLetterIsoCode;
            
            StripePayment payment = new StripePayment(_stripePaymentSettings.TransactionKey);
            
            try
            {
                StripeCharge charge = payment.Charge((int)(processPaymentRequest.OrderTotal * 100),
                    _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId).CurrencyCode.ToLower(), 
                    cc, string.Format("charge for {0} - {1}",
                    cc.FullName, processPaymentRequest.PurchaseOrderNumber));
            
                if (charge != null)
                {
                    result.NewPaymentStatus = PaymentStatus.Paid;
                    _stripePaymentSettings.TransactMode = TransactMode.AuthorizeAndCapture;
                    result.AuthorizationTransactionId = charge.ID;
                    result.AuthorizationTransactionResult = StripeChargeStatus.SUCCESS;
                    //need this for refund
                    result.AuthorizationTransactionCode = _stripePaymentSettings.TransactionKey;
                }
            }
            catch (StripeException stripeException)
            {
                result.AuthorizationTransactionResult = stripeException.StripeError.Message;
                result.AuthorizationTransactionCode = stripeException.StripeError.Code;
                result.AuthorizationTransactionId = "-1";
                result.AddError(string.Format("Declined ({0}: {1} - {2})", result.AuthorizationTransactionCode,
                    result.AuthorizationTransactionResult, _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId).CurrencyCode));
            }

            return result;
        }
 public override ProcessPaymentRequest GetPaymentInfo(FormCollection form)
 {
     var paymentInfo = new ProcessPaymentRequest();
     paymentInfo.PurchaseOrderNumber = form["PurchaseOrderNumber"];
     return paymentInfo;
 }
Exemplo n.º 19
0
        /// <summary>
        /// Process recurring payment
        /// </summary>
        /// <param name="processPaymentRequest">Payment info required for an order processing</param>
        /// <returns>Process payment result</returns>
        public ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest)
        {
            

            return null;
        }
 /// <summary>
 /// Process recurring payment
 /// </summary>
 /// <param name="processPaymentRequest">Payment info required for an order processing</param>
 /// <returns>Process payment result</returns>
 public virtual ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest)
 {
     if (processPaymentRequest.OrderTotal == decimal.Zero)
     {
         var result = new ProcessPaymentResult()
         {
             NewPaymentStatus = PaymentStatus.Paid
         };
         return result;
     }
     else
     {
         var paymentMethod = LoadPaymentMethodBySystemName(processPaymentRequest.PaymentMethodSystemName);
         if (paymentMethod == null)
             throw new NopException("Payment method couldn't be loaded");
         return paymentMethod.ProcessRecurringPayment(processPaymentRequest);
     }
 }
		public PlaceOrderResult PaypalOrderDetails(ProcessPaymentRequest processPaymentRequest)
		{
			//think about moving functionality of processing recurring orders (after the initial order was placed) to ProcessNextRecurringPayment() method
			if (processPaymentRequest == null)
				throw new ArgumentNullException("processPaymentRequest");



			var result = new PlaceOrderResult();
			try
			{
				//if (processPaymentRequest.OrderGuid == Guid.Empty)
				//	processPaymentRequest.OrderGuid = Guid.NewGuid();

				//prepare order details
				var details = PreparePlaceOrderDetails(processPaymentRequest);

				#region Payment workflow


				//process payment
				ProcessPaymentResult processPaymentResult = null;
				//skip payment workflow if order total equals zero
				var skipPaymentWorkflow = details.OrderTotal == decimal.Zero;
				if (!skipPaymentWorkflow)
				{
					var paymentMethod = _paymentService.LoadPaymentMethodBySystemName(processPaymentRequest.PaymentMethodSystemName);
					if (paymentMethod == null)
						throw new NopException("Payment method couldn't be loaded");

					//ensure that payment method is active
					if (!paymentMethod.IsPaymentMethodActive(_paymentSettings))
						throw new NopException("Payment method is not active");

					if (!processPaymentRequest.IsRecurringPayment)
					{
						if (details.IsRecurringShoppingCart)
						{
							//recurring cart
							var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName);
							switch (recurringPaymentType)
							{
								case RecurringPaymentType.NotSupported:
									throw new NopException("Recurring payments are not supported by selected payment method");
								case RecurringPaymentType.Manual:
								case RecurringPaymentType.Automatic:
									processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest);
									break;
								default:
									throw new NopException("Not supported recurring payment type");
							}
						}
						else
						{
							//standard cart
							processPaymentResult = _paymentService.ProcessPayment(processPaymentRequest);
						}
					}
					else
					{
						if (details.IsRecurringShoppingCart)
						{
							//Old credit card info
							processPaymentRequest.CreditCardType = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardType) : "";
							processPaymentRequest.CreditCardName = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardName) : "";
							processPaymentRequest.CreditCardNumber = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardNumber) : "";
							processPaymentRequest.CreditCardCvv2 = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardCvv2) : "";
							try
							{
								processPaymentRequest.CreditCardExpireMonth = details.InitialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(details.InitialOrder.CardExpirationMonth)) : 0;
								processPaymentRequest.CreditCardExpireYear = details.InitialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(details.InitialOrder.CardExpirationYear)) : 0;
							}
							catch { }

							var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName);
							switch (recurringPaymentType)
							{
								case RecurringPaymentType.NotSupported:
									throw new NopException("Recurring payments are not supported by selected payment method");
								case RecurringPaymentType.Manual:
									processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest);
									break;
								case RecurringPaymentType.Automatic:
									//payment is processed on payment gateway site
									processPaymentResult = new ProcessPaymentResult();
									break;
								default:
									throw new NopException("Not supported recurring payment type");
							}
						}
						else
						{
							throw new NopException("No recurring products");
						}
					}
				}
				else
				{
					//payment is not required
					if (processPaymentResult == null)
						processPaymentResult = new ProcessPaymentResult();
					processPaymentResult.NewPaymentStatus = PaymentStatus.Paid;
				}

				if (processPaymentResult == null)
					throw new NopException("processPaymentResult is not available");

				#endregion

				if (processPaymentResult.Success)
				{
					#region Save order details

					var order = new Order
					{
						StoreId = processPaymentRequest.StoreId,
						OrderGuid = processPaymentRequest.OrderGuid,
						CustomerId = details.Customer.Id,
						CustomerLanguageId = details.CustomerLanguage.Id,
						CustomerTaxDisplayType = details.CustomerTaxDisplayType,
						CustomerIp = _webHelper.GetCurrentIpAddress(),
						OrderSubtotalInclTax = details.OrderSubTotalInclTax,
						OrderSubtotalExclTax = details.OrderSubTotalExclTax,
						OrderSubTotalDiscountInclTax = details.OrderSubTotalDiscountInclTax,
						OrderSubTotalDiscountExclTax = details.OrderSubTotalDiscountExclTax,
						OrderShippingInclTax = details.OrderShippingTotalInclTax,
						OrderShippingExclTax = details.OrderShippingTotalExclTax,
						PaymentMethodAdditionalFeeInclTax = details.PaymentAdditionalFeeInclTax,
						PaymentMethodAdditionalFeeExclTax = details.PaymentAdditionalFeeExclTax,
						TaxRates = details.TaxRates,
						OrderTax = details.OrderTaxTotal,
						OrderTotal = details.OrderTotal,
						RefundedAmount = decimal.Zero,
						OrderDiscount = details.OrderDiscountAmount,
						CheckoutAttributeDescription = details.CheckoutAttributeDescription,
						CheckoutAttributesXml = details.CheckoutAttributesXml,
						CustomerCurrencyCode = details.CustomerCurrencyCode,
						CurrencyRate = details.CustomerCurrencyRate,
						AffiliateId = details.AffiliateId,
						OrderStatus = OrderStatus.Pending,
						AllowStoringCreditCardNumber = processPaymentResult.AllowStoringCreditCardNumber,
						CardType = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardType) : string.Empty,
						CardName = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardName) : string.Empty,
						CardNumber = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardNumber) : string.Empty,
						MaskedCreditCardNumber = _encryptionService.EncryptText(_paymentService.GetMaskedCreditCardNumber(processPaymentRequest.CreditCardNumber)),
						CardCvv2 = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardCvv2) : string.Empty,
						CardExpirationMonth = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireMonth.ToString()) : string.Empty,
						CardExpirationYear = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireYear.ToString()) : string.Empty,
						PaymentMethodSystemName = processPaymentRequest.PaymentMethodSystemName,
						AuthorizationTransactionId = processPaymentResult.AuthorizationTransactionId,
						AuthorizationTransactionCode = processPaymentResult.AuthorizationTransactionCode,
						AuthorizationTransactionResult = processPaymentResult.AuthorizationTransactionResult,
						CaptureTransactionId = processPaymentResult.CaptureTransactionId,
						CaptureTransactionResult = processPaymentResult.CaptureTransactionResult,
						SubscriptionTransactionId = processPaymentResult.SubscriptionTransactionId,
						PaymentStatus = processPaymentResult.NewPaymentStatus,
						PaidDateUtc = null,
						BillingAddress = details.BillingAddress,
						ShippingAddress = details.ShippingAddress,
						ShippingStatus = details.ShippingStatus,
						ShippingMethod = details.ShippingMethodName,
						PickUpInStore = details.PickUpInStore,
						ShippingRateComputationMethodSystemName = details.ShippingRateComputationMethodSystemName,
						CustomValuesXml = processPaymentRequest.SerializeCustomValues(),
						VatNumber = details.VatNumber,
						CreatedOnUtc = DateTime.UtcNow
					};
					//_orderService.InsertOrder(order);

					result.PlacedOrder = order;

					if (!processPaymentRequest.IsRecurringPayment)
					{
						//move shopping cart items to order items
						foreach (var sc in details.Cart)
						{
							//prices
							decimal taxRate;
							Discount scDiscount;
							decimal discountAmount;
							decimal scUnitPrice = _priceCalculationService.GetUnitPrice(sc);
							decimal scSubTotal = _priceCalculationService.GetSubTotal(sc, true, out discountAmount, out scDiscount);
							decimal scUnitPriceInclTax = _taxService.GetProductPrice(sc.Product, scUnitPrice, true, details.Customer, out taxRate);
							decimal scUnitPriceExclTax = _taxService.GetProductPrice(sc.Product, scUnitPrice, false, details.Customer, out taxRate);
							decimal scSubTotalInclTax = _taxService.GetProductPrice(sc.Product, scSubTotal, true, details.Customer, out taxRate);
							decimal scSubTotalExclTax = _taxService.GetProductPrice(sc.Product, scSubTotal, false, details.Customer, out taxRate);

							decimal discountAmountInclTax = _taxService.GetProductPrice(sc.Product, discountAmount, true, details.Customer, out taxRate);
							decimal discountAmountExclTax = _taxService.GetProductPrice(sc.Product, discountAmount, false, details.Customer, out taxRate);
							if (scDiscount != null && !details.AppliedDiscounts.ContainsDiscount(scDiscount))
								details.AppliedDiscounts.Add(scDiscount);

							//attributes
							string attributeDescription = _productAttributeFormatter.FormatAttributes(sc.Product, sc.AttributesXml, details.Customer);

							var itemWeight = _shippingService.GetShoppingCartItemWeight(sc);

							//save order item
							var orderItem = new OrderItem
							{
								OrderItemGuid = Guid.NewGuid(),
								Order = order,
								ProductId = sc.ProductId,
								UnitPriceInclTax = scUnitPriceInclTax,
								UnitPriceExclTax = scUnitPriceExclTax,
								PriceInclTax = scSubTotalInclTax,
								PriceExclTax = scSubTotalExclTax,
								OriginalProductCost = _priceCalculationService.GetProductCost(sc.Product, sc.AttributesXml),
								AttributeDescription = attributeDescription,
								AttributesXml = sc.AttributesXml,
								Quantity = sc.Quantity,
								DiscountAmountInclTax = discountAmountInclTax,
								DiscountAmountExclTax = discountAmountExclTax,
								DownloadCount = 0,
								IsDownloadActivated = false,
								LicenseDownloadId = 0,
								ItemWeight = itemWeight,
								RentalStartDateUtc = sc.RentalStartDateUtc,
								RentalEndDateUtc = sc.RentalEndDateUtc
							};
							order.OrderItems.Add(orderItem);
							//_orderService.UpdateOrder(order);

							//gift cards
							if (sc.Product.IsGiftCard)
							{
								string giftCardRecipientName, giftCardRecipientEmail,
									 giftCardSenderName, giftCardSenderEmail, giftCardMessage;
								_productAttributeParser.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
									{
										GiftCardType = sc.Product.GiftCardType,
										PurchasedWithOrderItem = orderItem,
										Amount = sc.Product.OverriddenGiftCardAmount.HasValue ? sc.Product.OverriddenGiftCardAmount.Value : scUnitPriceExclTax,
										IsGiftCardActivated = false,
										GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(),
										RecipientName = giftCardRecipientName,
										RecipientEmail = giftCardRecipientEmail,
										SenderName = giftCardSenderName,
										SenderEmail = giftCardSenderEmail,
										Message = giftCardMessage,
										IsRecipientNotified = false,
										CreatedOnUtc = DateTime.UtcNow
									};
									// _giftCardService.InsertGiftCard(gc);
								}
							}

							//inventory
							_productService.AdjustInventory(sc.Product, -sc.Quantity, sc.AttributesXml);
						}

						//clear shopping cart
						//details.Cart.ToList().ForEach(sci => _shoppingCartService.DeleteShoppingCartItem(sci, false));
					}
					else
					{
						//recurring payment
						var initialOrderItems = details.InitialOrder.OrderItems;
						foreach (var orderItem in initialOrderItems)
						{
							//save item
							var newOrderItem = new OrderItem
							{
								OrderItemGuid = Guid.NewGuid(),
								Order = order,
								ProductId = orderItem.ProductId,
								UnitPriceInclTax = orderItem.UnitPriceInclTax,
								UnitPriceExclTax = orderItem.UnitPriceExclTax,
								PriceInclTax = orderItem.PriceInclTax,
								PriceExclTax = orderItem.PriceExclTax,
								OriginalProductCost = orderItem.OriginalProductCost,
								AttributeDescription = orderItem.AttributeDescription,
								AttributesXml = orderItem.AttributesXml,
								Quantity = orderItem.Quantity,
								DiscountAmountInclTax = orderItem.DiscountAmountInclTax,
								DiscountAmountExclTax = orderItem.DiscountAmountExclTax,
								DownloadCount = 0,
								IsDownloadActivated = false,
								LicenseDownloadId = 0,
								ItemWeight = orderItem.ItemWeight,
								RentalStartDateUtc = orderItem.RentalStartDateUtc,
								RentalEndDateUtc = orderItem.RentalEndDateUtc
							};
							order.OrderItems.Add(newOrderItem);
							//_orderService.UpdateOrder(order);

							//gift cards
							if (orderItem.Product.IsGiftCard)
							{
								string giftCardRecipientName, giftCardRecipientEmail,
									 giftCardSenderName, giftCardSenderEmail, giftCardMessage;
								_productAttributeParser.GetGiftCardAttribute(orderItem.AttributesXml,
									 out giftCardRecipientName, out giftCardRecipientEmail,
									 out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage);

								for (int i = 0; i < orderItem.Quantity; i++)
								{
									var gc = new GiftCard
									{
										GiftCardType = orderItem.Product.GiftCardType,
										PurchasedWithOrderItem = newOrderItem,
										Amount = orderItem.UnitPriceExclTax,
										IsGiftCardActivated = false,
										GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(),
										RecipientName = giftCardRecipientName,
										RecipientEmail = giftCardRecipientEmail,
										SenderName = giftCardSenderName,
										SenderEmail = giftCardSenderEmail,
										Message = giftCardMessage,
										IsRecipientNotified = false,
										CreatedOnUtc = DateTime.UtcNow
									};
									//_giftCardService.InsertGiftCard(gc);
								}
							}

							//inventory
							_productService.AdjustInventory(orderItem.Product, -orderItem.Quantity, orderItem.AttributesXml);
						}
					}

					//discount usage history
					if (!processPaymentRequest.IsRecurringPayment)
						foreach (var discount in details.AppliedDiscounts)
						{
							var duh = new DiscountUsageHistory
							{
								Discount = discount,
								Order = order,
								CreatedOnUtc = DateTime.UtcNow
							};
							//_discountService.InsertDiscountUsageHistory(duh);
						}

					//gift card usage history
					if (!processPaymentRequest.IsRecurringPayment)
						if (details.AppliedGiftCards != null)
							foreach (var agc in details.AppliedGiftCards)
							{
								decimal amountUsed = agc.AmountCanBeUsed;
								var gcuh = new GiftCardUsageHistory
								{
									GiftCard = agc.GiftCard,
									UsedWithOrder = order,
									UsedValue = amountUsed,
									CreatedOnUtc = DateTime.UtcNow
								};
								agc.GiftCard.GiftCardUsageHistory.Add(gcuh);
								//_giftCardService.UpdateGiftCard(agc.GiftCard);
							}

					//reward points history
					if (details.RedeemedRewardPointsAmount > decimal.Zero)
					{
						_rewardPointService.AddRewardPointsHistoryEntry(details.Customer,
							 -details.RedeemedRewardPoints, order.StoreId,
							 string.Format(_localizationService.GetResource("RewardPoints.Message.RedeemedForOrder", order.CustomerLanguageId), order.Id),
							 order, details.RedeemedRewardPointsAmount);
						//_customerService.UpdateCustomer(details.Customer);
					}

					//recurring orders
					if (!processPaymentRequest.IsRecurringPayment && details.IsRecurringShoppingCart)
					{
						//create recurring payment (the first payment)
						var rp = new RecurringPayment
						{
							CycleLength = processPaymentRequest.RecurringCycleLength,
							CyclePeriod = processPaymentRequest.RecurringCyclePeriod,
							TotalCycles = processPaymentRequest.RecurringTotalCycles,
							StartDateUtc = DateTime.UtcNow,
							IsActive = true,
							CreatedOnUtc = DateTime.UtcNow,
							InitialOrder = order,
						};
						//_orderService.InsertRecurringPayment(rp);


						var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName);
						switch (recurringPaymentType)
						{
							case RecurringPaymentType.NotSupported:
								{
									//not supported
								}
								break;
							case RecurringPaymentType.Manual:
								{
									//first payment
									var rph = new RecurringPaymentHistory
									{
										RecurringPayment = rp,
										CreatedOnUtc = DateTime.UtcNow,
										OrderId = order.Id,
									};
									rp.RecurringPaymentHistory.Add(rph);
									_orderService.UpdateRecurringPayment(rp);
								}
								break;
							case RecurringPaymentType.Automatic:
								{
									//will be created later (process is automated)
								}
								break;
							default:
								break;
						}
					}

					#endregion

					#region Notifications & notes

					//notes, messages
					if (_workContext.OriginalCustomerIfImpersonated != null)
					{
						//this order is placed by a store administrator impersonating a customer
						order.OrderNotes.Add(new OrderNote
						{
							Note = string.Format("Order placed by a store owner ('{0}'. ID = {1}) impersonating the customer.",
								 _workContext.OriginalCustomerIfImpersonated.Email, _workContext.OriginalCustomerIfImpersonated.Id),
							DisplayToCustomer = false,
							CreatedOnUtc = DateTime.UtcNow
						});
						//_orderService.UpdateOrder(order);
					}
					else
					{
						order.OrderNotes.Add(new OrderNote
						{
							Note = "Order placed",
							DisplayToCustomer = false,
							CreatedOnUtc = DateTime.UtcNow
						});
						//_orderService.UpdateOrder(order);
					}


					//send email notifications
					//int orderPlacedStoreOwnerNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedStoreOwnerNotification(order, _localizationSettings.DefaultAdminLanguageId);
					//if (orderPlacedStoreOwnerNotificationQueuedEmailId > 0)
					//{
					//	order.OrderNotes.Add(new OrderNote
					//	{
					//		Note = string.Format("\"Order placed\" email (to store owner) has been queued. Queued email identifier: {0}.", orderPlacedStoreOwnerNotificationQueuedEmailId),
					//		DisplayToCustomer = false,
					//		CreatedOnUtc = DateTime.UtcNow
					//	});
					//	//_orderService.UpdateOrder(order);
					//}

					var orderPlacedAttachmentFilePath = _orderSettings.AttachPdfInvoiceToOrderPlacedEmail ?
						 _pdfService.PrintOrderToPdf(order, order.CustomerLanguageId) : null;
					//var orderPlacedAttachmentFileName = _orderSettings.AttachPdfInvoiceToOrderPlacedEmail ?
					//	 "order.pdf" : null;
					//int orderPlacedCustomerNotificationQueuedEmailId = _workflowMessageService
					//	 .SendOrderPlacedCustomerNotification(order, order.CustomerLanguageId, orderPlacedAttachmentFilePath, orderPlacedAttachmentFileName);
					//if (orderPlacedCustomerNotificationQueuedEmailId > 0)
					//{
					//	order.OrderNotes.Add(new OrderNote
					//	{
					//		Note = string.Format("\"Order placed\" email (to customer) has been queued. Queued email identifier: {0}.", orderPlacedCustomerNotificationQueuedEmailId),
					//		DisplayToCustomer = false,
					//		CreatedOnUtc = DateTime.UtcNow
					//	});
					//	//_orderService.UpdateOrder(order);
					//}

					//var vendors = GetVendorsInOrder(order);
					//foreach (var vendor in vendors)
					//{
					//	int orderPlacedVendorNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedVendorNotification(order, vendor, order.CustomerLanguageId);
					//	if (orderPlacedVendorNotificationQueuedEmailId > 0)
					//	{
					//		order.OrderNotes.Add(new OrderNote
					//		{
					//			Note = string.Format("\"Order placed\" email (to vendor) has been queued. Queued email identifier: {0}.", orderPlacedVendorNotificationQueuedEmailId),
					//			DisplayToCustomer = false,
					//			CreatedOnUtc = DateTime.UtcNow
					//		});
					//		//_orderService.UpdateOrder(order);
					//	}
					//}

					//check order status
					CheckOrderStatus(order);

					//reset checkout data
					//if (!processPaymentRequest.IsRecurringPayment)
					//	_customerService.ResetCheckoutData(details.Customer, processPaymentRequest.StoreId, clearCouponCodes: true, clearCheckoutAttributes: true);

					//if (!processPaymentRequest.IsRecurringPayment)
					//{
					//	_customerActivityService.InsertActivity(
					//		 "PublicStore.PlaceOrder",
					//		 _localizationService.GetResource("ActivityLog.PublicStore.PlaceOrder"),
					//		 order.Id);
					//}

					//raise event       
					//_eventPublisher.Publish(new OrderPlacedEvent(order));

					if (order.PaymentStatus == PaymentStatus.Paid)
					{
						ProcessOrderPaid(order);
					}
					#endregion
				}
				else
				{
					//payment errors
					foreach (var paymentError in processPaymentResult.Errors)
						result.AddError(string.Format(_localizationService.GetResource("Checkout.PaymentError"), paymentError));
				}
			}
			catch (Exception exc)
			{
				_logger.Error(exc.Message, exc);
				result.AddError(exc.Message);
			}

			#region Process errors

			string error = "";
			for (int i = 0; i < result.Errors.Count; i++)
			{
				error += string.Format("Error {0}: {1}", i + 1, result.Errors[i]);
				if (i != result.Errors.Count - 1)
					error += ". ";
			}
			if (!String.IsNullOrEmpty(error))
			{
				//log it
				string logError = string.Format("Error while placing order. {0}", error);
				var customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId);
				_logger.Error(logError, customer: customer);
			}

			#endregion

			return result;
		}
Exemplo n.º 22
0
        /// <summary>
        /// Process next recurring psayment
        /// </summary>
        /// <param name="recurringPayment">Recurring payment</param>
        public virtual void ProcessNextRecurringPayment(RecurringPayment recurringPayment)
        {
            if (recurringPayment == null)
                throw new ArgumentNullException("recurringPayment");
            try
            {
                if (!recurringPayment.IsActive)
                    throw new NopException("Recurring payment is not active");

                var initialOrder = recurringPayment.InitialOrder;
                if (initialOrder == null)
                    throw new NopException("Initial order could not be loaded");

                var customer = initialOrder.Customer;
                if (customer == null)
                    throw new NopException("Customer could not be loaded");

                var nextPaymentDate = recurringPayment.NextPaymentDate;
                if (!nextPaymentDate.HasValue)
                    throw new NopException("Next payment date could not be calculated");

                //payment info
                var paymentInfo = new ProcessPaymentRequest
                {
                    StoreId = initialOrder.StoreId,
                    CustomerId = customer.Id,
                    OrderGuid = Guid.NewGuid(),
                    IsRecurringPayment = true,
                    InitialOrderId = initialOrder.Id,
                    RecurringCycleLength = recurringPayment.CycleLength,
                    RecurringCyclePeriod = recurringPayment.CyclePeriod,
                    RecurringTotalCycles = recurringPayment.TotalCycles,
                };

                //place a new order
                var result = this.PlaceOrder(paymentInfo);
                if (result.Success)
                {
                    if (result.PlacedOrder == null)
                        throw new NopException("Placed order could not be loaded");

                    var rph = new RecurringPaymentHistory
                    {
                        RecurringPayment = recurringPayment,
                        CreatedOnUtc = DateTime.UtcNow,
                        OrderId = result.PlacedOrder.Id,
                    };
                    recurringPayment.RecurringPaymentHistory.Add(rph);
                    _orderService.UpdateRecurringPayment(recurringPayment);
                }
                else
                {
                    string error = "";
                    for (int i = 0; i < result.Errors.Count; i++)
                    {
                        error += string.Format("Error {0}: {1}", i, result.Errors[i]);
                        if (i != result.Errors.Count - 1)
                            error += ". ";
                    }
                    throw new NopException(error);
                }
            }
            catch (Exception exc)
            {
                _logger.Error(string.Format("Error while processing recurring order. {0}", exc.Message), exc);
                throw;
            }
        }
Exemplo n.º 23
0
        public ActionResult ConfirmOrder()
        {
            //validation
            var cart = _workContext.CurrentCustomer.ShoppingCartItems
                .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
                .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
                .ToList();
            if (cart.Count == 0)
                return RedirectToRoute("ShoppingCart");

            if (UseOnePageCheckout())
                return RedirectToRoute("CheckoutOnePage");

            if ((_workContext.CurrentCustomer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed))
                return new HttpUnauthorizedResult();

            //model
            var model = new CheckoutConfirmModel();
            try
            {
                var processPaymentRequest = _httpContext.Session["OrderPaymentInfo"] as ProcessPaymentRequest;
                if (processPaymentRequest == null)
                {
                    //Check whether payment workflow is required
                    if (IsPaymentWorkflowRequired(cart))
                        return RedirectToRoute("CheckoutPaymentInfo");
                    else
                        processPaymentRequest = new ProcessPaymentRequest();
                }

                //prevent 2 orders being placed within an X seconds time frame
                if (!IsMinimumOrderPlacementIntervalValid(_workContext.CurrentCustomer))
                    throw new Exception(_localizationService.GetResource("Checkout.MinOrderPlacementInterval"));

                //place order
                processPaymentRequest.StoreId = _storeContext.CurrentStore.Id;
                processPaymentRequest.CustomerId = _workContext.CurrentCustomer.Id;
                processPaymentRequest.PaymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute<string>(
                    SystemCustomerAttributeNames.SelectedPaymentMethod,
                    _genericAttributeService, _storeContext.CurrentStore.Id);
                var placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest);
                if (placeOrderResult.Success)
                {
                    _httpContext.Session["OrderPaymentInfo"] = null;
                    var postProcessPaymentRequest = new PostProcessPaymentRequest()
                    {
                        Order = placeOrderResult.PlacedOrder
                    };
                    _paymentService.PostProcessPayment(postProcessPaymentRequest);

                    if (_webHelper.IsRequestBeingRedirected || _webHelper.IsPostBeingDone)
                    {
                        //redirection or POST has been done in PostProcessPayment
                        return Content("Redirected");
                    }
                    else
                    {
                        return RedirectToRoute("CheckoutCompleted", new { orderId = placeOrderResult.PlacedOrder.Id });
                    }
                }
                else
                {
                    foreach (var error in placeOrderResult.Errors)
                        model.Warnings.Add(error);
                }
            }
            catch (Exception exc)
            {
                _logger.Warning(exc.Message, exc);
                model.Warnings.Add(exc.Message);
            }

            //If we got this far, something failed, redisplay form
            return View(model);
        }
        /// <summary>
        /// Process recurring payment
        /// </summary>
        /// <param name="processPaymentRequest">Payment info required for an order processing</param>
        /// <returns>Process payment result</returns>
        public ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest)
        {
            var result = new ProcessPaymentResult();

            var customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId);

            var req = new CreateRecurringPaymentsProfileReq();
            req.CreateRecurringPaymentsProfileRequest = new CreateRecurringPaymentsProfileRequestType();
            req.CreateRecurringPaymentsProfileRequest.Version = GetApiVersion();
            var details = new CreateRecurringPaymentsProfileRequestDetailsType();
            req.CreateRecurringPaymentsProfileRequest.CreateRecurringPaymentsProfileRequestDetails = details;

            details.CreditCard = new CreditCardDetailsType();
            details.CreditCard.CreditCardNumber = processPaymentRequest.CreditCardNumber;
            details.CreditCard.CreditCardType = GetPaypalCreditCardType(processPaymentRequest.CreditCardType);
            details.CreditCard.ExpMonthSpecified = true;
            details.CreditCard.ExpMonth = processPaymentRequest.CreditCardExpireMonth;
            details.CreditCard.ExpYearSpecified = true;
            details.CreditCard.ExpYear = processPaymentRequest.CreditCardExpireYear;
            details.CreditCard.CVV2 = processPaymentRequest.CreditCardCvv2;
            details.CreditCard.CardOwner = new PayerInfoType();
            details.CreditCard.CardOwner.PayerCountry = GetPaypalCountryCodeType(customer.BillingAddress.Country);
            details.CreditCard.CreditCardTypeSpecified = true;

            details.CreditCard.CardOwner.Address = new AddressType();
            details.CreditCard.CardOwner.Address.CountrySpecified = true;
            details.CreditCard.CardOwner.Address.Street1 = customer.BillingAddress.Address1;
            details.CreditCard.CardOwner.Address.Street2 = customer.BillingAddress.Address2;
            details.CreditCard.CardOwner.Address.CityName = customer.BillingAddress.City;
            if (customer.BillingAddress.StateProvince != null)
                details.CreditCard.CardOwner.Address.StateOrProvince = customer.BillingAddress.StateProvince.Abbreviation;
            else
                details.CreditCard.CardOwner.Address.StateOrProvince = "CA";
            details.CreditCard.CardOwner.Address.Country = GetPaypalCountryCodeType(customer.BillingAddress.Country);
            details.CreditCard.CardOwner.Address.PostalCode = customer.BillingAddress.ZipPostalCode;
            details.CreditCard.CardOwner.Payer = customer.BillingAddress.Email;
            details.CreditCard.CardOwner.PayerName = new PersonNameType();
            details.CreditCard.CardOwner.PayerName.FirstName = customer.BillingAddress.FirstName;
            details.CreditCard.CardOwner.PayerName.LastName = customer.BillingAddress.LastName;

            //start date
            details.RecurringPaymentsProfileDetails = new RecurringPaymentsProfileDetailsType();
            details.RecurringPaymentsProfileDetails.BillingStartDate = DateTime.UtcNow;
            details.RecurringPaymentsProfileDetails.ProfileReference = processPaymentRequest.OrderGuid.ToString();

            //schedule
            details.ScheduleDetails = new ScheduleDetailsType();
            details.ScheduleDetails.Description = "Recurring payment";
            details.ScheduleDetails.PaymentPeriod = new BillingPeriodDetailsType();
            details.ScheduleDetails.PaymentPeriod.Amount = new BasicAmountType();
            details.ScheduleDetails.PaymentPeriod.Amount.Value = Math.Round(processPaymentRequest.OrderTotal, 2).ToString("N", new CultureInfo("en-us"));
            details.ScheduleDetails.PaymentPeriod.Amount.currencyID = PaypalHelper.GetPaypalCurrency(_currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId));
            details.ScheduleDetails.PaymentPeriod.BillingFrequency = processPaymentRequest.RecurringCycleLength;
            switch (processPaymentRequest.RecurringCyclePeriod)
            {
                case RecurringProductCyclePeriod.Days:
                    details.ScheduleDetails.PaymentPeriod.BillingPeriod = BillingPeriodType.Day;
                    break;
                case RecurringProductCyclePeriod.Weeks:
                    details.ScheduleDetails.PaymentPeriod.BillingPeriod = BillingPeriodType.Week;
                    break;
                case RecurringProductCyclePeriod.Months:
                    details.ScheduleDetails.PaymentPeriod.BillingPeriod = BillingPeriodType.Month;
                    break;
                case RecurringProductCyclePeriod.Years:
                    details.ScheduleDetails.PaymentPeriod.BillingPeriod = BillingPeriodType.Year;
                    break;
                default:
                    throw new NopException("Not supported cycle period");
            }
            details.ScheduleDetails.PaymentPeriod.TotalBillingCycles = processPaymentRequest.RecurringTotalCycles;
            details.ScheduleDetails.PaymentPeriod.TotalBillingCyclesSpecified = true;



            using (var service2 = new PayPalAPIAASoapBinding())
            {
                if (!_paypalDirectPaymentSettings.UseSandbox)
                    service2.Url = "https://api-3t.paypal.com/2.0/";
                else
                    service2.Url = "https://api-3t.sandbox.paypal.com/2.0/";

                service2.RequesterCredentials = new CustomSecurityHeaderType();
                service2.RequesterCredentials.Credentials = new UserIdPasswordType();
                service2.RequesterCredentials.Credentials.Username = _paypalDirectPaymentSettings.ApiAccountName;
                service2.RequesterCredentials.Credentials.Password = _paypalDirectPaymentSettings.ApiAccountPassword;
                service2.RequesterCredentials.Credentials.Signature = _paypalDirectPaymentSettings.Signature;
                service2.RequesterCredentials.Credentials.Subject = "";

                CreateRecurringPaymentsProfileResponseType response = service2.CreateRecurringPaymentsProfile(req);

                string error = "";
                bool success = PaypalHelper.CheckSuccess(response, out error);
                if (success)
                {
                    result.NewPaymentStatus = PaymentStatus.Pending;
                    if (response.CreateRecurringPaymentsProfileResponseDetails != null)
                    {
                        result.SubscriptionTransactionId = response.CreateRecurringPaymentsProfileResponseDetails.ProfileID;
                    }
                }
                else
                {
                    result.AddError(error);
                }
            }

            return result;
        }
Exemplo n.º 25
0
        public ActionResult OpcConfirmOrder()
        {
            try
            {
                //validation
                var cart = _workContext.CurrentCustomer.ShoppingCartItems
                    .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
                    .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
                    .ToList();
                if (cart.Count == 0)
                    throw new Exception("Your cart is empty");

                if (!UseOnePageCheckout())
                    throw new Exception("One page checkout is disabled");

                if ((_workContext.CurrentCustomer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed))
                    throw new Exception("Anonymous checkout is not allowed");

                //prevent 2 orders being placed within an X seconds time frame
                if (!IsMinimumOrderPlacementIntervalValid(_workContext.CurrentCustomer))
                    throw new Exception(_localizationService.GetResource("Checkout.MinOrderPlacementInterval"));

                //place order
                var processPaymentRequest = _httpContext.Session["OrderPaymentInfo"] as ProcessPaymentRequest;
                if (processPaymentRequest == null)
                {
                    //Check whether payment workflow is required
                    if (IsPaymentWorkflowRequired(cart))
                    {
                        throw new Exception("Payment information is not entered");
                    }
                    else
                        processPaymentRequest = new ProcessPaymentRequest();
                }

                processPaymentRequest.StoreId = _storeContext.CurrentStore.Id;
                processPaymentRequest.CustomerId = _workContext.CurrentCustomer.Id;
                processPaymentRequest.PaymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute<string>(
                    SystemCustomerAttributeNames.SelectedPaymentMethod,
                    _genericAttributeService, _storeContext.CurrentStore.Id);
                var placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest);
                if (placeOrderResult.Success)
                {
                    _httpContext.Session["OrderPaymentInfo"] = null;
                    var postProcessPaymentRequest = new PostProcessPaymentRequest()
                    {
                        Order = placeOrderResult.PlacedOrder
                    };

                    var paymentMethod = _paymentService.LoadPaymentMethodBySystemName(placeOrderResult.PlacedOrder.PaymentMethodSystemName);
                    if (paymentMethod != null)
                    {
                        if (paymentMethod.PaymentMethodType == PaymentMethodType.Redirection)
                        {
                            //Redirection will not work because it's AJAX request.
                            //That's why we don't process it here (we redirect a user to another page where he'll be redirected)

                            //redirect
                            return Json(new { redirect = string.Format("{0}checkout/OpcCompleteRedirectionPayment", _webHelper.GetStoreLocation()) });
                        }
                        else
                        {
                            _paymentService.PostProcessPayment(postProcessPaymentRequest);
                            //success
                            return Json(new { success = 1 });
                        }
                    }
                    else
                    {
                        //payment method could be null if order total is 0

                        //success
                        return Json(new { success = 1 });
                    }
                }
                else
                {
                    //error
                    var confirmOrderModel = new CheckoutConfirmModel();
                    foreach (var error in placeOrderResult.Errors)
                        confirmOrderModel.Warnings.Add(error);

                    return Json(new
                        {
                            update_section = new UpdateSectionJsonModel()
                            {
                                name = "confirm-order",
                                html = this.RenderPartialViewToString("OpcConfirmOrder", confirmOrderModel)
                            },
                            goto_section = "confirm_order"
                        });
                }
            }
            catch (Exception exc)
            {
                _logger.Warning(exc.Message, exc, _workContext.CurrentCustomer);
                return Json(new { error = 1, message = exc.Message });
            }
        }
Exemplo n.º 26
0
        /// <summary>
        /// Process recurring payment
        /// </summary>
        /// <param name="processPaymentRequest">Payment info required for an order processing</param>
        /// <returns>Process payment result</returns>
        public ProcessPaymentResult ProcessRecurringPayment(ProcessPaymentRequest processPaymentRequest)
        {
            var result = new ProcessPaymentResult();

            var customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId);

            var req = new CreateRecurringPaymentsProfileReq();
            req.CreateRecurringPaymentsProfileRequest = new CreateRecurringPaymentsProfileRequestType();
            req.CreateRecurringPaymentsProfileRequest.Version = GetApiVersion();
            var details = new CreateRecurringPaymentsProfileRequestDetailsType();
            req.CreateRecurringPaymentsProfileRequest.CreateRecurringPaymentsProfileRequestDetails = details;

            details.CreditCard = new CreditCardDetailsType();
            details.CreditCard.CreditCardNumber = processPaymentRequest.CreditCardNumber;
            details.CreditCard.CreditCardType = GetPaypalCreditCardType(processPaymentRequest.CreditCardType);
            details.CreditCard.ExpMonth = processPaymentRequest.CreditCardExpireMonth;
            details.CreditCard.ExpYear = processPaymentRequest.CreditCardExpireYear;
            details.CreditCard.CVV2 = processPaymentRequest.CreditCardCvv2;
            details.CreditCard.CardOwner = new PayerInfoType();

            var country = EngineContext.Current.Resolve<ICountryService>().GetCountryById(customer.BillingAddress.CountryId);
            details.CreditCard.CardOwner.PayerCountry = GetPaypalCountryCodeType(country);

            details.CreditCard.CardOwner.Address = new AddressType();
            details.CreditCard.CardOwner.Address.Street1 = customer.BillingAddress.Address1;
            details.CreditCard.CardOwner.Address.Street2 = customer.BillingAddress.Address2;
            details.CreditCard.CardOwner.Address.CityName = customer.BillingAddress.City;
            if (customer.BillingAddress.StateProvinceId != 0)
            {
                var state = EngineContext.Current.Resolve<IStateProvinceService>().GetStateProvinceById(customer.BillingAddress.StateProvinceId);
                details.CreditCard.CardOwner.Address.StateOrProvince = state.Abbreviation;
            }
            else
                details.CreditCard.CardOwner.Address.StateOrProvince = "CA";
            details.CreditCard.CardOwner.Address.Country = GetPaypalCountryCodeType(country);
            details.CreditCard.CardOwner.Address.PostalCode = customer.BillingAddress.ZipPostalCode;
            details.CreditCard.CardOwner.Payer = customer.BillingAddress.Email;
            details.CreditCard.CardOwner.PayerName = new PersonNameType();
            details.CreditCard.CardOwner.PayerName.FirstName = customer.BillingAddress.FirstName;
            details.CreditCard.CardOwner.PayerName.LastName = customer.BillingAddress.LastName;

            //start date
            details.RecurringPaymentsProfileDetails = new RecurringPaymentsProfileDetailsType();
            details.RecurringPaymentsProfileDetails.BillingStartDate = DateTime.UtcNow.ToString("s", CultureInfo.InvariantCulture);
            details.RecurringPaymentsProfileDetails.ProfileReference = processPaymentRequest.OrderGuid.ToString();

            //schedule
            details.ScheduleDetails = new ScheduleDetailsType();
            details.ScheduleDetails.Description = "Recurring payment";
            details.ScheduleDetails.PaymentPeriod = new BillingPeriodDetailsType();
            details.ScheduleDetails.PaymentPeriod.Amount = new BasicAmountType();
            details.ScheduleDetails.PaymentPeriod.Amount.value = Math.Round(processPaymentRequest.OrderTotal, 2).ToString("N", new CultureInfo("en-us"));
            details.ScheduleDetails.PaymentPeriod.Amount.currencyID = PaypalHelper.GetPaypalCurrency(_currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId));
            details.ScheduleDetails.PaymentPeriod.BillingFrequency = processPaymentRequest.RecurringCycleLength;
            switch (processPaymentRequest.RecurringCyclePeriod)
            {
                case RecurringProductCyclePeriod.Days:
                    details.ScheduleDetails.PaymentPeriod.BillingPeriod = BillingPeriodType.DAY;
                    break;
                case RecurringProductCyclePeriod.Weeks:
                    details.ScheduleDetails.PaymentPeriod.BillingPeriod = BillingPeriodType.WEEK;
                    break;
                case RecurringProductCyclePeriod.Months:
                    details.ScheduleDetails.PaymentPeriod.BillingPeriod = BillingPeriodType.MONTH;
                    break;
                case RecurringProductCyclePeriod.Years:
                    details.ScheduleDetails.PaymentPeriod.BillingPeriod = BillingPeriodType.YEAR;
                    break;
                default:
                    throw new NopException("Not supported cycle period");
            }
            details.ScheduleDetails.PaymentPeriod.TotalBillingCycles = processPaymentRequest.RecurringTotalCycles;

            var service = GetService();
            CreateRecurringPaymentsProfileResponseType response = service.CreateRecurringPaymentsProfile(req);

            string error;
            bool success = PaypalHelper.CheckSuccess(response, out error);
            if (success)
            {
                result.NewPaymentStatus = PaymentStatus.Pending;
                if (response.CreateRecurringPaymentsProfileResponseDetails != null)
                {
                    result.SubscriptionTransactionId = response.CreateRecurringPaymentsProfileResponseDetails.ProfileID;
                }
            }
            else
            {
                result.AddError(error);
            }
            return result;
        }
 /// <summary>
 /// Process a payment
 /// </summary>
 /// <param name="processPaymentRequest">Payment info required for an order processing</param>
 /// <returns>Process payment result</returns>
 public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest)
 {
     var result = new ProcessPaymentResult();
     result.NewPaymentStatus = PaymentStatus.Pending;
     result.AuthorizationTransactionId = processPaymentRequest.GoogleOrderNumber;
     return result;
 }
 public override ProcessPaymentRequest GetPaymentInfo(FormCollection form)
 {
     var paymentInfo = new ProcessPaymentRequest();
     return paymentInfo;
 }
        private void ProcessNewOrderNotification(string xmlData)
        {
            try
            {
                var newOrderNotification = (NewOrderNotification)EncodeHelper.Deserialize(xmlData, typeof(NewOrderNotification));
                string googleOrderNumber = newOrderNotification.googleordernumber;

                XmlNode customerInfo = newOrderNotification.shoppingcart.merchantprivatedata.Any[0];
                int customerId = Convert.ToInt32(customerInfo.Attributes["CustomerID"].Value);
                //int customerLanguageId = Convert.ToInt32(customerInfo.Attributes["CustomerLanguageID"].Value);
                //int customerCurrencyId = Convert.ToInt32(customerInfo.Attributes["CustomerCurrencyID"].Value);
                var customer = _customerService.GetCustomerById(customerId);

                if (customer == null)
                {
                    LogMessage("Could not load a customer");
                    return;
                }

                var cart = customer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart).ToList();

                _workContext.CurrentCustomer = customer;

                if (cart.Count == 0)
                {
                    LogMessage("Cart is empty");
                    return;
                }

                //validate cart
                foreach (var sci in cart)
                {
                    bool ok = false;
                    foreach (Item item in newOrderNotification.shoppingcart.items)
                    {
                        if (!String.IsNullOrEmpty(item.merchantitemid))
                        {
                            if ((Convert.ToInt32(item.merchantitemid) == sci.Id) && (item.quantity == sci.Quantity))
                            {
                                ok = true;
                                break;
                            }
                        }
                    }

                    if (!ok)
                    {
                        LogMessage(string.Format("Shopping Cart item has been changed. {0}. {1}", sci.Id, sci.Quantity));
                        return;
                    }
                }

                string[] billingFullname = newOrderNotification.buyerbillingaddress.contactname.Trim().Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
                string billingFirstName = billingFullname[0];
                string billingLastName = string.Empty;
                if (billingFullname.Length > 1)
                    billingLastName = billingFullname[1];
                string billingEmail = newOrderNotification.buyerbillingaddress.email.Trim();
                string billingAddress1 = newOrderNotification.buyerbillingaddress.address1.Trim();
                string billingAddress2 = newOrderNotification.buyerbillingaddress.address2.Trim();
                string billingPhoneNumber = newOrderNotification.buyerbillingaddress.phone.Trim();
                string billingCity = newOrderNotification.buyerbillingaddress.city.Trim();
                int? billingStateProvinceId = null;
                var billingStateProvince = _stateProvinceService.GetStateProvinceByAbbreviation(newOrderNotification.buyerbillingaddress.region.Trim());
                if (billingStateProvince != null)
                    billingStateProvinceId = billingStateProvince.Id;
                string billingZipPostalCode = newOrderNotification.buyerbillingaddress.postalcode.Trim();
                int? billingCountryId = null;
                var billingCountry = _countryService.GetCountryByTwoLetterIsoCode(newOrderNotification.buyerbillingaddress.countrycode.Trim());
                if (billingCountry != null)
                    billingCountryId = billingCountry.Id;

                var billingAddress = customer.Addresses.ToList().FindAddress(
                    billingFirstName, billingLastName, billingPhoneNumber,
                    billingEmail, string.Empty, string.Empty, billingAddress1, billingAddress2, billingCity,
                    billingStateProvinceId, billingZipPostalCode, billingCountryId);

                if (billingAddress == null)
                {
                    billingAddress = new Core.Domain.Common.Address()
                    {
                        FirstName = billingFirstName,
                        LastName = billingLastName,
                        PhoneNumber = billingPhoneNumber,
                        Email = billingEmail,
                        Address1 = billingAddress1,
                        Address2 = billingAddress2,
                        City = billingCity,
                        StateProvinceId = billingStateProvinceId,
                        ZipPostalCode = billingZipPostalCode,
                        CountryId = billingCountryId,
                        CreatedOnUtc = DateTime.UtcNow,
                    };
                    customer.Addresses.Add(billingAddress);
                }
                //set default billing address
                customer.BillingAddress = billingAddress;
                _customerService.UpdateCustomer(customer);

                _genericAttributeService.SaveAttribute<ShippingOption>(customer, SystemCustomerAttributeNames.LastShippingOption, null);

                bool shoppingCartRequiresShipping = cart.RequiresShipping();
                if (shoppingCartRequiresShipping)
                {
                    string[] shippingFullname = newOrderNotification.buyershippingaddress.contactname.Trim().Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
                    string shippingFirstName = shippingFullname[0];
                    string shippingLastName = string.Empty;
                    if (shippingFullname.Length > 1)
                        shippingLastName = shippingFullname[1];
                    string shippingEmail = newOrderNotification.buyershippingaddress.email.Trim();
                    string shippingAddress1 = newOrderNotification.buyershippingaddress.address1.Trim();
                    string shippingAddress2 = newOrderNotification.buyershippingaddress.address2.Trim();
                    string shippingPhoneNumber = newOrderNotification.buyershippingaddress.phone.Trim();
                    string shippingCity = newOrderNotification.buyershippingaddress.city.Trim();
                    int? shippingStateProvinceId = null;
                    var shippingStateProvince = _stateProvinceService.GetStateProvinceByAbbreviation(newOrderNotification.buyershippingaddress.region.Trim());
                    if (shippingStateProvince != null)
                        shippingStateProvinceId = shippingStateProvince.Id;
                    int? shippingCountryId = null;
                    string shippingZipPostalCode = newOrderNotification.buyershippingaddress.postalcode.Trim();
                    var shippingCountry = _countryService.GetCountryByTwoLetterIsoCode(newOrderNotification.buyershippingaddress.countrycode.Trim());
                    if (shippingCountry != null)
                        shippingCountryId = shippingCountry.Id;

                    var shippingAddress = customer.Addresses.ToList().FindAddress(
                        shippingFirstName, shippingLastName, shippingPhoneNumber,
                        shippingEmail, string.Empty, string.Empty,
                        shippingAddress1, shippingAddress2, shippingCity,
                        shippingStateProvinceId, shippingZipPostalCode, shippingCountryId);
                    if (shippingAddress == null)
                    {
                        shippingAddress = new Core.Domain.Common.Address()
                        {
                            FirstName = shippingFirstName,
                            LastName = shippingLastName,
                            PhoneNumber = shippingPhoneNumber,
                            Email = shippingEmail,
                            Address1 = shippingAddress1,
                            Address2 = shippingAddress2,
                            City = shippingCity,
                            StateProvinceId = shippingStateProvinceId,
                            ZipPostalCode = shippingZipPostalCode,
                            CountryId = shippingCountryId,
                            CreatedOnUtc = DateTime.UtcNow,
                        };
                        customer.Addresses.Add(shippingAddress);
                    }
                    //set default shipping address
                    customer.ShippingAddress = shippingAddress;
                    _customerService.UpdateCustomer(customer);

                    if (newOrderNotification.orderadjustment != null &&
                        newOrderNotification.orderadjustment.shipping != null &&
                        newOrderNotification.orderadjustment.shipping.Item != null)
                    {
                        var shippingMethod = (FlatRateShippingAdjustment)newOrderNotification.orderadjustment.shipping.Item;
                        var shippingOption = new ShippingOption();
                        shippingOption.Name = shippingMethod.shippingname;
                        shippingOption.Rate = shippingMethod.shippingcost.Value;
                        _genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.LastShippingOption, shippingOption);
                    }
                }

                //customer.LastCalculatedTax = decimal.Zero;

                var paymentInfo = new ProcessPaymentRequest()
                {
                    PaymentMethodSystemName = "Payments.GoogleCheckout",
                    CustomerId = customer.Id,
                    GoogleOrderNumber = googleOrderNumber
                };
                //TODO set customer language and currency
                //paymentInfo.CustomerLanguage = IoC.Resolve<ILanguageService>().GetLanguageById(CustomerLanguageID);
                //paymentInfo.CustomerCurrency = IoC.Resolve<ICurrencyService>().GetCurrencyById(CustomerCurrencyID);
                var result = _orderProcessingService.PlaceOrder(paymentInfo);
                if (!result.Success)
                {
                    LogMessage("new-order-notification received. CreateOrder() error: Order Number " + googleOrderNumber + ". " + result);
                    return;
                }

                var order = result.PlacedOrder;
                if (order != null)
                {
                    LogMessage("new-order-notification received and saved: Order Number " + order.Id);
                }
            }
            catch (Exception exc)
            {
                LogMessage("processNewOrderNotification Exception: " + exc.Message + ": " + exc.StackTrace);
            }
        }
 /// <summary>
 /// Process a payment
 /// </summary>
 /// <param name="processPaymentRequest">Payment info required for an order processing</param>
 /// <returns>Process payment result</returns>
 public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest)
 {
     var result = new ProcessPaymentResult();
     result.NewPaymentStatus = PaymentStatus.Pending;
     return result;
 }
        /// <summary>
        /// Process recurring payment
        /// </summary>
        /// <param name="processPaymentRequest">Payment info required for an order processing</param>
        /// <returns>Process payment result</returns>
        public virtual async Task <ProcessPaymentResult> ProcessRecurringPaymentAsync(ProcessPaymentRequest processPaymentRequest)
        {
            if (processPaymentRequest.OrderTotal == decimal.Zero)
            {
                var result = new ProcessPaymentResult
                {
                    NewPaymentStatus = PaymentStatus.Paid
                };
                return(result);
            }

            var customer = await _customerService.GetCustomerByIdAsync(processPaymentRequest.CustomerId);

            var paymentMethod = await _paymentPluginManager
                                .LoadPluginBySystemNameAsync(processPaymentRequest.PaymentMethodSystemName, customer, processPaymentRequest.StoreId)
                                ?? throw new NopException("Payment method couldn't be loaded");

            return(await paymentMethod.ProcessRecurringPaymentAsync(processPaymentRequest));
        }