nopSolutions/nopCommerce · critical · NopException
Payment method couldn't be loaded
Error message
Payment method couldn't be loaded
What it means
Thrown by PaymentService.ProcessPaymentAsync when the payment method plugin selected for the order cannot be loaded by LoadPluginBySystemNameAsync. This happens for non-zero totals (zero totals short-circuit to Paid). It means processPaymentRequest.PaymentMethodSystemName does not resolve to an installed, active plugin for that customer/store, so the actual payment processing cannot run. This is a checkout-critical failure.
Source
Thrown at src/Libraries/Nop.Services/Payments/PaymentService.cs:65
/// <returns>
/// A task that represents the asynchronous operation
/// The task result contains the process payment result
/// </returns>
public virtual async Task<ProcessPaymentResult> ProcessPaymentAsync(ProcessPaymentRequest processPaymentRequest)
{
if (processPaymentRequest.OrderTotal == decimal.Zero)
{
var result = new ProcessPaymentResult
{
NewPaymentStatus = PaymentStatus.Paid
};
return result;
}
var customer = await _customerService.GetCustomerByIdAsync(processPaymentRequest.CustomerId);
var paymentMethod = await _paymentPluginManager
.LoadPluginBySystemNameAsync(processPaymentRequest.PaymentMethodSystemName, customer, processPaymentRequest.StoreId)
?? throw new NopException("Payment method couldn't be loaded");
return await paymentMethod.ProcessPaymentAsync(processPaymentRequest);
}
/// <summary>
/// Post process payment (used by payment gateways that require redirecting to a third-party URL)
/// </summary>
/// <param name="postProcessPaymentRequest">Payment info required for an order processing</param>
/// <returns>A task that represents the asynchronous operation</returns>
public virtual async Task PostProcessPaymentAsync(PostProcessPaymentRequest postProcessPaymentRequest)
{
//already paid or order.OrderTotal == decimal.Zero
if (postProcessPaymentRequest.Order.PaymentStatus == PaymentStatus.Paid)
return;
var customer = await _customerService.GetCustomerByIdAsync(postProcessPaymentRequest.Order.CustomerId);
var paymentMethod = await _paymentPluginManager
.LoadPluginBySystemNameAsync(postProcessPaymentRequest.Order.PaymentMethodSystemName, customer, postProcessPaymentRequest.Order.StoreId)
View on GitHub (pinned to 64bdf2ff08)
Solutions
- Ensure the payment plugin matching PaymentMethodSystemName is installed, enabled, and active for the current store/customer.
- Set processPaymentRequest.PaymentMethodSystemName to a valid, active method before calling ProcessPaymentAsync.
- Check LimitToStores and LimitedToRoles on the plugin so it covers the checkout context.
- Add a pre-checkout guard: verify _paymentPluginManager.IsPluginActive(systemName, customer, storeId) before submitting payment.
Example fix
// before
await _paymentService.ProcessPaymentAsync(request);
// after
var pm = await _paymentPluginManager.LoadPluginBySystemNameAsync(request.PaymentMethodSystemName, customer, request.StoreId);
if (pm is null)
throw new InvalidOperationException($"Payment method '{request.PaymentMethodSystemName}' is not available.");
await _paymentService.ProcessPaymentAsync(request); Defensive patterns
Strategy: validation
Validate before calling
var pm = await _paymentPluginManager.LoadPluginBySystemNameAsync(request.PaymentMethodSystemName, customer, request.StoreId);
if (pm is null)
throw new InvalidOperationException($"Payment method '{request.PaymentMethodSystemName}' is not available.");
await _paymentService.ProcessPaymentAsync(request); Prevention
- Ensure the selected payment plugin is installed and active for the current store/customer.
- Set a valid PaymentMethodSystemName on the request before checkout.
- Verify IsPluginActive(systemName, customer, storeId) before submitting payment.
When it happens
Trigger: Placing an order / processing payment with a PaymentMethodSystemName that is null, empty, misspelled, uninstalled, disabled, or restricted to a different store/customer. Reachable on the final checkout step or any direct ProcessPaymentAsync call.
Common situations: Payment plugin uninstalled or disabled after orders were placed against it; LimitToStores/LimitedToRoles excluding the current customer/store; PaymentMethodSystemName not set on the process payment request; a renamed plugin whose old system name is stored on the order; environment mismatch (plugin present in dev, missing in prod).
Related errors
- Payment method couldn't be loaded
- Payment method is not active
- Shipping rate computation method could not be loaded
- Selected payment method can't be parsed
- Active exchange rate provider cannot be loaded
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/87a500a13ce3c727.
Report an issue: GitHub.