{"record":{"id":"856cd67222d6c2cf","repo":"nopSolutions/nopCommerce","slug":"cart-is-empty","errorCode":null,"errorMessage":"Cart is empty","messagePattern":"Cart is empty","errorType":"validation","errorClass":"NopException","httpStatus":null,"severity":"error","filePath":"src/Libraries/Nop.Services/Orders/OrderProcessingService.cs","lineNumber":499,"sourceCode":"    /// <summary>\r\n    /// Prepare and validate shopping cart and checkout attributes\r\n    /// </summary>\r\n    /// <param name=\"details\">PlaceOrder container</param>\r\n    /// <param name=\"processPaymentRequest\">payment info holder</param>\r\n    /// <param name=\"currentCurrency\">The working currency</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 PrepareAndValidateShoppingCartAndCheckoutAttributesAsync(PlaceOrderContainer details, ProcessPaymentRequest processPaymentRequest, Currency currentCurrency)\r\n    {\r\n        //checkout attributes\r\n        details.CheckoutAttributesXml = await _genericAttributeService.GetAttributeAsync<string>(details.Customer, NopCustomerDefaults.CheckoutAttributes, processPaymentRequest.StoreId);\r\n        details.CheckoutAttributeDescription = await _checkoutAttributeFormatter.FormatAttributesAsync(details.CheckoutAttributesXml, details.Customer);\r\n\r\n        //load shopping cart\r\n        details.Cart = await _shoppingCartService.GetShoppingCartAsync(details.Customer, ShoppingCartType.ShoppingCart, processPaymentRequest.StoreId);\r\n\r\n        if (!details.Cart.Any())\r\n            throw new NopException(\"Cart is empty\");\r\n\r\n        //validate the entire shopping cart\r\n        var warnings = await _shoppingCartService.GetShoppingCartWarningsAsync(details.Cart, details.CheckoutAttributesXml, true);\r\n        if (warnings.Any())\r\n            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","sourceCodeStart":481,"sourceCodeEnd":517,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Orders/OrderProcessingService.cs#L481-L517","documentation":"Thrown by PrepareAndValidateShoppingCartAndCheckoutAttributesAsync when the customer's shopping cart (loaded by type ShoppingCart and store) contains no items. An empty cart cannot produce an order, so this is the first sanity check in the PlaceOrder pipeline.","triggerScenarios":"PlaceOrder or ProcessPayment is invoked when the customer has no active shopping cart items for the current store. The cart was emptied (items purchased or removed) between the checkout review page and the payment submission. A programmatic payment request was created with a stale CustomerId or StoreId that doesn't match the cart.","commonSituations":"Double-click or double-submit of the payment button where the first request completes and empties the cart. Session timeout causing the cart reference to become stale. A custom integration building a ProcessPaymentRequest manually without ensuring cart items exist. Store-mismatch where the cart was created under one store and PlaceOrder runs under another.","solutions":["Guard the payment submission with a client-side check that disables the button after first click and verifies cart count.","In custom integrations, verify IShoppingCartService.GetShoppingCartAsync returns items before constructing the payment request.","Ensure the StoreId on the ProcessPaymentRequest matches the store where cart items were added.","Redirect users with an empty cart away from the payment page."],"exampleFix":"// before: var result = await _orderProcessingService.PlaceOrderAsync(processPaymentRequest);\n// after:\nvar cart = await _shoppingCartService.GetShoppingCartAsync(customer, ShoppingCartType.ShoppingCart, storeId);\nif (!cart.Any())\n    return; // or redirect to cart page\nvar result = await _orderProcessingService.PlaceOrderAsync(processPaymentRequest);","handlingStrategy":"validation","validationCode":"// Before PlaceOrder, confirm the cart has items\nvar cart = await _shoppingCartService.GetShoppingCartAsync(\n    customer, ShoppingCartType.ShoppingCart, storeId);\nif (!cart.Any())\n{\n    _notificationService.ErrorNotification(\"Your cart is empty.\");\n    return RedirectToRoute(\"ShoppingCart\");\n}","typeGuard":"bool CartHasItems(IList<ShoppingCartItem> cart) => cart != null && cart.Count > 0;","tryCatchPattern":"try\n{\n    var result = await _orderProcessingService.PlaceOrderAsync(processPaymentRequest);\n}\ncatch (NopException ex) when (ex.Message == \"Cart is empty\")\n{\n    return RedirectToRoute(\"ShoppingCart\");\n}","preventionTips":["Disable the payment submit button after first click (prevent double-submit that empties the cart).","Redirect away from the payment page if the cart is empty.","In custom integrations, always verify cart items exist before constructing a ProcessPaymentRequest.","Ensure the StoreId on the payment request matches the store where cart items were added.","Use optimistic concurrency or a lock to prevent duplicate PlaceOrder calls for the same cart."],"tags":["nopcommerce","empty-cart","checkout","validation","order-processing"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}