{"record":{"id":"a3ca35aeb8f0ef8c","repo":"nopSolutions/nopCommerce","slug":"checkout-minordersubtotalamount","errorCode":null,"errorMessage":"Checkout.MinOrderSubtotalAmount","messagePattern":"Checkout\\.MinOrderSubtotalAmount","errorType":"validation","errorClass":"NopException","httpStatus":null,"severity":"warning","filePath":"src/Libraries/Nop.Services/Orders/OrderProcessingService.cs","lineNumber":522,"sourceCode":"            throw new NopException(warnings.Aggregate(string.Empty, (current, next) => $\"{current}{next};\"));\r\n\r\n        //validate individual cart items\r\n        foreach (var sci in details.Cart)\r\n        {\r\n            var product = await _productService.GetProductByIdAsync(sci.ProductId);\r\n\r\n            var sciWarnings = await _shoppingCartService.GetShoppingCartItemWarningsAsync(details.Customer,\r\n                sci.ShoppingCartType, product, processPaymentRequest.StoreId, sci.AttributesXml,\r\n                sci.CustomerEnteredPrice, sci.RentalStartDateUtc, sci.RentalEndDateUtc, sci.Quantity, false, sci.Id);\r\n            if (sciWarnings.Any())\r\n                throw new NopException(sciWarnings.Aggregate(string.Empty, (current, next) => $\"{current}{next};\"));\r\n        }\r\n\r\n        //min totals validation\r\n        if (!await ValidateMinOrderSubtotalAmountAsync(details.Cart))\r\n        {\r\n            var minOrderSubtotalAmount = await _currencyService.ConvertFromPrimaryStoreCurrencyAsync(_orderSettings.MinOrderSubtotalAmount, currentCurrency);\r\n            throw new NopException(string.Format(await _localizationService.GetResourceAsync(\"Checkout.MinOrderSubtotalAmount\"),\r\n                await _priceFormatter.FormatPriceAsync(minOrderSubtotalAmount, true, false)));\r\n        }\r\n\r\n        if (!await ValidateMinOrderTotalAmountAsync(details.Cart))\r\n        {\r\n            var minOrderTotalAmount = await _currencyService.ConvertFromPrimaryStoreCurrencyAsync(_orderSettings.MinOrderTotalAmount, currentCurrency);\r\n            throw new NopException(string.Format(await _localizationService.GetResourceAsync(\"Checkout.MinOrderTotalAmount\"),\r\n                await _priceFormatter.FormatPriceAsync(minOrderTotalAmount, true, false)));\r\n        }\r\n    }\r\n\r\n    /// <summary>\r\n    /// Prepare and validate billing address\r\n    /// </summary>\r\n    /// <param name=\"details\">PlaceOrder container</param>\r\n    /// <returns>A task that represents the asynchronous operation</returns>\r\n    /// <exception cref=\"NopException\">Validation problems</exception>\r\n    protected virtual async Task PrepareAndValidateBillingAddressAsync(PlaceOrderContainer details)\r","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Orders/OrderProcessingService.cs#L504-L540","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (admin): orderSettings.MinOrderSubtotalAmount = 50m; cart subtotal = 35m\n// after: orderSettings.MinOrderSubtotalAmount = 0m;  // disable minimum\n// or: customer adds more items to exceed 50m","handlingStrategy":"validation","validationCode":"// Before PlaceOrder, check minimum subtotal\nif (await ValidateMinOrderSubtotalAmountAsync(cart) == false)\n{\n    var minAmount = await _currencyService.ConvertFromPrimaryStoreCurrencyAsync(\n        _orderSettings.MinOrderSubtotalAmount, currentCurrency);\n    var formatted = await _priceFormatter.FormatPriceAsync(minAmount, true, false);\n    _notificationService.ErrorNotification(\n        string.Format(await _localizationService.GetResourceAsync(\"Checkout.MinOrderSubtotalAmount\"), formatted));\n    return RedirectToRoute(\"ShoppingCart\");\n}","typeGuard":"async Task<bool> MeetsMinSubtotalAsync(IShoppingCartService svc, IList<ShoppingCartItem> cart, decimal min) =>\n    min <= 0 || (await svc.GetShoppingCartSubTotalAsync(cart)).subTotal >= min;","tryCatchPattern":"try\n{\n    var result = await _orderProcessingService.PlaceOrderAsync(processPaymentRequest);\n}\ncatch (NopException ex) when (ex.Message.Contains(\"MinOrderSubtotal\"))\n{\n    _notificationService.ErrorNotification(ex.Message);\n    return RedirectToRoute(\"ShoppingCart\");\n}","preventionTips":["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."],"tags":["nopcommerce","minimum-order","subtotal","business-rule","checkout","order-processing"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}