{"record":{"id":"78f7e69e7bb769d0","repo":"nopSolutions/nopCommerce","slug":"checkout-minorderplacementinterval-78f7e6","errorCode":null,"errorMessage":"Checkout.MinOrderPlacementInterval","messagePattern":"Checkout\\.MinOrderPlacementInterval","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"src/Presentation/Nop.Web/Controllers/CheckoutController.cs","lineNumber":1314,"sourceCode":"\r\n        //model\r\n        var model = await _checkoutModelFactory.PrepareConfirmOrderModelAsync(cart);\r\n\r\n        var isCaptchaSettingEnabled = await _customerService.IsGuestAsync(customer) &&\r\n                                      _captchaSettings.Enabled && _captchaSettings.ShowOnCheckoutPageForGuests;\r\n\r\n        //captcha validation for guest customers\r\n        if (isCaptchaSettingEnabled && !captchaValid)\r\n        {\r\n            model.Warnings.Add(await _localizationService.GetResourceAsync(\"Common.WrongCaptchaMessage\"));\r\n            return View(model);\r\n        }\r\n\r\n        try\r\n        {\r\n            //prevent 2 orders being placed within an X seconds time frame\r\n            if (!await IsMinimumOrderPlacementIntervalValidAsync(customer))\r\n                throw new Exception(await _localizationService.GetResourceAsync(\"Checkout.MinOrderPlacementInterval\"));\r\n\r\n            //place order\r\n            var processPaymentRequest = await _orderProcessingService.GetProcessPaymentRequestAsync();\r\n            if (processPaymentRequest == null)\r\n            {\r\n                //Check whether payment workflow is required\r\n                if (await _orderProcessingService.IsPaymentWorkflowRequiredAsync(cart))\r\n                    return RedirectToRoute(NopRouteNames.Standard.CHECKOUT_PAYMENT_INFO);\r\n\r\n                processPaymentRequest = new ProcessPaymentRequest();\r\n            }\r\n\r\n            processPaymentRequest.StoreId = store.Id;\r\n            processPaymentRequest.CustomerId = customer.Id;\r\n            processPaymentRequest.PaymentMethodSystemName = await _genericAttributeService.GetAttributeAsync<string>(customer,\r\n                NopCustomerDefaults.SelectedPaymentMethodAttribute, store.Id);\r\n            await _orderProcessingService.SetProcessPaymentRequestAsync(processPaymentRequest);\r\n            var placeOrderResult = await _orderProcessingService.PlaceOrderAsync(processPaymentRequest);\r","sourceCodeStart":1296,"sourceCodeEnd":1332,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Presentation/Nop.Web/Controllers/CheckoutController.cs#L1296-L1332","documentation":"Thrown during order placement (the checkout confirm flow) when IsMinimumOrderPlacementIntervalValidAsync returns false — i.e., the same customer is trying to place a second order within the configured MinimumOrderPlacementInterval window. The exception message is the localized resource 'Checkout.MinOrderPlacementInterval' (a customer-facing 'please wait' string). It is an anti-fraud/anti-double-submit throttle, not a data error.","triggerScenarios":"A customer submits the checkout confirm twice in quick succession (double-click, retry, or scripted) within the MinimumOrderPlacementInterval seconds. The second submission hits this guard and throws the localized interval message.","commonSituations":"Customer double-clicks the 'Place Order' button; network retry resubmits; automated/bot checkout testing fires rapidly; the interval setting is too high for legitimate fast repeat orders; frontend does not disable the button after first click.","solutions":["Disable the 'Place Order' button immediately after the first click to prevent double submission.","Wait the configured MinimumOrderPlacementInterval (OrderSettings) and retry if the order genuinely did not go through.","Lower MinimumOrderPlacementInterval in OrderSettings if legitimate fast repeat orders are being blocked.","Confirm the first submission's result before retrying to avoid duplicate orders."],"exampleFix":"// before\nif (!await IsMinimumOrderPlacementIntervalValidAsync(customer))\n    throw new Exception(await _localizationService.GetResourceAsync(\"Checkout.MinOrderPlacementInterval\"));\n// after (treat as warning, not a thrown exception)\nif (!await IsMinimumOrderPlacementIntervalValidAsync(customer))\n{\n    model.Warnings.Add(await _localizationService.GetResourceAsync(\"Checkout.MinOrderPlacementInterval\"));\n    return View(model);\n}","handlingStrategy":"validation","validationCode":"// Check the interval client-side and disable the button after first click.\n// Server-side, treat as a warning rather than throwing:\nif (!await IsMinimumOrderPlacementIntervalValidAsync(customer))\n{\n    model.Warnings.Add(await _localizationService.GetResourceAsync(\"Checkout.MinOrderPlacementInterval\"));\n    return View(model);\n}","typeGuard":null,"tryCatchPattern":"// The placement try/catch surfaces this as an order warning; verify the first order succeeded before retrying.\ncatch (Exception ex) when (ex.Message.Contains(\"MinOrderPlacementInterval\"))\n{ /* show 'please wait' message */ }","preventionTips":["Disable the 'Place Order' button immediately after first click.","Confirm the first submission's outcome before retrying to avoid duplicate orders.","Tune MinimumOrderPlacementInterval in OrderSettings to fit legitimate repeat-order speed."],"tags":["nopcommerce","checkout","order","throttle","anti-fraud","double-submit","localization"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}