nopSolutions/nopCommerce · warning · Exception

Checkout.Disabled

Error message

Checkout.Disabled

What it means

Thrown at the start of OpcSaveBilling (one-page checkout billing save) when _orderSettings.CheckoutDisabled is true. The message is the localized 'Checkout.Disabled' resource, i.e., the store administrator has turned off checkout globally. The exception is caught downstream and surfaced as JSON. It is a configuration gate, not a runtime fault: checkout is intentionally closed.

Source

Thrown at src/Presentation/Nop.Web/Controllers/CheckoutController.cs:1525

        if (!_orderSettings.OnePageCheckoutEnabled)
            return RedirectToRoute(NopRouteNames.Standard.CHECKOUT);

        if (await _customerService.IsGuestAsync(customer) && !_orderSettings.AnonymousCheckoutAllowed)
            return Challenge();

        var model = await _checkoutModelFactory.PrepareOnePageCheckoutModelAsync(cart);
        return View(model);
    }

    [HttpPost]
    public virtual async Task<IActionResult> OpcSaveBilling(CheckoutBillingAddressModel model, IFormCollection form)
    {
        try
        {
            //validation
            if (_orderSettings.CheckoutDisabled)
                throw new Exception(await _localizationService.GetResourceAsync("Checkout.Disabled"));

            var customer = await _workContext.GetCurrentCustomerAsync();
            var store = await _storeContext.GetCurrentStoreAsync();
            var cart = await _shoppingCartService.GetShoppingCartAsync(customer, ShoppingCartType.ShoppingCart, store.Id);

            if (!cart.Any())
                throw new Exception("Your cart is empty");

            if (!_orderSettings.OnePageCheckoutEnabled)
                throw new Exception("One page checkout is disabled");

            if (await _customerService.IsGuestAsync(customer) && !_orderSettings.AnonymousCheckoutAllowed)
                throw new Exception("Anonymous checkout is not allowed");

            _ = int.TryParse(form["billing_address_id"], out var billingAddressId);

            if (billingAddressId > 0)
            {

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Re-enable checkout in OrderSettings (set CheckoutDisabled = false) when the store is ready.
  2. If intentionally disabled, ensure the storefront hides/disables the checkout entry so these POSTs do not occur.
  3. Clear storefront cache and reload after toggling so the disabled state is consistent.
  4. Return a clear localized 'checkout is currently unavailable' page instead of a thrown exception on the AJAX path.

Example fix

// before
if (_orderSettings.CheckoutDisabled)
    throw new Exception(await _localizationService.GetResourceAsync("Checkout.Disabled"));
// after (redirect for the AJAX path)
if (_orderSettings.CheckoutDisabled)
    return Json(new { redirect = Url.RouteUrl(NopRouteNames.General.CART) });
Defensive patterns

Strategy: validation

Validate before calling

// Gate the OPC path on configuration without throwing.
if (_orderSettings.CheckoutDisabled)
    return Json(new { redirect = Url.RouteUrl(NopRouteNames.General.CART) });

Try / catch

// Wrapped downstream; returns JSON error. Prefer the redirect pattern above.

Prevention

When it happens

Trigger: OrderSettings.CheckoutDisabled = true (admin toggled 'Disable checkout' in configuration settings), and a customer's OPC billing save request reaches OpcSaveBilling. The POST is rejected with the disabled-checkout message.

Common situations: Store in maintenance mode or pre-launch with checkout disabled; admin disabled checkout during an incident but the storefront still received OPC AJAX calls; misconfiguration where CheckoutDisabled was set and forgotten; cached client still attempting checkout after the toggle.

Related errors


AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13). Data as JSON: /api/errors/ffb7b88e0cb5a621. Report an issue: GitHub.