nopSolutions/nopCommerce · error · NopException
Anonymous checkout is not allowed
Error message
Anonymous checkout is not allowed
What it means
Thrown by PrepareAndValidateCustomerAsync during the standard PlaceOrder flow when the customer is a guest (IsGuestAsync returns true) and _orderSettings.AnonymousCheckoutAllowed is false. This enforces the store's policy on whether guest (non-registered) customers can complete purchases. If disabled, customers must register and log in before placing an order.
Source
Thrown at src/Libraries/Nop.Services/Orders/OrderProcessingService.cs:573
/// <summary>
/// Prepare and validate customer
/// </summary>
/// <param name="details">PlaceOrder container</param>
/// <param name="processPaymentRequest">payment info holder</param>
/// <param name="currentCurrency">The working currency</param>
/// <returns>A task that represents the asynchronous operation</returns>
/// <exception cref="NopException">Validation problems</exception>
protected virtual async Task PrepareAndValidateCustomerAsync(PlaceOrderContainer details, ProcessPaymentRequest processPaymentRequest, Currency currentCurrency)
{
details.Customer = await _customerService.GetCustomerByIdAsync(processPaymentRequest.CustomerId);
if (details.Customer == null)
throw new ArgumentException("Customer is not set");
//check whether customer is guest
if (await _customerService.IsGuestAsync(details.Customer) && !_orderSettings.AnonymousCheckoutAllowed)
throw new NopException("Anonymous checkout is not allowed");
//customer currency
var currencyTmp = await _currencyService.GetCurrencyByIdAsync(details.Customer.CurrencyId ?? 0);
var customerCurrency = currencyTmp != null && currencyTmp.Published && await _storeMappingService.AuthorizeAsync(currencyTmp) ? currencyTmp : currentCurrency;
var primaryStoreCurrency = await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId);
details.CustomerCurrencyCode = customerCurrency.CurrencyCode;
details.CustomerCurrencyRate = customerCurrency.Rate / primaryStoreCurrency.Rate;
//customer language
details.CustomerLanguage = await _languageService.GetLanguageByIdAsync(details.Customer.LanguageId ?? 0);
if (details.CustomerLanguage == null || !details.CustomerLanguage.Published || !await _storeMappingService.AuthorizeAsync(details.CustomerLanguage))
details.CustomerLanguage = await _workContext.GetWorkingLanguageAsync();
}
/// <summary>
/// Prepare details to place order based on the recurring payment.
/// </summary>
/// <param name="processPaymentRequest">Process payment request</param>
View on GitHub (pinned to 64bdf2ff08)
Solutions
- Enable anonymous checkout in admin: Configuration > Settings > Order settings > 'Anonymous checkout allowed'.
- Require the customer to register/log in before reaching the payment step.
- Extend session timeout or implement a 'keep alive' to prevent mid-checkout authentication loss.
- In custom integrations, ensure the ProcessPaymentRequest.CustomerId refers to a registered (non-guest) customer.
Example fix
// before (admin): orderSettings.AnonymousCheckoutAllowed = false // after: orderSettings.AnonymousCheckoutAllowed = true; await _settingService.SaveSettingAsync(orderSettings, x => x.AnonymousCheckoutAllowed);
Defensive patterns
Strategy: validation
Validate before calling
// Before PlaceOrder, check guest + anonymous checkout policy
var customer = await _customerService.GetCustomerByIdAsync(processPaymentRequest.CustomerId);
if (await _customerService.IsGuestAsync(customer) && !_orderSettings.AnonymousCheckoutAllowed)
{
_notificationService.ErrorNotification("Please register or log in to complete your order.");
return RedirectToRoute("Login");
} Type guard
async Task<bool> CanCheckoutAsync(ICustomerService svc, Customer c, bool anonAllowed) =>
!await svc.IsGuestAsync(c) || anonAllowed; Try / catch
try
{
var result = await _orderProcessingService.PlaceOrderAsync(processPaymentRequest);
}
catch (NopException ex) when (ex.Message == "Anonymous checkout is not allowed")
{
return RedirectToRoute("Login");
} Prevention
- Check anonymous checkout policy early in the checkout flow and redirect guests to login/register.
- If enabling/disabling anonymous checkout, communicate the change to customers beforehand.
- Extend session timeout or add keep-alive to prevent mid-checkout authentication loss.
- In custom integrations, ensure ProcessPaymentRequest.CustomerId refers to a registered customer when anonymous checkout is disabled.
When it happens
Trigger: A guest user (not logged in) attempts to check out while the 'Anonymous checkout allowed' setting is disabled in Order settings. The setting was changed from true to false after guest customers added items to their carts. A customer's session lost authentication and they reverted to guest status mid-checkout.
Common situations: B2B stores that require account registration. Admin disabled anonymous checkout to improve order tracking or comply with regulations. Session timeout caused an authenticated customer's session to expire, reverting them to guest status. A custom integration passing a guest CustomerId to PlaceOrder.
Related errors
- Country '{shippingCountry.Name}' is not allowed for shipping
- Checkout.MinOrderSubtotalAmount
- Checkout.MinOrderTotalAmount
- Country '{billingCountry.Name}' is not allowed for billing
- Failed to obtain user credentials for the authorization serv
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/a88ed3a41f6bfdb4.
Report an issue: GitHub.