{"record":{"id":"b43e9dbb260250ab","repo":"nopSolutions/nopCommerce","slug":"payment-method-is-not-selected","errorCode":null,"errorMessage":"Payment method is not selected","messagePattern":"Payment method is not selected","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Presentation/Nop.Web/Controllers/CheckoutController.cs","lineNumber":1978,"sourceCode":"\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            var paymentMethodSystemName = await _genericAttributeService.GetAttributeAsync<string>(customer,\r\n                NopCustomerDefaults.SelectedPaymentMethodAttribute, store.Id);\r\n            var paymentMethod = await _paymentPluginManager\r\n                                    .LoadPluginBySystemNameAsync(paymentMethodSystemName, customer, store.Id)\r\n                                ?? throw new Exception(\"Payment method is not selected\");\r\n\r\n            var warnings = await paymentMethod.ValidatePaymentFormAsync(form);\r\n            foreach (var warning in warnings)\r\n                ModelState.AddModelError(\"\", warning);\r\n            if (ModelState.IsValid)\r\n            {\r\n                await _orderProcessingService.SetProcessPaymentRequestAsync(await paymentMethod.GetPaymentInfoAsync(form));\r\n\r\n                var confirmOrderModel = await _checkoutModelFactory.PrepareConfirmOrderModelAsync(cart);\r\n                return Json(new\r\n                {\r\n                    update_section = new UpdateSectionJsonModel\r\n                    {\r\n                        name = \"confirm-order\",\r\n                        html = await RenderPartialViewToStringAsync(\"OpcConfirmOrder\", confirmOrderModel)\r\n                    },\r\n                    goto_section = \"confirm_order\"\r\n                });\r","sourceCodeStart":1960,"sourceCodeEnd":1996,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Presentation/Nop.Web/Controllers/CheckoutController.cs#L1960-L1996","documentation":"Thrown in OpcSavePaymentInfo when the previously-selected payment method cannot be loaded. The code reads SelectedPaymentMethodAttribute from the customer's generic attributes; if it is null/empty or the system name does not resolve to a plugin, LoadPluginBySystemNameAsync returns null and the ?? operator throws.","triggerScenarios":"Customer reaches payment-info step without having selected a payment method first (SelectedPaymentMethodAttribute is null), or the selected method's plugin was uninstalled/disabled between selection and payment-info submission (line ~1978).","commonSituations":"Customer skipped/back-navigated past the payment method selection step; the generic attribute was never saved due to an earlier error; the payment plugin was removed by an admin; OPC flow state lost on session restart.","solutions":["Ensure the customer completes the payment method selection step (OpcSelectPaymentMethod) before payment-info; redirect back if SelectedPaymentMethodAttribute is missing.","Verify the selected payment plugin is installed and active for the current store/customer.","Validate the attribute exists server-side before invoking the plugin manager and surface a clear redirect."],"exampleFix":"// before\nvar paymentMethod = await _paymentPluginManager\n        .LoadPluginBySystemNameAsync(paymentMethodSystemName, customer, store.Id)\n    ?? throw new Exception(\"Payment method is not selected\");\n\n// after\nif (string.IsNullOrEmpty(paymentMethodSystemName))\n    return Json(new { error = 1, goto_section = \"payment_method\" });\nvar paymentMethod = await _paymentPluginManager\n        .LoadPluginBySystemNameAsync(paymentMethodSystemName, customer, store.Id);\nif (paymentMethod == null)\n    return Json(new { error = 1, goto_section = \"payment_method\" });","handlingStrategy":"validation","validationCode":"// Validate the stored payment method attribute before loading the plugin\nvar sysName = await _genericAttributeService.GetAttributeAsync<string>(customer, NopCustomerDefaults.SelectedPaymentMethodAttribute, store.Id);\nif (string.IsNullOrWhiteSpace(sysName))\n    return Json(new { error = 1, goto_section = \"payment_method\" });","typeGuard":"static bool IsValidSystemName(string s) => !string.IsNullOrWhiteSpace(s) && s.Contains('.');","tryCatchPattern":"catch (Exception exc) when (exc.Message == \"Payment method is not selected\")\n{\n    return Json(new { error = 1, goto_section = \"payment_method\" });\n}","preventionTips":["Enforce step ordering in the OPC flow so payment-info cannot be reached without payment-method selection.","Use distributed session/generic-attribute storage in load-balanced setups so selection persists.","Clear stale SelectedPaymentMethodAttribute when a payment plugin is uninstalled."],"tags":["nopcommerce","checkout","opc","payment-method","generic-attribute"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}