{"record":{"id":"5daac309c4cb4c8e","repo":"nopSolutions/nopCommerce","slug":"processpaymentresult-is-not-available","errorCode":null,"errorMessage":"processPaymentResult is not available","messagePattern":"processPaymentResult is not available","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"critical","filePath":"src/Libraries/Nop.Services/Orders/OrderProcessingService.cs","lineNumber":1953,"sourceCode":"                    throw new NopException(\"Payment method is not active\");\r\n\r\n                //payment type\r\n                processPaymentResult = (await _paymentService.GetRecurringPaymentTypeAsync(processPaymentRequest.PaymentMethodSystemName)) switch\r\n                {\r\n                    RecurringPaymentType.NotSupported => throw new NopException(\"Recurring payments are not supported by selected payment method\"),\r\n                    RecurringPaymentType.Manual => await _paymentService.ProcessRecurringPaymentAsync(processPaymentRequest),\r\n                    //payment is processed on payment gateway site, info about last transaction in paymentResult parameter\r\n                    RecurringPaymentType.Automatic => paymentResult ?? new ProcessPaymentResult(),\r\n                    _ => throw new NopException(\"Not supported recurring payment type\"),\r\n                };\r\n            }\r\n            else\r\n            {\r\n                processPaymentResult = paymentResult ?? new ProcessPaymentResult { NewPaymentStatus = PaymentStatus.Paid };\r\n            }\r\n\r\n            if (processPaymentResult == null)\r\n                throw new NopException(\"processPaymentResult is not available\");\r\n\r\n            if (processPaymentResult.Success)\r\n            {\r\n                //save order details\r\n                var order = await SaveOrderDetailsAsync(processPaymentRequest, processPaymentResult, details);\r\n\r\n                foreach (var orderItem in await _orderService.GetOrderItemsAsync(details.InitialOrder.Id))\r\n                {\r\n                    //save item\r\n                    var newOrderItem = new OrderItem\r\n                    {\r\n                        OrderItemGuid = Guid.NewGuid(),\r\n                        OrderId = order.Id,\r\n                        ProductId = orderItem.ProductId,\r\n                        UnitPriceInclTax = orderItem.UnitPriceInclTax,\r\n                        UnitPriceExclTax = orderItem.UnitPriceExclTax,\r\n                        PriceInclTax = orderItem.PriceInclTax,\r\n                        PriceExclTax = orderItem.PriceExclTax,\r","sourceCodeStart":1935,"sourceCodeEnd":1971,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Orders/OrderProcessingService.cs#L1935-L1971","documentation":"Thrown after the payment branch when processPaymentResult is still null. Both the payment-required branch (switch) and the skip-payment branch assign processPaymentResult, so this guard catches a logic regression where neither path produced a result object before SaveOrderDetailsAsync consumes it.","triggerScenarios":"A code path where the switch arms were extended/modified and none assigned processPaymentResult, or a refactor left an unhandled case. With stock code the only realistic trigger is a custom fork that introduces a branch forgetting the assignment.","commonSituations":"Custom modification of ProcessNextRecurringPaymentAsync adding a new payment scenario without assigning the result; partial merge of an upstream change; a plugin hooking into the flow and returning without setting the variable.","solutions":["Audit any custom edits to ProcessNextRecurringPaymentAsync to ensure every branch assigns processPaymentResult.","Re-merge upstream changes if a recent nopCommerce update added a switch arm you missed.","Add a unit test covering all payment branches to prevent regression."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    var errors = await _orderProcessingService.ProcessNextRecurringPaymentAsync(recurringPayment);\n}\ncatch (NopException ex) when (ex.Message == \"processPaymentResult is not available\")\n{\n    _logger.LogCritical(ex, \"Recurring payment {Id}: no processPaymentResult produced - logic regression.\",\n        recurringPayment.Id);\n    throw; // surface to ops; this indicates a code bug, not transient failure\n}","preventionTips":["When customising ProcessNextRecurringPaymentAsync, ensure every branch assigns processPaymentResult.","Re-merge upstream changes after upgrades to catch newly added switch arms.","Add unit tests covering each payment branch so a missing assignment fails CI."],"tags":["payment","recurring","logic-regression","defensive","nopcommerce"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}