{"record":{"id":"25fc341a10b2de70","repo":"nopSolutions/nopCommerce","slug":"one-page-checkout-is-disabled","errorCode":null,"errorMessage":"One page checkout is disabled","messagePattern":"One page checkout is disabled","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Presentation/Nop.Web/Controllers/CheckoutController.cs","lineNumber":1535,"sourceCode":"\r\n    [HttpPost]\r\n    public virtual async Task<IActionResult> OpcSaveBilling(CheckoutBillingAddressModel model, IFormCollection form)\r\n    {\r\n        try\r\n        {\r\n            //validation\r\n            if (_orderSettings.CheckoutDisabled)\r\n                throw new Exception(await _localizationService.GetResourceAsync(\"Checkout.Disabled\"));\r\n\r\n            var customer = await _workContext.GetCurrentCustomerAsync();\r\n            var store = await _storeContext.GetCurrentStoreAsync();\r\n            var cart = await _shoppingCartService.GetShoppingCartAsync(customer, ShoppingCartType.ShoppingCart, store.Id);\r\n\r\n            if (!cart.Any())\r\n                throw new Exception(\"Your cart is empty\");\r\n\r\n            if (!_orderSettings.OnePageCheckoutEnabled)\r\n                throw new Exception(\"One page checkout is disabled\");\r\n\r\n            if (await _customerService.IsGuestAsync(customer) && !_orderSettings.AnonymousCheckoutAllowed)\r\n                throw new Exception(\"Anonymous checkout is not allowed\");\r\n\r\n            _ = int.TryParse(form[\"billing_address_id\"], out var billingAddressId);\r\n\r\n            if (billingAddressId > 0)\r\n            {\r\n                //existing address\r\n                var address = await _customerService.GetCustomerAddressAsync(customer.Id, billingAddressId)\r\n                              ?? throw new Exception(await _localizationService.GetResourceAsync(\"Checkout.Address.NotFound\"));\r\n\r\n                customer.BillingAddressId = address.Id;\r\n                await _customerService.UpdateCustomerAsync(customer);\r\n            }\r\n            else\r\n            {\r\n                if (await _customerService.IsGuestAsync(customer) && _taxSettings.EuVatEnabled && _taxSettings.EuVatEnabledForGuests)\r","sourceCodeStart":1517,"sourceCodeEnd":1553,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Presentation/Nop.Web/Controllers/CheckoutController.cs#L1517-L1553","documentation":"Thrown by the OpcSaveBilling action when _orderSettings.OnePageCheckoutEnabled is false, yet a one-page-checkout (OPC) AJAX POST was received. nopCommerce guards every OPC step with this check so a store running multi-page checkout cannot be driven through OPC endpoints. The message is a hardcoded English literal returned inside the JSON error payload { error=1, message }. It indicates a configuration/flow mismatch, not a malformed request.","triggerScenarios":"A client POSTs to the OpcSaveBilling billing step while _orderSettings.OnePageCheckoutEnabled == false. Typical when an admin disabled OPC but a shopper's stale browser tab still renders the OPC UI, or a custom integration calls OpcSaveBilling directly against a multi-page-checkout store.","commonSituations":"Admin toggled 'One page checkout enabled' off (Configuration > Order settings); a theme deployed that defaults to standard multi-page checkout; CDN/page cache still serving the old OPC page after the switch; integration tests calling OPC endpoints after a config change.","solutions":["Enable OnePageCheckoutEnabled in admin (Order settings) if OPC is the intended flow.","If OPC is intentionally off, ensure clients never call OpcSaveBilling: redirect the OPC page to the standard BillingAddress action.","Purge output/CDN cache so browsers stop posting to OPC endpoints after the setting flipped.","If a custom theme hardcodes OPC AJAX calls, switch it to the multi-page controller flow."],"exampleFix":"// before (admin Order settings)\norderSettings.OnePageCheckoutEnabled = false;\n// after\norderSettings.OnePageCheckoutEnabled = true; // enables OpcSaveBilling/OpcSaveShipping/etc.","handlingStrategy":"validation","validationCode":"// Client: only render/submit the OPC billing step when OPC is on.\nconst settings = await fetch('/api/checkout-settings').then(r => r.json());\nif (!settings.onePageCheckoutEnabled) { location.href = '/checkout/billingaddress'; return; }","typeGuard":null,"tryCatchPattern":"// The controller wraps the action in try/catch and returns JSON; handle it.\nconst res = await fetch('/Checkout/OpcSaveBilling', { method:'POST', body });\nconst data = await res.json();\nif (data.error) {\n  if (data.message === 'One page checkout is disabled') location.href = '/checkout/billingaddress';\n  else showUserError(data.message);\n}","preventionTips":["Read OnePageCheckoutEnabled before rendering OPC UI and redirect otherwise.","Version-bust cached OPC pages on deploy so stale tabs reload.","Avoid hardcoding OPC AJAX in custom themes; respect the setting."],"tags":["checkout","opc","config","validation","nopcommerce"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}