{"record":{"id":"023739763d127b12","repo":"nopSolutions/nopCommerce","slug":"anonymous-checkout-disabled-for-recurring-items","errorCode":null,"errorMessage":"Anonymous checkout disabled for recurring items","messagePattern":"Anonymous checkout disabled for recurring items","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"error","filePath":"src/Plugins/Nop.Plugin.Payments.PayPalCommerce/Services/PayPalCommerceServiceManager.cs","lineNumber":1651,"sourceCode":"\n            if (string.IsNullOrEmpty(settings.MerchantId))\n                throw new NopException(\"Merchant PayPal ID not set\");\n\n            var details = await PrepareCartDetailsAsync(placement);\n\n            var savedPaymentToken = await _tokenService.GetByIdAsync(cardId ?? 0);\n            if (savedPaymentToken is not null && savedPaymentToken.CustomerId != details.Customer.Id)\n                throw new NopException(\"Card details not found\");\n\n            var isGuest = await _customerService.IsGuestAsync(details.Customer);\n            var isRecurring = await _shoppingCartService.ShoppingCartIsRecurringAsync(details.Cart);\n            if (isRecurring)\n            {\n                if (!settings.UseVault)\n                    throw new NopException(\"Vault disabled\");\n\n                if (isGuest)\n                    throw new NopException(\"Anonymous checkout disabled for recurring items\");\n\n                var (error, cycleLength, cyclePeriod, totalCycles) = await _shoppingCartService.GetRecurringCycleInfoAsync(details.Cart);\n                if (!string.IsNullOrEmpty(error))\n                    throw new NopException(error);\n            }\n\n            var paymentRequest = await _orderProcessingService.GetProcessPaymentRequestAsync();\n            var (order, _) = await GetCreatedOrderAsync(settings, paymentRequest, placement, details.ShippingIsRequired, paymentSource);\n            if (paymentRequest is null || order is null)\n                paymentRequest = new();\n\n            //prepare purchase unit\n            var purchaseUnit = await PreparePurchaseUnitAsync(settings, details, paymentRequest.OrderGuid.ToString());\n\n            //whether we should create a new order\n            if (order is null || isRecurring)\n            {\n                var isCard = string.Equals(paymentSource, nameof(PaymentSource.Card), StringComparison.InvariantCultureIgnoreCase);","sourceCodeStart":1633,"sourceCodeEnd":1669,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Plugins/Nop.Plugin.Payments.PayPalCommerce/Services/PayPalCommerceServiceManager.cs#L1633-L1669","documentation":"Thrown in CreateOrderAsync when the cart contains recurring items, the customer is a guest (not logged in), and recurring billing is active. Vault-based recurring payments require a registered customer account to associate payment tokens; guest checkout cannot persist tokens for future billing cycles.","triggerScenarios":"isRecurring is true and isGuest is true — ShoppingCartIsRecurringAsync returned true and CustomerService.IsGuestAsync returned true for the current customer.","commonSituations":"A guest customer added a subscription or recurring product to the cart; the store allows guest checkout but recurring products require an account; the customer is not logged in or their session expired and they became a guest.","solutions":["Require customers to log in or create an account before adding recurring products to the cart","Add a UI guard on the product page for recurring items that requires authentication before 'Add to cart'","Configure nopCommerce to disable guest checkout globally if the store sells recurring products","Redirect guest customers with recurring items to the login/registration page before checkout"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check if guest customer has recurring items before checkout\nvar isRecurring = await _shoppingCartService.ShoppingCartIsRecurringAsync(cart);\nvar isGuest = await _customerService.IsGuestAsync(customer);\nif (isRecurring && isGuest)\n{\n    return Redirect(\"/login?returnUrl=\" + Url.Action(\"Checkout\"));\n}","typeGuard":"static bool CanGuestCheckout(bool isRecurring, bool isGuest)\n    => !isRecurring || !isGuest;","tryCatchPattern":"var (order, error) = await manager.CreateOrderAsync(settings, placement, paymentSource, cardId, saveCard);\nif (!string.IsNullOrEmpty(error) && error.Contains(\"Anonymous checkout disabled\"))\n    return RedirectToRoute(\"Login\", new { returnUrl = \"/checkout\" });","preventionTips":["Require authentication before adding recurring products to the cart","Disable guest checkout if the store sells recurring products","Add UI indicators on recurring product pages requiring login"],"tags":["recurring","guest-checkout","authentication","vault","paypal-commerce","nopcommerce"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}