private string GetPaymentFee(Provider <IPaymentMethod> provider, List <OrganizedShoppingCartItem> cart) { var paymentMethodAdditionalFee = provider.Value.GetAdditionalHandlingFee(cart); var rateBase = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, Services.WorkContext.CurrentCustomer); var rate = _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, Services.WorkContext.WorkingCurrency); if (rate != decimal.Zero) { return(_priceFormatter.FormatPaymentMethodAdditionalFee(rate, true)); } return(""); }
private async Task PreparePayment(OrderTotalsModel model, GetOrderTotals request) { var paymentMethodSystemName = request.Customer.GetUserFieldFromEntity <string>( SystemCustomerFieldNames.SelectedPaymentMethod, request.Store.Id); decimal paymentMethodAdditionalFee = await _paymentService.GetAdditionalHandlingFee(request.Cart, paymentMethodSystemName); decimal paymentMethodAdditionalFeeWithTaxBase = (await _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, request.Customer)).paymentPrice; if (paymentMethodAdditionalFeeWithTaxBase > decimal.Zero) { model.PaymentMethodAdditionalFee = _priceFormatter.FormatPaymentMethodAdditionalFee(paymentMethodAdditionalFeeWithTaxBase); } }
private async Task PreparePayment(OrderTotalsModel model, GetOrderTotals request) { var paymentMethodSystemName = request.Customer.GetAttributeFromEntity <string>( SystemCustomerAttributeNames.SelectedPaymentMethod, request.Store.Id); decimal paymentMethodAdditionalFee = await _paymentService.GetAdditionalHandlingFee(request.Cart, paymentMethodSystemName); decimal paymentMethodAdditionalFeeWithTaxBase = (await _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, request.Customer)).paymentPrice; if (paymentMethodAdditionalFeeWithTaxBase > decimal.Zero) { decimal paymentMethodAdditionalFeeWithTax = await _currencyService.ConvertFromPrimaryStoreCurrency(paymentMethodAdditionalFeeWithTaxBase, request.Currency); model.PaymentMethodAdditionalFee = _priceFormatter.FormatPaymentMethodAdditionalFee(paymentMethodAdditionalFeeWithTax, true); } }
/// <summary> /// Create item for payment method additional fee /// </summary> /// <param name="shoppingCart">Shopping cart</param> /// <param name="customer">Customer</param> /// <returns>PayPal item</returns> protected Item CreateItemForPaymentAdditionalFee(IList <ShoppingCartItem> shoppingCart, Customer customer) { //var processor = _paymentPluginManager.LoadPluginBySystemName("Payment.PayPalPlus") as PayPalPlusPaymentProcessor; //_paymentService.LoadPaymentMethodBySystemName("Payments.PayPalPlus") as PayPalPlusPaymentProcessor; //if (processor == null || !processor.PluginDescriptor.Installed) // throw new NopException("PayPal Standard module cannot be loaded"); //get price //var paymentAdditionalFee = _paymentService.GetAdditionalHandlingFee(shoppingCart, processor.PluginDescriptor.SystemName); var paymentAdditionalFee = _paymentService.GetAdditionalHandlingFee(shoppingCart, "Payment.PayPalPlus"); var paymentPrice = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, false, customer); if (paymentPrice <= decimal.Zero) { return(null); } //create item return(new Item { //name = $"Metodo de Pago (" + processor.PluginDescriptor.FriendlyName + ") Costo adicional", name = $"Metodo de Pago Costo adicional", price = paymentPrice.ToString("N", new CultureInfo("en-US")), quantity = "1" }); }
/// <summary> /// Gets tax /// </summary> /// <param name="cart">Shopping cart</param> /// <param name="taxRates">Tax rates</param> /// <param name="usePaymentMethodAdditionalFee">A value indicating whether we should use payment method additional fee when calculating tax</param> /// <returns>Tax total</returns> public virtual decimal GetTaxTotal(IList <ShoppingCartItem> cart, out SortedDictionary <decimal, decimal> taxRates, bool usePaymentMethodAdditionalFee = true) { if (cart == null) { throw new ArgumentNullException("cart"); } taxRates = new SortedDictionary <decimal, decimal>(); var customer = cart.GetCustomer(); string paymentMethodSystemName = ""; if (customer != null) { paymentMethodSystemName = customer.GetAttribute <string>( SystemCustomerAttributeNames.SelectedPaymentMethod, _genericAttributeService, _storeContext.CurrentStore.Id); } //subscription sub total (items + checkout attributes) decimal subTotalTaxTotal = decimal.Zero; decimal subscriptionSubTotalDiscountAmount; decimal subTotalWithoutDiscountBase; decimal subTotalWithDiscountBase; SortedDictionary <decimal, decimal> subscriptionSubTotalTaxRates; GetShoppingCartSubTotal(cart, false, out subscriptionSubTotalDiscountAmount, out subTotalWithoutDiscountBase, out subTotalWithDiscountBase, out subscriptionSubTotalTaxRates); foreach (KeyValuePair <decimal, decimal> kvp in subscriptionSubTotalTaxRates) { decimal taxRate = kvp.Key; decimal taxValue = kvp.Value; subTotalTaxTotal += taxValue; if (taxRate > decimal.Zero && taxValue > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, taxValue); } else { taxRates[taxRate] = taxRates[taxRate] + taxValue; } } } //payment method additional fee decimal paymentMethodAdditionalFeeTax = decimal.Zero; if (usePaymentMethodAdditionalFee && _taxSettings.PaymentMethodAdditionalFeeIsTaxable) { decimal taxRate; decimal paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, paymentMethodSystemName); decimal paymentMethodAdditionalFeeExclTax = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, false, customer, out taxRate); decimal paymentMethodAdditionalFeeInclTax = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, true, customer, out taxRate); paymentMethodAdditionalFeeTax = paymentMethodAdditionalFeeInclTax - paymentMethodAdditionalFeeExclTax; //ensure that tax is equal or greater than zero if (paymentMethodAdditionalFeeTax < decimal.Zero) { paymentMethodAdditionalFeeTax = decimal.Zero; } //tax rates if (taxRate > decimal.Zero && paymentMethodAdditionalFeeTax > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, paymentMethodAdditionalFeeTax); } else { taxRates[taxRate] = taxRates[taxRate] + paymentMethodAdditionalFeeTax; } } } //add at least one tax rate (0%) if (!taxRates.Any()) { taxRates.Add(decimal.Zero, decimal.Zero); } //summarize taxes decimal taxTotal = subTotalTaxTotal + paymentMethodAdditionalFeeTax; //ensure that tax is equal or greater than zero if (taxTotal < decimal.Zero) { taxTotal = decimal.Zero; } //round tax if (_shoppingCartSettings.RoundPricesDuringCalculation) { taxTotal = RoundingHelper.RoundPrice(taxTotal); } return(taxTotal); }
/// <summary> /// Gets tax total /// </summary> /// <param name="taxTotalRequest">Tax total request</param> /// <returns>Tax total</returns> public TaxTotalResult GetTaxTotal(TaxTotalRequest taxTotalRequest) { if (!(_httpContextAccessor.HttpContext.Items.TryGetValue("nop.TaxTotal", out var result) && result is TaxTotalResult taxTotalResult)) { var taxRates = new SortedDictionary <decimal, decimal>(); //order sub total (items + checkout attributes) _orderTotalCalculationService .GetShoppingCartSubTotal(taxTotalRequest.ShoppingCart, false, out _, out _, out _, out _, out var orderSubTotalTaxRates); var subTotalTaxTotal = decimal.Zero; foreach (var kvp in orderSubTotalTaxRates) { var taxRate = kvp.Key; var taxValue = kvp.Value; subTotalTaxTotal += taxValue; if (taxRate > decimal.Zero && taxValue > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, taxValue); } else { taxRates[taxRate] = taxRates[taxRate] + taxValue; } } } //shipping var shippingTax = decimal.Zero; if (_taxSettings.ShippingIsTaxable) { var shippingExclTax = _orderTotalCalculationService .GetShoppingCartShippingTotal(taxTotalRequest.ShoppingCart, false, out _); var shippingInclTax = _orderTotalCalculationService .GetShoppingCartShippingTotal(taxTotalRequest.ShoppingCart, true, out var taxRate); if (shippingExclTax.HasValue && shippingInclTax.HasValue) { shippingTax = shippingInclTax.Value - shippingExclTax.Value; if (shippingTax < decimal.Zero) { shippingTax = decimal.Zero; } if (taxRate > decimal.Zero && shippingTax > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, shippingTax); } else { taxRates[taxRate] = taxRates[taxRate] + shippingTax; } } } } //add at least one tax rate (0%) if (!taxRates.Any()) { taxRates.Add(decimal.Zero, decimal.Zero); } var taxTotal = subTotalTaxTotal + shippingTax; if (taxTotal < decimal.Zero) { taxTotal = decimal.Zero; } taxTotalResult = new TaxTotalResult { TaxTotal = taxTotal, TaxRates = taxRates }; _httpContextAccessor.HttpContext.Items.TryAdd("nop.TaxTotal", taxTotalResult); } //payment method additional fee if (taxTotalRequest.UsePaymentMethodAdditionalFee && _taxSettings.PaymentMethodAdditionalFeeIsTaxable) { var paymentMethodSystemName = taxTotalRequest.Customer != null ? _genericAttributeService.GetAttribute <string>(taxTotalRequest.Customer, NopCustomerDefaults.SelectedPaymentMethodAttribute, taxTotalRequest.StoreId) : string.Empty; var paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(taxTotalRequest.ShoppingCart, paymentMethodSystemName); var paymentMethodAdditionalFeeExclTax = _taxService .GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, false, taxTotalRequest.Customer, out _); var paymentMethodAdditionalFeeInclTax = _taxService .GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, true, taxTotalRequest.Customer, out var taxRate); var paymentMethodAdditionalFeeTax = paymentMethodAdditionalFeeInclTax - paymentMethodAdditionalFeeExclTax; if (paymentMethodAdditionalFeeTax < decimal.Zero) { paymentMethodAdditionalFeeTax = decimal.Zero; } taxTotalResult.TaxTotal += paymentMethodAdditionalFeeTax; if (taxRate > decimal.Zero && paymentMethodAdditionalFeeTax > decimal.Zero) { if (!taxTotalResult.TaxRates.ContainsKey(taxRate)) { taxTotalResult.TaxRates.Add(taxRate, paymentMethodAdditionalFeeTax); } else { taxTotalResult.TaxRates[taxRate] = taxTotalResult.TaxRates[taxRate] + paymentMethodAdditionalFeeTax; } } } return(taxTotalResult); }
protected CheckoutPaymentMethodModel PreparePaymentMethodModel(IList<OrganizedShoppingCartItem> cart) { var model = new CheckoutPaymentMethodModel(); //reward points if (_rewardPointsSettings.Enabled && !cart.IsRecurring()) { int rewardPointsBalance = _workContext.CurrentCustomer.GetRewardPointsBalance(); decimal rewardPointsAmountBase = _orderTotalCalculationService.ConvertRewardPointsToAmount(rewardPointsBalance); decimal rewardPointsAmount = _currencyService.ConvertFromPrimaryStoreCurrency(rewardPointsAmountBase, _workContext.WorkingCurrency); if (rewardPointsAmount > decimal.Zero) { model.DisplayRewardPoints = true; model.RewardPointsAmount = _priceFormatter.FormatPrice(rewardPointsAmount, true, false); model.RewardPointsBalance = rewardPointsBalance; } } var boundPaymentMethods = _paymentService .LoadActivePaymentMethods(_workContext.CurrentCustomer.Id, _storeContext.CurrentStore.Id) .Where(pm => pm.Value.PaymentMethodType == PaymentMethodType.Standard || pm.Value.PaymentMethodType == PaymentMethodType.Redirection || pm.Value.PaymentMethodType == PaymentMethodType.StandardAndRedirection) .ToList(); foreach (var pm in boundPaymentMethods) { if (cart.IsRecurring() && pm.Value.RecurringPaymentType == RecurringPaymentType.NotSupported) continue; var pmModel = new CheckoutPaymentMethodModel.PaymentMethodModel() { Name = _pluginMediator.GetLocalizedFriendlyName(pm.Metadata), Description = _pluginMediator.GetLocalizedDescription(pm.Metadata), PaymentMethodSystemName = pm.Metadata.SystemName, PaymentInfoRoute = pm.Value.GetPaymentInfoRoute(), RequiresInteraction = pm.Value.RequiresInteraction }; pmModel.BrandUrl = _pluginMediator.GetBrandImageUrl(pm.Metadata); // payment method additional fee decimal paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, pm.Metadata.SystemName); decimal rateBase = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, _workContext.CurrentCustomer); decimal rate = _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, _workContext.WorkingCurrency); if (rate != decimal.Zero) pmModel.Fee = _priceFormatter.FormatPaymentMethodAdditionalFee(rate, true); model.PaymentMethods.Add(pmModel); } // find a selected (previously) payment method var selectedPaymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute<string>( SystemCustomerAttributeNames.SelectedPaymentMethod, _genericAttributeService, _storeContext.CurrentStore.Id); bool selected = false; if (selectedPaymentMethodSystemName.HasValue()) { var paymentMethodToSelect = model.PaymentMethods.Find(pm => pm.PaymentMethodSystemName.IsCaseInsensitiveEqual(selectedPaymentMethodSystemName)); if (paymentMethodToSelect != null) { paymentMethodToSelect.Selected = true; selected = true; } } // if no option has been selected, let's do it for the first one if (!selected) { var paymentMethodToSelect = model.PaymentMethods.FirstOrDefault(); if (paymentMethodToSelect != null) paymentMethodToSelect.Selected = true; } return model; }
/// <summary> /// Prepare payment method model /// </summary> /// <param name="cart">Cart</param> /// <param name="filterByCountryId">Filter by country identifier</param> /// <returns>Payment method model</returns> public virtual CheckoutPaymentMethodModel PreparePaymentMethodModel(IList <ShoppingCartItem> cart, int filterByCountryId) { var model = new CheckoutPaymentMethodModel(); //reward points if (_rewardPointsSettings.Enabled && !_shoppingCartService.ShoppingCartIsRecurring(cart)) { var rewardPointsBalance = _rewardPointService.GetRewardPointsBalance(_workContext.CurrentCustomer.Id, _storeContext.CurrentStore.Id); rewardPointsBalance = _rewardPointService.GetReducedPointsBalance(rewardPointsBalance); var rewardPointsAmountBase = _orderTotalCalculationService.ConvertRewardPointsToAmount(rewardPointsBalance); var rewardPointsAmount = _currencyService.ConvertFromPrimaryStoreCurrency(rewardPointsAmountBase, _workContext.WorkingCurrency); if (rewardPointsAmount > decimal.Zero && _orderTotalCalculationService.CheckMinimumRewardPointsToUseRequirement(rewardPointsBalance)) { model.DisplayRewardPoints = true; model.RewardPointsAmount = _priceFormatter.FormatPrice(rewardPointsAmount, true, false); model.RewardPointsBalance = rewardPointsBalance; //are points enough to pay for entire order? like if this option (to use them) was selected model.RewardPointsEnoughToPayForOrder = !_orderProcessingService.IsPaymentWorkflowRequired(cart, true); } } //filter by country var paymentMethods = _paymentService .LoadActivePaymentMethods(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id, filterByCountryId) .Where(pm => pm.PaymentMethodType == PaymentMethodType.Standard || pm.PaymentMethodType == PaymentMethodType.Redirection) .Where(pm => !pm.HidePaymentMethod(cart)) .ToList(); foreach (var pm in paymentMethods) { if (_shoppingCartService.ShoppingCartIsRecurring(cart) && pm.RecurringPaymentType == RecurringPaymentType.NotSupported) { continue; } var pmModel = new CheckoutPaymentMethodModel.PaymentMethodModel { Name = _localizationService.GetLocalizedFriendlyName(pm, _workContext.WorkingLanguage.Id), Description = _paymentSettings.ShowPaymentMethodDescriptions ? pm.PaymentMethodDescription : string.Empty, PaymentMethodSystemName = pm.PluginDescriptor.SystemName, LogoUrl = PluginManager.GetLogoUrl(pm.PluginDescriptor) }; //payment method additional fee var paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, pm.PluginDescriptor.SystemName); var rateBase = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, _workContext.CurrentCustomer); var rate = _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, _workContext.WorkingCurrency); if (rate > decimal.Zero) { pmModel.Fee = _priceFormatter.FormatPaymentMethodAdditionalFee(rate, true); } model.PaymentMethods.Add(pmModel); } //find a selected (previously) payment method var selectedPaymentMethodSystemName = _genericAttributeService.GetAttribute <string>(_workContext.CurrentCustomer, NopCustomerDefaults.SelectedPaymentMethodAttribute, _storeContext.CurrentStore.Id); if (!string.IsNullOrEmpty(selectedPaymentMethodSystemName)) { var paymentMethodToSelect = model.PaymentMethods.ToList() .Find(pm => pm.PaymentMethodSystemName.Equals(selectedPaymentMethodSystemName, StringComparison.InvariantCultureIgnoreCase)); if (paymentMethodToSelect != null) { paymentMethodToSelect.Selected = true; } } //if no option has been selected, let's do it for the first one if (model.PaymentMethods.FirstOrDefault(so => so.Selected) == null) { var paymentMethodToSelect = model.PaymentMethods.FirstOrDefault(); if (paymentMethodToSelect != null) { paymentMethodToSelect.Selected = true; } } return(model); }
/// <summary> /// Gets tax /// </summary> /// <param name="cart">Shopping cart</param> /// <param name="taxRates">Tax rates</param> /// <returns>Tax total</returns> public virtual decimal GetTaxTotal(IList <ShoppingCartItem> cart, out SortedDictionary <decimal, decimal> taxRates) { if (cart == null) { throw new ArgumentNullException("cart"); } taxRates = new SortedDictionary <decimal, decimal>(); var customer = cart.GetCustomer(); string paymentMethodSystemName = ""; if (customer != null) { paymentMethodSystemName = customer.SelectedPaymentMethodSystemName; } //order sub total (items + checkout attributes) decimal subTotalTaxTotal = decimal.Zero; decimal orderSubTotalDiscountAmount = decimal.Zero; Discount orderSubTotalAppliedDiscount = null; decimal subTotalWithoutDiscountBase = decimal.Zero; decimal subTotalWithDiscountBase = decimal.Zero; SortedDictionary <decimal, decimal> orderSubTotalTaxRates = null; GetShoppingCartSubTotal(cart, false, out orderSubTotalDiscountAmount, out orderSubTotalAppliedDiscount, out subTotalWithoutDiscountBase, out subTotalWithDiscountBase, out orderSubTotalTaxRates); foreach (KeyValuePair <decimal, decimal> kvp in orderSubTotalTaxRates) { decimal taxRate = kvp.Key; decimal taxValue = kvp.Value; subTotalTaxTotal += taxValue; if (taxRate > decimal.Zero && taxValue > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, taxValue); } else { taxRates[taxRate] = taxRates[taxRate] + taxValue; } } } //shipping decimal shippingTax = decimal.Zero; if (_taxSettings.ShippingIsTaxable) { decimal taxRate = decimal.Zero; decimal?shippingExclTax = GetShoppingCartShippingTotal(cart, false, out taxRate); decimal?shippingInclTax = GetShoppingCartShippingTotal(cart, true, out taxRate); if (shippingExclTax.HasValue && shippingInclTax.HasValue) { shippingTax = shippingInclTax.Value - shippingExclTax.Value; //tax rates if (taxRate > decimal.Zero && shippingTax > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, shippingTax); } else { taxRates[taxRate] = taxRates[taxRate] + shippingTax; } } } } //payment method additional fee decimal paymentMethodAdditionalFeeTax = decimal.Zero; if (_taxSettings.PaymentMethodAdditionalFeeIsTaxable) { decimal taxRate = decimal.Zero; decimal paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(paymentMethodSystemName); decimal paymentMethodAdditionalFeeExclTax = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, false, customer, out taxRate); decimal paymentMethodAdditionalFeeInclTax = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, true, customer, out taxRate); paymentMethodAdditionalFeeTax = paymentMethodAdditionalFeeInclTax - paymentMethodAdditionalFeeExclTax; //tax rates if (taxRate > decimal.Zero && paymentMethodAdditionalFeeTax > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, paymentMethodAdditionalFeeTax); } else { taxRates[taxRate] = taxRates[taxRate] + paymentMethodAdditionalFeeTax; } } } //add at least one tax rate (0%) if (taxRates.Count == 0) { taxRates.Add(decimal.Zero, decimal.Zero); } //summarize taxes decimal taxTotal = subTotalTaxTotal + shippingTax + paymentMethodAdditionalFeeTax; if (_shoppingCartSettings.RoundPricesDuringCalculation) { taxTotal = Math.Round(taxTotal, 2); } return(taxTotal); }
/// <summary> /// Gets tax /// </summary> /// <param name="cart">Shopping cart</param> /// <param name="taxRates">Tax rates</param> /// <param name="usePaymentMethodAdditionalFee">A value indicating whether we should use payment method additional fee when calculating tax</param> /// <returns>Tax total</returns> public virtual async Task <(decimal taxtotal, SortedDictionary <decimal, decimal> taxRates)> GetTaxTotal(IList <ShoppingCartItem> cart, bool usePaymentMethodAdditionalFee = true) { if (cart == null) { throw new ArgumentNullException(nameof(cart)); } var taxRates = new SortedDictionary <decimal, decimal>(); var customer = _workContext.CurrentCustomer; string paymentMethodSystemName = ""; if (customer != null) { paymentMethodSystemName = customer.GetUserFieldFromEntity <string>( SystemCustomerFieldNames.SelectedPaymentMethod, _workContext.CurrentStore.Id); } //order sub total (items + checkout attributes) decimal subTotalTaxTotal = decimal.Zero; var shoppingCartSubTotal = await GetShoppingCartSubTotal(cart, false); SortedDictionary <decimal, decimal> orderSubTotalTaxRates = shoppingCartSubTotal.taxRates; foreach (KeyValuePair <decimal, decimal> kvp in orderSubTotalTaxRates) { decimal taxRate = kvp.Key; decimal taxValue = kvp.Value; subTotalTaxTotal += taxValue; if (taxRate > decimal.Zero && taxValue > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, taxValue); } else { taxRates[taxRate] = taxRates[taxRate] + taxValue; } } } //shipping decimal shippingTax = decimal.Zero; if (_taxSettings.ShippingIsTaxable) { decimal taxRate; var shippingTotalExcl = await GetShoppingCartShippingTotal(cart, false); decimal?shippingExclTax = shippingTotalExcl.shoppingCartShippingTotal; var shippingTotalIncl = await GetShoppingCartShippingTotal(cart, true); decimal?shippingInclTax = shippingTotalIncl.shoppingCartShippingTotal; taxRate = shippingTotalIncl.taxRate; if (shippingExclTax.HasValue && shippingInclTax.HasValue) { shippingTax = shippingInclTax.Value - shippingExclTax.Value; //ensure that tax is equal or greater than zero if (shippingTax < decimal.Zero) { shippingTax = decimal.Zero; } //tax rates if (taxRate > decimal.Zero && shippingTax > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, shippingTax); } else { taxRates[taxRate] = taxRates[taxRate] + shippingTax; } } } } //payment method additional fee decimal paymentMethodAdditionalFeeTax = decimal.Zero; if (usePaymentMethodAdditionalFee && _taxSettings.PaymentMethodAdditionalFeeIsTaxable) { decimal taxRate; decimal paymentMethodAdditionalFee = await _paymentService.GetAdditionalHandlingFee(cart, paymentMethodSystemName); var additionalFeeExclTax = await _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, false, customer); decimal paymentMethodAdditionalFeeExclTax = additionalFeeExclTax.paymentPrice; var additionalFeeInclTax = await _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, true, customer); decimal paymentMethodAdditionalFeeInclTax = additionalFeeInclTax.paymentPrice; taxRate = additionalFeeInclTax.taxRate; paymentMethodAdditionalFeeTax = paymentMethodAdditionalFeeInclTax - paymentMethodAdditionalFeeExclTax; //ensure that tax is equal or greater than zero if (paymentMethodAdditionalFeeTax < decimal.Zero) { paymentMethodAdditionalFeeTax = decimal.Zero; } //tax rates if (taxRate > decimal.Zero && paymentMethodAdditionalFeeTax > decimal.Zero) { if (!taxRates.ContainsKey(taxRate)) { taxRates.Add(taxRate, paymentMethodAdditionalFeeTax); } else { taxRates[taxRate] = taxRates[taxRate] + paymentMethodAdditionalFeeTax; } } } //add at least one tax rate (0%) if (!taxRates.Any()) { taxRates.Add(decimal.Zero, decimal.Zero); } //summarize taxes decimal taxTotal = subTotalTaxTotal + shippingTax + paymentMethodAdditionalFeeTax; //ensure that tax is equal or greater than zero if (taxTotal < decimal.Zero) { taxTotal = decimal.Zero; } //round tax if (_shoppingCartSettings.RoundPrices) { taxTotal = RoundingHelper.RoundPrice(taxTotal, _workContext.WorkingCurrency); } return(taxTotal, taxRates); }
/// <summary> /// PrepareOrderTotalsModel: /// </summary> /// <param name="cart"></param> /// <param name="isEditable"></param> /// <returns></returns> public virtual decimal PrepareOrderTotalsModel(IList <ShoppingCartItem> cart, bool isEditable) { var model = new OrderTotalsModel(); model.IsEditable = isEditable; if (cart.Count > 0) { //subtotal decimal orderSubTotalDiscountAmountBase; Discount orderSubTotalAppliedDiscount; decimal subTotalWithoutDiscountBase; decimal subTotalWithDiscountBase; var subTotalIncludingTax = _workContext.TaxDisplayType == TaxDisplayType.IncludingTax && !_taxSettings.ForceTaxExclusionFromOrderSubtotal; _orderTotalCalculationService.GetShoppingCartSubTotal(cart, subTotalIncludingTax, out orderSubTotalDiscountAmountBase, out orderSubTotalAppliedDiscount, out subTotalWithoutDiscountBase, out subTotalWithDiscountBase); decimal subtotalBase = subTotalWithoutDiscountBase; decimal subtotal = _currencyService.ConvertFromPrimaryStoreCurrency(subtotalBase, _workContext.WorkingCurrency); model.SubTotal = _priceFormatter.FormatPrice(subtotal, true, _workContext.WorkingCurrency, _workContext.WorkingLanguage, subTotalIncludingTax); if (orderSubTotalDiscountAmountBase > decimal.Zero) { decimal orderSubTotalDiscountAmount = _currencyService.ConvertFromPrimaryStoreCurrency(orderSubTotalDiscountAmountBase, _workContext.WorkingCurrency); model.SubTotalDiscount = _priceFormatter.FormatPrice(-orderSubTotalDiscountAmount, true, _workContext.WorkingCurrency, _workContext.WorkingLanguage, subTotalIncludingTax); model.AllowRemovingSubTotalDiscount = orderSubTotalAppliedDiscount != null && orderSubTotalAppliedDiscount.RequiresCouponCode && !String.IsNullOrEmpty(orderSubTotalAppliedDiscount.CouponCode) && model.IsEditable; } //shipping info model.RequiresShipping = cart.RequiresShipping(); if (model.RequiresShipping) { decimal?shoppingCartShippingBase = _orderTotalCalculationService.GetShoppingCartShippingTotal(cart); if (shoppingCartShippingBase.HasValue) { decimal shoppingCartShipping = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartShippingBase.Value, _workContext.WorkingCurrency); model.Shipping = _priceFormatter.FormatShippingPrice(shoppingCartShipping, true); //selected shipping method var shippingOption = _workContext.CurrentCustomer.GetAttribute <ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, _storeContext.CurrentStore.Id); if (shippingOption != null) { model.SelectedShippingMethod = shippingOption.Name; } } } //payment method fee var paymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute <string>( SystemCustomerAttributeNames.SelectedPaymentMethod, _storeContext.CurrentStore.Id); decimal paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, paymentMethodSystemName); decimal paymentMethodAdditionalFeeWithTaxBase = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, _workContext.CurrentCustomer); if (paymentMethodAdditionalFeeWithTaxBase > decimal.Zero) { decimal paymentMethodAdditionalFeeWithTax = _currencyService.ConvertFromPrimaryStoreCurrency(paymentMethodAdditionalFeeWithTaxBase, _workContext.WorkingCurrency); model.PaymentMethodAdditionalFee = _priceFormatter.FormatPaymentMethodAdditionalFee(paymentMethodAdditionalFeeWithTax, true); } //tax bool displayTax = true; bool displayTaxRates = true; if (_taxSettings.HideTaxInOrderSummary && _workContext.TaxDisplayType == TaxDisplayType.IncludingTax) { displayTax = false; displayTaxRates = false; } else { SortedDictionary <decimal, decimal> taxRates; decimal shoppingCartTaxBase = _orderTotalCalculationService.GetTaxTotal(cart, out taxRates); decimal shoppingCartTax = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartTaxBase, _workContext.WorkingCurrency); if (shoppingCartTaxBase == 0 && _taxSettings.HideZeroTax) { displayTax = false; displayTaxRates = false; } else { displayTaxRates = _taxSettings.DisplayTaxRates && taxRates.Count > 0; displayTax = !displayTaxRates; model.Tax = _priceFormatter.FormatPrice(shoppingCartTax, true, false); foreach (var tr in taxRates) { model.TaxRates.Add(new OrderTotalsModel.TaxRate { Rate = _priceFormatter.FormatTaxRate(tr.Key), Value = _priceFormatter.FormatPrice(_currencyService.ConvertFromPrimaryStoreCurrency(tr.Value, _workContext.WorkingCurrency), true, false), }); } } } model.DisplayTaxRates = displayTaxRates; model.DisplayTax = displayTax; //total decimal orderTotalDiscountAmountBase; Discount orderTotalAppliedDiscount; List <AppliedGiftCard> appliedGiftCards; int redeemedRewardPoints; decimal redeemedRewardPointsAmount; decimal?shoppingCartTotalBase = _orderTotalCalculationService.GetShoppingCartTotal(cart, out orderTotalDiscountAmountBase, out orderTotalAppliedDiscount, out appliedGiftCards, out redeemedRewardPoints, out redeemedRewardPointsAmount); return(_currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartTotalBase.Value, _workContext.WorkingCurrency)); } return(decimal.Zero); }
public async Task <CheckoutPaymentMethodModel> Handle(GetPaymentMethod request, CancellationToken cancellationToken) { var model = new CheckoutPaymentMethodModel(); //loyalty points if (_loyaltyPointsSettings.Enabled) { int loyaltyPointsBalance = await _loyaltyPointsService.GetLoyaltyPointsBalance(request.Customer.Id, request.Store.Id); double loyaltyPointsAmount = await _currencyService.ConvertFromPrimaryStoreCurrency(await _orderTotalCalculationService.ConvertLoyaltyPointsToAmount(loyaltyPointsBalance), request.Currency); if (loyaltyPointsAmount > 0 && _orderTotalCalculationService.CheckMinimumLoyaltyPointsToUseRequirement(loyaltyPointsBalance)) { model.DisplayLoyaltyPoints = true; model.LoyaltyPointsAmount = _priceFormatter.FormatPrice(loyaltyPointsAmount, false); model.LoyaltyPointsBalance = loyaltyPointsBalance; var shoppingCartTotalBase = (await _orderTotalCalculationService.GetShoppingCartTotal(request.Cart, useLoyaltyPoints: true)).shoppingCartTotal; model.LoyaltyPointsEnoughToPayForOrder = (shoppingCartTotalBase.HasValue && shoppingCartTotalBase.Value == 0); } } //filter by country var paymentMethods = (await _paymentService .LoadActivePaymentMethods(request.Customer, request.Store.Id, request.FilterByCountryId)) .Where(pm => pm.PaymentMethodType == PaymentMethodType.Standard || pm.PaymentMethodType == PaymentMethodType.Redirection).ToList(); var availablepaymentMethods = new List <IPaymentProvider>(); foreach (var pm in paymentMethods) { if (!await pm.HidePaymentMethod(request.Cart)) { availablepaymentMethods.Add(pm); } } foreach (var pm in availablepaymentMethods) { var pmModel = new CheckoutPaymentMethodModel.PaymentMethodModel { Name = pm.FriendlyName, Description = _paymentSettings.ShowPaymentDescriptions ? await pm.Description() : string.Empty, PaymentMethodSystemName = pm.SystemName, LogoUrl = pm.LogoURL }; //payment method additional fee double paymentMethodAdditionalFee = await _paymentService.GetAdditionalHandlingFee(request.Cart, pm.SystemName); double rate = (await _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, request.Customer)).paymentPrice; if (rate > 0) { pmModel.Fee = _priceFormatter.FormatPaymentMethodAdditionalFee(rate); } model.PaymentMethods.Add(pmModel); } //find a selected (previously) payment method var selectedPaymentMethodSystemName = request.Customer.GetUserFieldFromEntity <string>(SystemCustomerFieldNames.SelectedPaymentMethod, request.Store.Id); if (!string.IsNullOrEmpty(selectedPaymentMethodSystemName)) { var paymentMethodToSelect = model.PaymentMethods.ToList() .Find(pm => pm.PaymentMethodSystemName.Equals(selectedPaymentMethodSystemName, StringComparison.OrdinalIgnoreCase)); if (paymentMethodToSelect != null) { paymentMethodToSelect.Selected = true; } } //if no option has been selected, do it for the first one if (model.PaymentMethods.FirstOrDefault(so => so.Selected) == null) { var paymentMethodToSelect = model.PaymentMethods.FirstOrDefault(); if (paymentMethodToSelect != null) { paymentMethodToSelect.Selected = true; } } return(model); }
/// <summary> /// Prepare details to place an order. It also sets some properties to "processPaymentRequest" /// </summary> /// <param name="processPaymentRequest">Process payment request</param> /// <returns>Details</returns> protected override PlaceOrderContainter PreparePlaceOrderDetails(ProcessPaymentRequest processPaymentRequest) { var details = new PlaceOrderContainter(); //customer details.Customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId); if (details.Customer == null) { throw new ArgumentException("Customer is not set"); } //affiliate var affiliate = _affiliateService.GetAffiliateById(details.Customer.AffiliateId); if (affiliate != null && affiliate.Active && !affiliate.Deleted) { details.AffiliateId = affiliate.Id; } //check whether customer is guest if (details.Customer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed) { throw new NopException("Anonymous checkout is not allowed"); } //customer currency var currencyTmp = _currencyService.GetCurrencyById( details.Customer.GetAttribute <int>(SystemCustomerAttributeNames.CurrencyId, processPaymentRequest.StoreId)); var customerCurrency = (currencyTmp != null && currencyTmp.Published) ? currencyTmp : _workContext.WorkingCurrency; var primaryStoreCurrency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId); details.CustomerCurrencyCode = customerCurrency.CurrencyCode; //START PATCH var coinServiceSettings = EngineContext.Current.ContainerManager.Resolve <CoinServiceSettings>(); string[] Cryptos; if (coinServiceSettings.SupportedCoins != null) { Cryptos = coinServiceSettings.SupportedCoins.Split(','); } else { Cryptos = new string[0]; } if (Cryptos.Contains(details.CustomerCurrencyCode)) { details.CustomerCurrencyRate = CoinMarketCapHelper.GetCoinMarketCapRate(details.CustomerCurrencyCode) / primaryStoreCurrency.Rate; } else { details.CustomerCurrencyRate = customerCurrency.Rate / primaryStoreCurrency.Rate; } //END PATCH //customer language details.CustomerLanguage = _languageService.GetLanguageById( details.Customer.GetAttribute <int>(SystemCustomerAttributeNames.LanguageId, processPaymentRequest.StoreId)); if (details.CustomerLanguage == null || !details.CustomerLanguage.Published) { details.CustomerLanguage = _workContext.WorkingLanguage; } //billing address if (details.Customer.BillingAddress == null) { throw new NopException("Billing address is not provided"); } if (!CommonHelper.IsValidEmail(details.Customer.BillingAddress.Email)) { throw new NopException("Email is not valid"); } details.BillingAddress = (Address)details.Customer.BillingAddress.Clone(); if (details.BillingAddress.Country != null && !details.BillingAddress.Country.AllowsBilling) { throw new NopException(string.Format("Country '{0}' is not allowed for billing", details.BillingAddress.Country.Name)); } //checkout attributes details.CheckoutAttributesXml = details.Customer.GetAttribute <string>(SystemCustomerAttributeNames.CheckoutAttributes, processPaymentRequest.StoreId); details.CheckoutAttributeDescription = _checkoutAttributeFormatter.FormatAttributes(details.CheckoutAttributesXml, details.Customer); //load shopping cart details.Cart = details.Customer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart) .LimitPerStore(processPaymentRequest.StoreId).ToList(); if (!details.Cart.Any()) { throw new NopException("Cart is empty"); } //validate the entire shopping cart var warnings = _shoppingCartService.GetShoppingCartWarnings(details.Cart, details.CheckoutAttributesXml, true); if (warnings.Any()) { throw new NopException(warnings.Aggregate(string.Empty, (current, next) => string.Format("{0}{1};", current, next))); } //validate individual cart items foreach (var sci in details.Cart) { var sciWarnings = _shoppingCartService.GetShoppingCartItemWarnings(details.Customer, sci.ShoppingCartType, sci.Product, processPaymentRequest.StoreId, sci.AttributesXml, sci.CustomerEnteredPrice, sci.RentalStartDateUtc, sci.RentalEndDateUtc, sci.Quantity, false); if (sciWarnings.Any()) { throw new NopException(sciWarnings.Aggregate(string.Empty, (current, next) => string.Format("{0}{1};", current, next))); } } //min totals validation if (!ValidateMinOrderSubtotalAmount(details.Cart)) { var minOrderSubtotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderSubtotalAmount, _workContext.WorkingCurrency); throw new NopException(string.Format(_localizationService.GetResource("Checkout.MinOrderSubtotalAmount"), _priceFormatter.FormatPrice(minOrderSubtotalAmount, true, false))); } if (!ValidateMinOrderTotalAmount(details.Cart)) { var minOrderTotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderTotalAmount, _workContext.WorkingCurrency); throw new NopException(string.Format(_localizationService.GetResource("Checkout.MinOrderTotalAmount"), _priceFormatter.FormatPrice(minOrderTotalAmount, true, false))); } //tax display type if (_taxSettings.AllowCustomersToSelectTaxDisplayType) { details.CustomerTaxDisplayType = (TaxDisplayType)details.Customer.GetAttribute <int>(SystemCustomerAttributeNames.TaxDisplayTypeId, processPaymentRequest.StoreId); } else { details.CustomerTaxDisplayType = _taxSettings.TaxDisplayType; } //sub total (incl tax) decimal orderSubTotalDiscountAmount; List <DiscountForCaching> orderSubTotalAppliedDiscounts; decimal subTotalWithoutDiscountBase; decimal subTotalWithDiscountBase; _orderTotalCalculationService.GetShoppingCartSubTotal(details.Cart, true, out orderSubTotalDiscountAmount, out orderSubTotalAppliedDiscounts, out subTotalWithoutDiscountBase, out subTotalWithDiscountBase); details.OrderSubTotalInclTax = subTotalWithoutDiscountBase; details.OrderSubTotalDiscountInclTax = orderSubTotalDiscountAmount; //discount history foreach (var disc in orderSubTotalAppliedDiscounts) { if (!details.AppliedDiscounts.ContainsDiscount(disc)) { details.AppliedDiscounts.Add(disc); } } //sub total (excl tax) _orderTotalCalculationService.GetShoppingCartSubTotal(details.Cart, false, out orderSubTotalDiscountAmount, out orderSubTotalAppliedDiscounts, out subTotalWithoutDiscountBase, out subTotalWithDiscountBase); details.OrderSubTotalExclTax = subTotalWithoutDiscountBase; details.OrderSubTotalDiscountExclTax = orderSubTotalDiscountAmount; //shipping info if (details.Cart.RequiresShipping()) { var pickupPoint = details.Customer.GetAttribute <PickupPoint>(SystemCustomerAttributeNames.SelectedPickupPoint, processPaymentRequest.StoreId); if (_shippingSettings.AllowPickUpInStore && pickupPoint != null) { var country = _countryService.GetCountryByTwoLetterIsoCode(pickupPoint.CountryCode); var state = _stateProvinceService.GetStateProvinceByAbbreviation(pickupPoint.StateAbbreviation); details.PickUpInStore = true; details.PickupAddress = new Address { Address1 = pickupPoint.Address, City = pickupPoint.City, Country = country, StateProvince = state, ZipPostalCode = pickupPoint.ZipPostalCode, CreatedOnUtc = DateTime.UtcNow, }; } else { if (details.Customer.ShippingAddress == null) { throw new NopException("Shipping address is not provided"); } if (!CommonHelper.IsValidEmail(details.Customer.ShippingAddress.Email)) { throw new NopException("Email is not valid"); } //clone shipping address details.ShippingAddress = (Address)details.Customer.ShippingAddress.Clone(); if (details.ShippingAddress.Country != null && !details.ShippingAddress.Country.AllowsShipping) { throw new NopException(string.Format("Country '{0}' is not allowed for shipping", details.ShippingAddress.Country.Name)); } } var shippingOption = details.Customer.GetAttribute <ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, processPaymentRequest.StoreId); if (shippingOption != null) { details.ShippingMethodName = shippingOption.Name; details.ShippingRateComputationMethodSystemName = shippingOption.ShippingRateComputationMethodSystemName; } details.ShippingStatus = ShippingStatus.NotYetShipped; } else { details.ShippingStatus = ShippingStatus.ShippingNotRequired; } //shipping total decimal tax; List <DiscountForCaching> shippingTotalDiscounts; var orderShippingTotalInclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(details.Cart, true, out tax, out shippingTotalDiscounts); var orderShippingTotalExclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(details.Cart, false); if (!orderShippingTotalInclTax.HasValue || !orderShippingTotalExclTax.HasValue) { throw new NopException("Shipping total couldn't be calculated"); } details.OrderShippingTotalInclTax = orderShippingTotalInclTax.Value; details.OrderShippingTotalExclTax = orderShippingTotalExclTax.Value; foreach (var disc in shippingTotalDiscounts) { if (!details.AppliedDiscounts.ContainsDiscount(disc)) { details.AppliedDiscounts.Add(disc); } } //payment total var paymentAdditionalFee = _paymentService.GetAdditionalHandlingFee(details.Cart, processPaymentRequest.PaymentMethodSystemName); details.PaymentAdditionalFeeInclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, true, details.Customer); details.PaymentAdditionalFeeExclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, false, details.Customer); //tax amount SortedDictionary <decimal, decimal> taxRatesDictionary; details.OrderTaxTotal = _orderTotalCalculationService.GetTaxTotal(details.Cart, out taxRatesDictionary); //VAT number var customerVatStatus = (VatNumberStatus)details.Customer.GetAttribute <int>(SystemCustomerAttributeNames.VatNumberStatusId); if (_taxSettings.EuVatEnabled && customerVatStatus == VatNumberStatus.Valid) { details.VatNumber = details.Customer.GetAttribute <string>(SystemCustomerAttributeNames.VatNumber); } //tax rates details.TaxRates = taxRatesDictionary.Aggregate(string.Empty, (current, next) => string.Format("{0}{1}:{2}; ", current, next.Key.ToString(CultureInfo.InvariantCulture), next.Value.ToString(CultureInfo.InvariantCulture))); //order total (and applied discounts, gift cards, reward points) List <AppliedGiftCard> appliedGiftCards; List <DiscountForCaching> orderAppliedDiscounts; decimal orderDiscountAmount; int redeemedRewardPoints; decimal redeemedRewardPointsAmount; var orderTotal = _orderTotalCalculationService.GetShoppingCartTotal(details.Cart, out orderDiscountAmount, out orderAppliedDiscounts, out appliedGiftCards, out redeemedRewardPoints, out redeemedRewardPointsAmount); if (!orderTotal.HasValue) { throw new NopException("Order total couldn't be calculated"); } details.OrderDiscountAmount = orderDiscountAmount; details.RedeemedRewardPoints = redeemedRewardPoints; details.RedeemedRewardPointsAmount = redeemedRewardPointsAmount; details.AppliedGiftCards = appliedGiftCards; details.OrderTotal = orderTotal.Value; //discount history foreach (var disc in orderAppliedDiscounts) { if (!details.AppliedDiscounts.ContainsDiscount(disc)) { details.AppliedDiscounts.Add(disc); } } processPaymentRequest.OrderTotal = details.OrderTotal; //recurring or standard shopping cart? details.IsRecurringShoppingCart = details.Cart.IsRecurring(); if (details.IsRecurringShoppingCart) { int recurringCycleLength; RecurringProductCyclePeriod recurringCyclePeriod; int recurringTotalCycles; var recurringCyclesError = details.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; } return(details); }
/// <summary> /// Gets payment method additional handling fee /// </summary> /// <param name="price">Price</param> /// <param name="customer">Customer</param> /// <returns>Price</returns> public decimal GetPaymentMethodAdditionalFee(decimal price, Customer customer) { return(_taxService.GetPaymentMethodAdditionalFee(price, customer)); }
/// <summary> /// Prepare tax details by Avalara tax service /// </summary> /// <param name="cart">Shopping cart</param> private void PrepareTaxDetails(IList <ShoppingCartItem> cart) { //ensure that Avalara tax provider is active var taxProvider = _taxPluginManager .LoadPluginBySystemName(AvalaraTaxDefaults.SystemName, _workContext.CurrentCustomer, _storeContext.CurrentStore.Id) as AvalaraTaxProvider; if (!_taxPluginManager.IsPluginActive(taxProvider)) { return; } //create dummy order for the tax request var order = new Order { Customer = _workContext.CurrentCustomer }; //addresses order.BillingAddress = _workContext.CurrentCustomer.BillingAddress; order.ShippingAddress = _workContext.CurrentCustomer.ShippingAddress; if (_shippingSettings.AllowPickupInStore) { var pickupPoint = _genericAttributeService.GetAttribute <PickupPoint>(_workContext.CurrentCustomer, NopCustomerDefaults.SelectedPickupPointAttribute, _storeContext.CurrentStore.Id); if (pickupPoint != null) { var country = _countryService.GetCountryByTwoLetterIsoCode(pickupPoint.CountryCode); order.PickupAddress = new Address { Address1 = pickupPoint.Address, City = pickupPoint.City, Country = country, StateProvince = _stateProvinceService.GetStateProvinceByAbbreviation(pickupPoint.StateAbbreviation, country?.Id), ZipPostalCode = pickupPoint.ZipPostalCode, CreatedOnUtc = DateTime.UtcNow, }; } } //checkout attributes order.CheckoutAttributesXml = _genericAttributeService.GetAttribute <string>(_workContext.CurrentCustomer, NopCustomerDefaults.CheckoutAttributes, _storeContext.CurrentStore.Id); //shipping method var shippingRateComputationMethods = _shippingPluginManager.LoadActivePlugins(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id); order.OrderShippingExclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(cart, false, shippingRateComputationMethods) ?? 0; order.ShippingMethod = _genericAttributeService.GetAttribute <ShippingOption>(_workContext.CurrentCustomer, NopCustomerDefaults.SelectedShippingOptionAttribute, _storeContext.CurrentStore.Id)?.Name; //payment method var paymentMethod = _genericAttributeService.GetAttribute <string>(_workContext.CurrentCustomer, NopCustomerDefaults.SelectedPaymentMethodAttribute, _storeContext.CurrentStore.Id); var paymentFee = _paymentService.GetAdditionalHandlingFee(cart, paymentMethod); order.PaymentMethodAdditionalFeeExclTax = _taxService.GetPaymentMethodAdditionalFee(paymentFee, false, _workContext.CurrentCustomer); order.PaymentMethodSystemName = paymentMethod; //add discount amount _orderTotalCalculationService.GetShoppingCartSubTotal(cart, false, out var orderSubTotalDiscountExclTax, out _, out _, out _); order.OrderSubTotalDiscountExclTax = orderSubTotalDiscountExclTax; //create dummy order items foreach (var cartItem in cart) { var orderItem = new OrderItem { AttributesXml = cartItem.AttributesXml, Product = cartItem.Product, Quantity = cartItem.Quantity }; var itemSubtotal = _priceCalculationService.GetSubTotal(cartItem, true, out _, out _, out _); orderItem.PriceExclTax = _taxService.GetProductPrice(cartItem.Product, itemSubtotal, false, _workContext.CurrentCustomer, out _); order.OrderItems.Add(orderItem); } //get tax details var taxTransaction = taxProvider.CreateOrderTaxTransaction(order, false); if (taxTransaction == null) { return; } //and save it for the further usage var taxDetails = new TaxDetails { TaxTotal = taxTransaction.totalTax }; foreach (var item in taxTransaction.summary) { if (!item.rate.HasValue || !item.tax.HasValue) { continue; } var taxRate = item.rate.Value * 100; var taxValue = item.tax.Value; if (!taxDetails.TaxRates.ContainsKey(taxRate)) { taxDetails.TaxRates.Add(taxRate, taxValue); } else { taxDetails.TaxRates[taxRate] = taxDetails.TaxRates[taxRate] + taxValue; } } _httpContextAccessor.HttpContext.Session.Set(AvalaraTaxDefaults.TaxDetailsSessionValue, taxDetails); }
public virtual async Task <CheckoutPaymentMethodModel> PreparePaymentMethod(IList <ShoppingCartItem> cart, string filterByCountryId) { var model = new CheckoutPaymentMethodModel(); //reward points if (_rewardPointsSettings.Enabled && !cart.IsRecurring()) { int rewardPointsBalance = await _rewardPointsService.GetRewardPointsBalance(_workContext.CurrentCustomer.Id, _storeContext.CurrentStore.Id); decimal rewardPointsAmountBase = await _orderTotalCalculationService.ConvertRewardPointsToAmount(rewardPointsBalance); decimal rewardPointsAmount = await _currencyService.ConvertFromPrimaryStoreCurrency(rewardPointsAmountBase, _workContext.WorkingCurrency); if (rewardPointsAmount > decimal.Zero && _orderTotalCalculationService.CheckMinimumRewardPointsToUseRequirement(rewardPointsBalance)) { model.DisplayRewardPoints = true; model.RewardPointsAmount = _priceFormatter.FormatPrice(rewardPointsAmount, true, false); model.RewardPointsBalance = rewardPointsBalance; model.RewardPointsEnoughToPayForOrder = !(await IsPaymentWorkflowRequired(cart, true)); } } //filter by country var paymentMethods = (await _paymentService .LoadActivePaymentMethods(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id, filterByCountryId)) .Where(pm => pm.PaymentMethodType == PaymentMethodType.Standard || pm.PaymentMethodType == PaymentMethodType.Redirection).ToList(); var availablepaymentMethods = new List <IPaymentMethod>(); foreach (var pm in paymentMethods) { if (!await pm.HidePaymentMethod(cart)) { availablepaymentMethods.Add(pm); } } foreach (var pm in availablepaymentMethods) { if (cart.IsRecurring() && pm.RecurringPaymentType == RecurringPaymentType.NotSupported) { continue; } var pmModel = new CheckoutPaymentMethodModel.PaymentMethodModel { Name = pm.GetLocalizedFriendlyName(_localizationService, _workContext.WorkingLanguage.Id), Description = _paymentSettings.ShowPaymentMethodDescriptions ? await pm.PaymentMethodDescription() : string.Empty, PaymentMethodSystemName = pm.PluginDescriptor.SystemName, LogoUrl = pm.PluginDescriptor.GetLogoUrl(_webHelper) }; //payment method additional fee decimal paymentMethodAdditionalFee = await _paymentService.GetAdditionalHandlingFee(cart, pm.PluginDescriptor.SystemName); decimal rateBase = (await _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, _workContext.CurrentCustomer)).paymentPrice; decimal rate = await _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, _workContext.WorkingCurrency); if (rate > decimal.Zero) { pmModel.Fee = _priceFormatter.FormatPaymentMethodAdditionalFee(rate, true); } model.PaymentMethods.Add(pmModel); } //find a selected (previously) payment method var selectedPaymentMethodSystemName = await _workContext.CurrentCustomer.GetAttribute <string>( _genericAttributeService, SystemCustomerAttributeNames.SelectedPaymentMethod, _storeContext.CurrentStore.Id); if (!String.IsNullOrEmpty(selectedPaymentMethodSystemName)) { var paymentMethodToSelect = model.PaymentMethods.ToList() .Find(pm => pm.PaymentMethodSystemName.Equals(selectedPaymentMethodSystemName, StringComparison.OrdinalIgnoreCase)); if (paymentMethodToSelect != null) { paymentMethodToSelect.Selected = true; } } //if no option has been selected, let's do it for the first one if (model.PaymentMethods.FirstOrDefault(so => so.Selected) == null) { var paymentMethodToSelect = model.PaymentMethods.FirstOrDefault(); if (paymentMethodToSelect != null) { paymentMethodToSelect.Selected = true; } } return(model); }
/// <summary> /// Gets shopping cart total /// </summary> /// <param name="cart">Cart</param> /// <param name="appliedGiftCards">Applied gift cards</param> /// <param name="discountAmount">Applied discount amount</param> /// <param name="appliedDiscounts">Applied discounts</param> /// <param name="redeemedRewardPoints">Reward points to redeem</param> /// <param name="redeemedRewardPointsAmount">Reward points amount in primary store currency to redeem</param> /// <param name="useRewardPoints">A value indicating reward points should be used; null to detect current choice of the customer</param> /// <param name="usePaymentMethodAdditionalFee">A value indicating whether we should use payment method additional fee when calculating order total</param> /// <returns>Shopping cart total;Null if shopping cart total couldn't be calculated now</returns> public override decimal?GetShoppingCartTotal(IList <ShoppingCartItem> cart, out decimal discountAmount, out List <DiscountForCaching> appliedDiscounts, out List <AppliedGiftCard> appliedGiftCards, out int redeemedRewardPoints, out decimal redeemedRewardPointsAmount, bool?useRewardPoints = null, bool usePaymentMethodAdditionalFee = true) { redeemedRewardPoints = 0; redeemedRewardPointsAmount = decimal.Zero; var customer = cart.FirstOrDefault(item => item.Customer != null)?.Customer; var paymentMethodSystemName = string.Empty; if (customer != null) { paymentMethodSystemName = _genericAttributeService.GetAttribute <string>(customer, NopCustomerDefaults.SelectedPaymentMethodAttribute, _storeContext.CurrentStore.Id); } //subtotal without tax GetShoppingCartSubTotal(cart, false, out _, out _, out _, out var subTotalWithDiscountBase); //subtotal with discount var subtotalBase = subTotalWithDiscountBase; //LoadAllShippingRateComputationMethods var shippingRateComputationMethods = _shippingPluginManager.LoadActivePlugins(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id); //shipping without tax var shoppingCartShipping = GetShoppingCartShippingTotal(cart, false, shippingRateComputationMethods); //todo override this method again to include the refundable price //refundable price without tax var refundablePrice = cart.Sum(x => x.Product.RefundablePrice * x.Quantity); //payment method additional fee without tax var paymentMethodAdditionalFeeWithoutTax = decimal.Zero; if (usePaymentMethodAdditionalFee && !string.IsNullOrEmpty(paymentMethodSystemName)) { var paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, paymentMethodSystemName); paymentMethodAdditionalFeeWithoutTax = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, false, customer); } //tax var shoppingCartTax = GetTaxTotal(cart, shippingRateComputationMethods, usePaymentMethodAdditionalFee); //Avalara plugin changes //adjust tax total according to received value from the Avalara shoppingCartTax = _httpContextAccessor.HttpContext.Session .Get <TaxDetails>(AvalaraTaxDefaults.TaxDetailsSessionValue)?.TaxTotal ?? shoppingCartTax; //Avalara plugin changes //order total var resultTemp = decimal.Zero; //refundable price resultTemp += refundablePrice; resultTemp += subtotalBase; if (shoppingCartShipping.HasValue) { resultTemp += shoppingCartShipping.Value; } resultTemp += paymentMethodAdditionalFeeWithoutTax; resultTemp += shoppingCartTax; if (_shoppingCartSettings.RoundPricesDuringCalculation) { resultTemp = _priceCalculationService.RoundPrice(resultTemp); } //order total discount discountAmount = GetOrderTotalDiscount(customer, resultTemp, out appliedDiscounts); //sub totals with discount if (resultTemp < discountAmount) { discountAmount = resultTemp; } //reduce subtotal resultTemp -= discountAmount; if (resultTemp < decimal.Zero) { resultTemp = decimal.Zero; } if (_shoppingCartSettings.RoundPricesDuringCalculation) { resultTemp = _priceCalculationService.RoundPrice(resultTemp); } //let's apply gift cards now (gift cards that can be used) appliedGiftCards = new List <AppliedGiftCard>(); AppliedGiftCards(cart, appliedGiftCards, customer, ref resultTemp); if (resultTemp < decimal.Zero) { resultTemp = decimal.Zero; } if (_shoppingCartSettings.RoundPricesDuringCalculation) { resultTemp = _priceCalculationService.RoundPrice(resultTemp); } if (!shoppingCartShipping.HasValue) { //we have errors return(null); } var orderTotal = resultTemp; //reward points SetRewardPoints(ref redeemedRewardPoints, ref redeemedRewardPointsAmount, useRewardPoints, customer, orderTotal); orderTotal = orderTotal - redeemedRewardPointsAmount; if (_shoppingCartSettings.RoundPricesDuringCalculation) { orderTotal = _priceCalculationService.RoundPrice(orderTotal); } //todo append the refundable price return(orderTotal); }
protected CheckoutPaymentMethodModel PreparePaymentMethodModel(IList <OrganizedShoppingCartItem> cart) { var model = new CheckoutPaymentMethodModel(); // was shipping skipped var shippingOptions = _shippingService.GetShippingOptions(cart, _workContext.CurrentCustomer.ShippingAddress, "", _storeContext.CurrentStore.Id).ShippingOptions; if (!cart.RequiresShipping() || (shippingOptions.Count <= 1 && _shippingSettings.SkipShippingIfSingleOption)) { model.SkippedSelectShipping = true; } var paymentTypes = new PaymentMethodType[] { PaymentMethodType.Standard, PaymentMethodType.Redirection, PaymentMethodType.StandardAndRedirection }; var boundPaymentMethods = _paymentService .LoadActivePaymentMethods(_workContext.CurrentCustomer, cart, _storeContext.CurrentStore.Id, paymentTypes) .ToList(); var allPaymentMethods = _paymentService.GetAllPaymentMethods(); foreach (var pm in boundPaymentMethods) { if (cart.IsRecurring() && pm.Value.RecurringPaymentType == RecurringPaymentType.NotSupported) { continue; } var paymentMethod = allPaymentMethods.FirstOrDefault(x => x.PaymentMethodSystemName.IsCaseInsensitiveEqual(pm.Metadata.SystemName)); var pmModel = new CheckoutPaymentMethodModel.PaymentMethodModel { Name = _pluginMediator.GetLocalizedFriendlyName(pm.Metadata), Description = _pluginMediator.GetLocalizedDescription(pm.Metadata), PaymentMethodSystemName = pm.Metadata.SystemName, PaymentInfoRoute = pm.Value.GetPaymentInfoRoute(), RequiresInteraction = pm.Value.RequiresInteraction }; if (paymentMethod != null) { pmModel.FullDescription = paymentMethod.GetLocalized(x => x.FullDescription, _workContext.WorkingLanguage.Id); } pmModel.BrandUrl = _pluginMediator.GetBrandImageUrl(pm.Metadata); // payment method additional fee decimal paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, pm.Metadata.SystemName); decimal rateBase = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, _workContext.CurrentCustomer); decimal rate = _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, _workContext.WorkingCurrency); if (rate != decimal.Zero) { pmModel.Fee = _priceFormatter.FormatPaymentMethodAdditionalFee(rate, true); } model.PaymentMethods.Add(pmModel); } // find a selected (previously) payment method var selectedPaymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute <string>( SystemCustomerAttributeNames.SelectedPaymentMethod, _genericAttributeService, _storeContext.CurrentStore.Id); bool selected = false; if (selectedPaymentMethodSystemName.HasValue()) { var paymentMethodToSelect = model.PaymentMethods.Find(pm => pm.PaymentMethodSystemName.IsCaseInsensitiveEqual(selectedPaymentMethodSystemName)); if (paymentMethodToSelect != null) { paymentMethodToSelect.Selected = true; selected = true; } } // if no option has been selected, let's do it for the first one if (!selected) { var paymentMethodToSelect = model.PaymentMethods.FirstOrDefault(); if (paymentMethodToSelect != null) { paymentMethodToSelect.Selected = true; } } return(model); }
/// <summary> /// Prepare details to place an order. It also sets some properties to "processPaymentRequest" /// </summary> /// <param name="processPaymentRequest">Process payment request</param> /// <returns>Details</returns> protected override PlaceOrderContainer PreparePlaceOrderDetails(ProcessPaymentRequest processPaymentRequest) { var details = new PlaceOrderContainer { //customer Customer = _customerService.GetCustomerById(processPaymentRequest.CustomerId) }; if (details.Customer == null) { throw new ArgumentException("Customer is not set"); } //affiliate var affiliate = _affiliateService.GetAffiliateById(details.Customer.AffiliateId); if (affiliate != null && affiliate.Active && !affiliate.Deleted) { details.AffiliateId = affiliate.Id; } //check whether customer is guest if (details.Customer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed) { throw new QNetException("Anonymous checkout is not allowed"); } //customer currency var currencyTmp = _currencyService.GetCurrencyById( _genericAttributeService.GetAttribute <int>(details.Customer, QNetCustomerDefaults.CurrencyIdAttribute, processPaymentRequest.StoreId)); var customerCurrency = currencyTmp != null && currencyTmp.Published ? currencyTmp : _workContext.WorkingCurrency; var primaryStoreCurrency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId); details.CustomerCurrencyCode = customerCurrency.CurrencyCode; details.CustomerCurrencyRate = customerCurrency.Rate / primaryStoreCurrency.Rate; //customer language details.CustomerLanguage = _languageService.GetLanguageById( _genericAttributeService.GetAttribute <int>(details.Customer, QNetCustomerDefaults.LanguageIdAttribute, processPaymentRequest.StoreId)); if (details.CustomerLanguage == null || !details.CustomerLanguage.Published) { details.CustomerLanguage = _workContext.WorkingLanguage; } //billing address if (details.Customer.BillingAddress == null) { throw new QNetException("Billing address is not provided"); } if (!CommonHelper.IsValidEmail(details.Customer.BillingAddress.Email)) { throw new QNetException("Email is not valid"); } details.BillingAddress = (Address)details.Customer.BillingAddress.Clone(); if (details.BillingAddress.Country != null && !details.BillingAddress.Country.AllowsBilling) { throw new QNetException($"Country '{details.BillingAddress.Country.Name}' is not allowed for billing"); } //checkout attributes details.CheckoutAttributesXml = _genericAttributeService.GetAttribute <string>(details.Customer, QNetCustomerDefaults.CheckoutAttributes, processPaymentRequest.StoreId); details.CheckoutAttributeDescription = _checkoutAttributeFormatter.FormatAttributes(details.CheckoutAttributesXml, details.Customer); //load shopping cart details.Cart = _shoppingCartService.GetShoppingCart(details.Customer, ShoppingCartType.ShoppingCart, processPaymentRequest.StoreId); if (!details.Cart.Any()) { throw new QNetException("Cart is empty"); } //validate the entire shopping cart var warnings = _shoppingCartService.GetShoppingCartWarnings(details.Cart, details.CheckoutAttributesXml, true); if (warnings.Any()) { throw new QNetException(warnings.Aggregate(string.Empty, (current, next) => $"{current}{next};")); } //validate individual cart items foreach (var sci in details.Cart) { var sciWarnings = _shoppingCartService.GetShoppingCartItemWarnings(details.Customer, sci.ShoppingCartType, sci.Product, processPaymentRequest.StoreId, sci.AttributesXml, sci.CustomerEnteredPrice, sci.RentalStartDateUtc, sci.RentalEndDateUtc, sci.Quantity, false, sci.Id); if (sciWarnings.Any()) { throw new QNetException(sciWarnings.Aggregate(string.Empty, (current, next) => $"{current}{next};")); } } //min totals validation if (!ValidateMinOrderSubtotalAmount(details.Cart)) { var minOrderSubtotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderSubtotalAmount, _workContext.WorkingCurrency); throw new QNetException(string.Format(_localizationService.GetResource("Checkout.MinOrderSubtotalAmount"), _priceFormatter.FormatPrice(minOrderSubtotalAmount, true, false))); } if (!ValidateMinOrderTotalAmount(details.Cart)) { var minOrderTotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderTotalAmount, _workContext.WorkingCurrency); throw new QNetException(string.Format(_localizationService.GetResource("Checkout.MinOrderTotalAmount"), _priceFormatter.FormatPrice(minOrderTotalAmount, true, false))); } //tax display type if (_taxSettings.AllowCustomersToSelectTaxDisplayType) { details.CustomerTaxDisplayType = (TaxDisplayType)_genericAttributeService.GetAttribute <int>(details.Customer, QNetCustomerDefaults.TaxDisplayTypeIdAttribute, processPaymentRequest.StoreId); } else { details.CustomerTaxDisplayType = _taxSettings.TaxDisplayType; } //sub total (incl tax) _orderTotalCalculationService.GetShoppingCartSubTotal(details.Cart, true, out var orderSubTotalDiscountAmount, out var orderSubTotalAppliedDiscounts, out var subTotalWithoutDiscountBase, out var _); details.OrderSubTotalInclTax = subTotalWithoutDiscountBase; details.OrderSubTotalDiscountInclTax = orderSubTotalDiscountAmount; //discount history foreach (var disc in orderSubTotalAppliedDiscounts) { if (!_discountService.ContainsDiscount(details.AppliedDiscounts, disc)) { details.AppliedDiscounts.Add(disc); } } //sub total (excl tax) _orderTotalCalculationService.GetShoppingCartSubTotal(details.Cart, false, out orderSubTotalDiscountAmount, out orderSubTotalAppliedDiscounts, out subTotalWithoutDiscountBase, out _); details.OrderSubTotalExclTax = subTotalWithoutDiscountBase; details.OrderSubTotalDiscountExclTax = orderSubTotalDiscountAmount; //shipping info if (_shoppingCartService.ShoppingCartRequiresShipping(details.Cart)) { var pickupPoint = _genericAttributeService.GetAttribute <PickupPoint>(details.Customer, QNetCustomerDefaults.SelectedPickupPointAttribute, processPaymentRequest.StoreId); if (_shippingSettings.AllowPickupInStore && pickupPoint != null) { var country = _countryService.GetCountryByTwoLetterIsoCode(pickupPoint.CountryCode); var state = _stateProvinceService.GetStateProvinceByAbbreviation(pickupPoint.StateAbbreviation, country?.Id); details.PickupInStore = true; details.PickupAddress = new Address { Address1 = pickupPoint.Address, City = pickupPoint.City, County = pickupPoint.County, Country = country, StateProvince = state, ZipPostalCode = pickupPoint.ZipPostalCode, CreatedOnUtc = DateTime.UtcNow }; } else { if (details.Customer.ShippingAddress == null) { throw new QNetException("Shipping address is not provided"); } if (!CommonHelper.IsValidEmail(details.Customer.ShippingAddress.Email)) { throw new QNetException("Email is not valid"); } //clone shipping address details.ShippingAddress = (Address)details.Customer.ShippingAddress.Clone(); if (details.ShippingAddress.Country != null && !details.ShippingAddress.Country.AllowsShipping) { throw new QNetException($"Country '{details.ShippingAddress.Country.Name}' is not allowed for shipping"); } } var shippingOption = _genericAttributeService.GetAttribute <ShippingOption>(details.Customer, QNetCustomerDefaults.SelectedShippingOptionAttribute, processPaymentRequest.StoreId); if (shippingOption != null) { details.ShippingMethodName = shippingOption.Name; details.ShippingRateComputationMethodSystemName = shippingOption.ShippingRateComputationMethodSystemName; } details.ShippingStatus = ShippingStatus.NotYetShipped; } else { details.ShippingStatus = ShippingStatus.ShippingNotRequired; } //LoadAllShippingRateComputationMethods var shippingRateComputationMethods = _shippingPluginManager.LoadActivePlugins(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id); //shipping total var orderShippingTotalInclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(details.Cart, true, shippingRateComputationMethods, out var _, out var shippingTotalDiscounts); var orderShippingTotalExclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(details.Cart, false, shippingRateComputationMethods); if (!orderShippingTotalInclTax.HasValue || !orderShippingTotalExclTax.HasValue) { throw new QNetException("Shipping total couldn't be calculated"); } details.OrderShippingTotalInclTax = orderShippingTotalInclTax.Value; details.OrderShippingTotalExclTax = orderShippingTotalExclTax.Value; foreach (var disc in shippingTotalDiscounts) { if (!_discountService.ContainsDiscount(details.AppliedDiscounts, disc)) { details.AppliedDiscounts.Add(disc); } } //payment total var paymentAdditionalFee = _paymentService.GetAdditionalHandlingFee(details.Cart, processPaymentRequest.PaymentMethodSystemName); details.PaymentAdditionalFeeInclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, true, details.Customer); details.PaymentAdditionalFeeExclTax = _taxService.GetPaymentMethodAdditionalFee(paymentAdditionalFee, false, details.Customer); //tax amount details.OrderTaxTotal = _orderTotalCalculationService.GetTaxTotal(details.Cart, shippingRateComputationMethods, out var taxRatesDictionary); //Avalara plugin changes //get previously saved tax details received from the Avalara tax service var taxDetails = _httpContextAccessor.HttpContext.Session.Get <TaxDetails>(AvalaraTaxDefaults.TaxDetailsSessionValue); if (taxDetails != null) { //adjust tax total according to received value from the Avalara if (taxDetails.TaxTotal.HasValue) { details.OrderTaxTotal = taxDetails.TaxTotal.Value; } if (taxDetails.TaxRates?.Any() ?? false) { taxRatesDictionary = new SortedDictionary <decimal, decimal>(taxDetails.TaxRates); } } //Avalara plugin changes //VAT number var customerVatStatus = (VatNumberStatus)_genericAttributeService.GetAttribute <int>(details.Customer, QNetCustomerDefaults.VatNumberStatusIdAttribute); if (_taxSettings.EuVatEnabled && customerVatStatus == VatNumberStatus.Valid) { details.VatNumber = _genericAttributeService.GetAttribute <string>(details.Customer, QNetCustomerDefaults.VatNumberAttribute); } //tax rates details.TaxRates = taxRatesDictionary.Aggregate(string.Empty, (current, next) => $"{current}{next.Key.ToString(CultureInfo.InvariantCulture)}:{next.Value.ToString(CultureInfo.InvariantCulture)}; "); //order total (and applied discounts, gift cards, reward points) var orderTotal = _orderTotalCalculationService.GetShoppingCartTotal(details.Cart, out var orderDiscountAmount, out var orderAppliedDiscounts, out var appliedGiftCards, out var redeemedRewardPoints, out var redeemedRewardPointsAmount); if (!orderTotal.HasValue) { throw new QNetException("Order total couldn't be calculated"); } details.OrderDiscountAmount = orderDiscountAmount; details.RedeemedRewardPoints = redeemedRewardPoints; details.RedeemedRewardPointsAmount = redeemedRewardPointsAmount; details.AppliedGiftCards = appliedGiftCards; details.OrderTotal = orderTotal.Value; //discount history foreach (var disc in orderAppliedDiscounts) { if (!_discountService.ContainsDiscount(details.AppliedDiscounts, disc)) { details.AppliedDiscounts.Add(disc); } } processPaymentRequest.OrderTotal = details.OrderTotal; //Avalara plugin changes //delete custom value _httpContextAccessor.HttpContext.Session.Set <TaxDetails>(AvalaraTaxDefaults.TaxDetailsSessionValue, null); //Avalara plugin changes //recurring or standard shopping cart? details.IsRecurringShoppingCart = _shoppingCartService.ShoppingCartIsRecurring(details.Cart); if (!details.IsRecurringShoppingCart) { return(details); } var recurringCyclesError = _shoppingCartService.GetRecurringCycleInfo(details.Cart, out var recurringCycleLength, out var recurringCyclePeriod, out var recurringTotalCycles); if (!string.IsNullOrEmpty(recurringCyclesError)) { throw new QNetException(recurringCyclesError); } processPaymentRequest.RecurringCycleLength = recurringCycleLength; processPaymentRequest.RecurringCyclePeriod = recurringCyclePeriod; processPaymentRequest.RecurringTotalCycles = recurringTotalCycles; return(details); }