nopSolutions/nopCommerce · warning · NopException
Checkout.MinOrderSubtotalAmount
Error message
Checkout.MinOrderSubtotalAmount
What it means
Thrown when the cart subtotal is below the configured minimum order subtotal threshold (_orderSettings.MinOrderSubtotalAmount) and ValidateMinOrderSubtotalAmountAsync returns false. The message uses the localized resource 'Checkout.MinOrderSubtotalAmount' formatted with the threshold converted to the customer's currency. This enforces a minimum spend policy at order placement.
Source
Thrown at src/Libraries/Nop.Services/Orders/OrderProcessingService.cs:522
throw new NopException(warnings.Aggregate(string.Empty, (current, next) => $"{current}{next};"));
//validate individual cart items
foreach (var sci in details.Cart)
{
var product = await _productService.GetProductByIdAsync(sci.ProductId);
var sciWarnings = await _shoppingCartService.GetShoppingCartItemWarningsAsync(details.Customer,
sci.ShoppingCartType, product, processPaymentRequest.StoreId, sci.AttributesXml,
sci.CustomerEnteredPrice, sci.RentalStartDateUtc, sci.RentalEndDateUtc, sci.Quantity, false, sci.Id);
if (sciWarnings.Any())
throw new NopException(sciWarnings.Aggregate(string.Empty, (current, next) => $"{current}{next};"));
}
//min totals validation
if (!await ValidateMinOrderSubtotalAmountAsync(details.Cart))
{
var minOrderSubtotalAmount = await _currencyService.ConvertFromPrimaryStoreCurrencyAsync(_orderSettings.MinOrderSubtotalAmount, currentCurrency);
throw new NopException(string.Format(await _localizationService.GetResourceAsync("Checkout.MinOrderSubtotalAmount"),
await _priceFormatter.FormatPriceAsync(minOrderSubtotalAmount, true, false)));
}
if (!await ValidateMinOrderTotalAmountAsync(details.Cart))
{
var minOrderTotalAmount = await _currencyService.ConvertFromPrimaryStoreCurrencyAsync(_orderSettings.MinOrderTotalAmount, currentCurrency);
throw new NopException(string.Format(await _localizationService.GetResourceAsync("Checkout.MinOrderTotalAmount"),
await _priceFormatter.FormatPriceAsync(minOrderTotalAmount, true, false)));
}
}
/// <summary>
/// Prepare and validate billing address
/// </summary>
/// <param name="details">PlaceOrder container</param>
/// <returns>A task that represents the asynchronous operation</returns>
/// <exception cref="NopException">Validation problems</exception>
protected virtual async Task PrepareAndValidateBillingAddressAsync(PlaceOrderContainer details)
View on GitHub (pinned to 64bdf2ff08)
Solutions
- Increase the cart subtotal by adding items or removing discount codes that push it below the threshold.
- Review and adjust _orderSettings.MinOrderSubtotalAmount in admin (Configuration > Settings > Order settings) if the threshold is too high.
- Display the minimum order requirement prominently on the cart page before the customer proceeds to checkout.
- Set MinOrderSubtotalAmount to 0 if no minimum is desired.
Example fix
// before (admin): orderSettings.MinOrderSubtotalAmount = 50m; cart subtotal = 35m // after: orderSettings.MinOrderSubtotalAmount = 0m; // disable minimum // or: customer adds more items to exceed 50m
Defensive patterns
Strategy: validation
Validate before calling
// Before PlaceOrder, check minimum subtotal
if (await ValidateMinOrderSubtotalAmountAsync(cart) == false)
{
var minAmount = await _currencyService.ConvertFromPrimaryStoreCurrencyAsync(
_orderSettings.MinOrderSubtotalAmount, currentCurrency);
var formatted = await _priceFormatter.FormatPriceAsync(minAmount, true, false);
_notificationService.ErrorNotification(
string.Format(await _localizationService.GetResourceAsync("Checkout.MinOrderSubtotalAmount"), formatted));
return RedirectToRoute("ShoppingCart");
} Type guard
async Task<bool> MeetsMinSubtotalAsync(IShoppingCartService svc, IList<ShoppingCartItem> cart, decimal min) =>
min <= 0 || (await svc.GetShoppingCartSubTotalAsync(cart)).subTotal >= min; Try / catch
try
{
var result = await _orderProcessingService.PlaceOrderAsync(processPaymentRequest);
}
catch (NopException ex) when (ex.Message.Contains("MinOrderSubtotal"))
{
_notificationService.ErrorNotification(ex.Message);
return RedirectToRoute("ShoppingCart");
} Prevention
- Display the minimum order subtotal requirement on the cart page with a live 'amount remaining' indicator.
- Review MinOrderSubtotalAmount setting whenever pricing strategy or shipping cost structure changes.
- Ensure discount codes don't silently reduce the subtotal below the minimum — warn at apply time.
- Set MinOrderSubtotalAmount to 0 if no minimum is required to avoid false positives.
When it happens
Trigger: The store has MinOrderSubtotalAmount configured (e.g. $50) and the customer's cart subtotal (after item-level discounts but before order-level discounts) falls below it. The setting was increased after the customer added items. The subtotal calculation is affected by tax inclusion settings reducing the visible subtotal.
Common situations: Admin set a minimum order value to cover shipping/handling costs. A customer applies a discount code that brings the subtotal below the minimum. Tax display settings make the subtotal appear higher than the pre-tax subtotal used for validation. A B2B store with a minimum order requirement.
Related errors
- Checkout.MinOrderTotalAmount
- Shipping address is not provided
- Country '{shippingCountry.Name}' is not allowed for shipping
- Cart is empty
- {warning1};{warning2};...
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/a3ca35aeb8f0ef8c.
Report an issue: GitHub.