nopSolutions/nopCommerce · error · NopException
Shopping cart total couldn't be calculated now
Error message
Shopping cart total couldn't be calculated now
What it means
Thrown when GetShoppingCartTotalAsync returns null for the cart total during order preparation on the payment method page. This happens when nopCommerce's order total calculation cannot produce a final total, typically due to complex discount/tax/rounding configurations. On product and cart pages the code falls back to subtotal, but on the payment method page it throws.
Source
Thrown at src/Plugins/Nop.Plugin.Payments.PayPalCommerce/Services/PayPalCommerceServiceManager.cs:557
/// A task that represents the asynchronous operation
/// The task result contains the order amount with breakdown
/// </returns>
private async Task<OrderMoney> PrepareOrderMoneyAsync(CartDetails details, List<Item> items)
{
//in some rare cases we need an additional item to adjust the order total
//this can happen due to complex discounts or a large order and related to rounding in calculations
//PayPal uses two decimal places, while nopCommerce can use more complex types of rounding (configured for each currency separately)
var adjustmentName = await _localizationService.GetResourceAsync("Plugins.Payments.PayPalCommerce.Order.Adjustment.Name");
var adjustmentDescription = await _localizationService.GetResourceAsync("Plugins.Payments.PayPalCommerce.Order.Adjustment.Description");
if (items.FirstOrDefault(item => adjustmentName.Equals(item.Name) && adjustmentDescription.Equals(item.Description)) is Item adjustmentItem)
items.Remove(adjustmentItem);
var (total, _, _, _, _, _) = await _orderTotalCalculationService
.GetShoppingCartTotalAsync(details.Cart, usePaymentMethodAdditionalFee: false);
if (total is null)
{
if (details.Placement == ButtonPlacement.PaymentMethod)
throw new NopException("Shopping cart total couldn't be calculated now");
//on product and cart pages the total is not yet calculated, so use subtotal here
var (_, _, subTotal, _, _) = await _orderTotalCalculationService.GetShoppingCartSubTotalAsync(details.Cart, includingTax: false);
total = subTotal;
}
var orderTotal = PrepareMoney(total.Value, details.CurrencyCode);
var (shippingTotal, _, _) = await _orderTotalCalculationService
.GetShoppingCartShippingTotalAsync(details.Cart, includingTax: _taxSettings.ShippingPriceIncludesTax);
var orderShippingTotal = PrepareMoney(shippingTotal ?? decimal.Zero, details.CurrencyCode);
var (taxTotal, _) = await _orderTotalCalculationService.GetTaxTotalAsync(details.Cart, usePaymentMethodAdditionalFee: false);
var orderTaxTotal = PrepareMoney(taxTotal, details.CurrencyCode);
var itemAdjustment = decimal.Zero;
var itemTotal = items.Sum(item => ConvertMoney(item.UnitAmount) * int.Parse(item.Quantity));
var discountTotal = itemTotal + ConvertMoney(orderTaxTotal) + ConvertMoney(orderShippingTotal) - ConvertMoney(orderTotal);
if (discountTotal < decimal.Zero)View on GitHub (pinned to 64bdf2ff08)
Solutions
- Review active discount combinations for rounding conflicts; simplify or disable conflicting discount rules
- Check currency rounding configuration in nopCommerce (Configuration > Currencies) to ensure consistent decimal places
- Verify tax calculation settings do not produce null totals (Configuration > Tax Settings)
- Test the cart total calculation independently via GetShoppingCartTotalAsync to identify which configuration causes the null result
- If using custom discount or tax providers, verify their output is non-null for all cart combinations
Example fix
// before
var (total, _, _, _, _, _) = await _orderTotalCalculationService
.GetShoppingCartTotalAsync(details.Cart, usePaymentMethodAdditionalFee: false);
if (total is null)
throw new NopException("Shopping cart total couldn't be calculated now");
// after
var (total, _, _, _, _, _) = await _orderTotalCalculationService
.GetShoppingCartTotalAsync(details.Cart, usePaymentMethodAdditionalFee: false);
if (total is null)
{
//log details for diagnosis
await _logger.InformationAsync($"Cart total was null for customer {details.Customer.Id}, placement {details.Placement}");
var (_, _, subTotal, _, _) = await _orderTotalCalculationService
.GetShoppingCartSubTotalAsync(details.Cart, includingTax: false);
total = subTotal;
} Defensive patterns
Strategy: fallback
Validate before calling
// Pre-check cart total calculation independently
var (testTotal, _, _, _, _, _) = await _orderTotalCalculationService
.GetShoppingCartTotalAsync(cart, usePaymentMethodAdditionalFee: false);
if (testTotal is null && placement == ButtonPlacement.PaymentMethod)
{
//investigate discount/tax configuration before proceeding
_logger.Warning("Cart total returned null — check discount and tax configuration");
return Error("Unable to calculate order total. Please review your discount and tax settings.");
} Try / catch
var (order, error) = await manager.CreateOrderAsync(settings, placement, paymentSource, cardId, saveCard);
if (!string.IsNullOrEmpty(error))
{
if (error.Contains("total couldn't be calculated"))
{
//guide user to simplify cart or contact support
return View("CartTotalError");
}
} Prevention
- Audit discount combinations for rounding conflicts with PayPal's two-decimal-place format
- Test cart total calculation with various discount and tax scenarios
- Ensure currency decimal place configuration is consistent with payment processor requirements
- Monitor logs for null cart total occurrences to catch configuration issues early
When it happens
Trigger: PreparePurchaseUnitAsync calls GetShoppingCartTotalAsync with usePaymentMethodAdditionalFee=false, the result total is null, and details.Placement == ButtonPlacement.PaymentMethod.
Common situations: Complex discount combinations (e.g., percentage + fixed discounts on the same order) that cause rounding conflicts between nopCommerce's currency-specific rounding and PayPal's two-decimal-place requirement; tax calculation configuration that produces unresolvable totals; gift card or store credit that drives the total calculation to an indeterminate state.
Related errors
- Order total couldn't be calculated
- Shipping total couldn't be calculated
- Checkout.MinOrderTotalAmount
- Customer billing address not set
- Customer shipping address not set
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/ca54c8ff428be954.
Report an issue: GitHub.