nopSolutions/nopCommerce · critical · NopException
Customer could not be loaded
Error message
Customer could not be loaded
What it means
Thrown in ProcessNextRecurringPaymentAsync when _customerService.GetCustomerByIdAsync(initialOrder.CustomerId) returns null. The recurring payment's owning customer no longer exists, so nopCommerce cannot build the ProcessPaymentRequest (which needs CustomerId) and refuses the next cycle.
Source
Thrown at src/Libraries/Nop.Services/Orders/OrderProcessingService.cs:1902
/// <param name="paymentResult">Process payment result (info about last payment for automatic recurring payments)</param>
/// <returns>
/// A task that represents the asynchronous operation
/// The task result contains the collection of errors
/// </returns>
public virtual async Task<IEnumerable<string>> ProcessNextRecurringPaymentAsync(RecurringPayment recurringPayment, ProcessPaymentResult paymentResult = null)
{
ArgumentNullException.ThrowIfNull(recurringPayment);
try
{
if (!recurringPayment.IsActive)
throw new NopException("Recurring payment is not active");
var initialOrder = await _orderService.GetOrderByIdAsync(recurringPayment.InitialOrderId)
?? throw new NopException("Initial order could not be loaded");
var customer = await _customerService.GetCustomerByIdAsync(initialOrder.CustomerId)
?? throw new NopException("Customer could not be loaded");
if (await GetNextPaymentDateAsync(recurringPayment) is null)
throw new NopException("Next payment date could not be calculated");
//payment info
var processPaymentRequest = new ProcessPaymentRequest
{
StoreId = initialOrder.StoreId,
CustomerId = customer.Id,
OrderGuid = Guid.NewGuid(),
InitialOrder = initialOrder,
RecurringCycleLength = recurringPayment.CycleLength,
RecurringCyclePeriod = recurringPayment.CyclePeriod,
RecurringTotalCycles = recurringPayment.TotalCycles
};
processPaymentRequest.CustomValues.FillByXml(initialOrder.CustomValuesXml);
View on GitHub (pinned to 64bdf2ff08)
Solutions
- Cancel (IsActive=false) any recurring payments before deleting a customer.
- Restore the customer record from backup if the deletion was accidental.
- Extend customer-deletion logic to deactivate dependent recurring payments.
Example fix
// before
await _customerService.DeleteCustomerAsync(customer);
// after
foreach (var rp in await _orderService.GetRecurringPaymentsByInitialOrderIdAsync(initialOrder.Id))
rp.IsActive = false;
await _orderService.UpdateRecurringPaymentAsync(rp);
await _customerService.DeleteCustomerAsync(customer); Defensive patterns
Strategy: validation
Validate before calling
var initialOrder = await _orderService.GetOrderByIdAsync(recurringPayment.InitialOrderId);
var customer = initialOrder is not null
? await _customerService.GetCustomerByIdAsync(initialOrder.CustomerId)
: null;
if (customer is null)
{
recurringPayment.IsActive = false;
await _orderService.UpdateRecurringPaymentAsync(recurringPayment);
_logger.LogWarning("Customer missing for recurring payment {Id}", recurringPayment.Id);
return Array.Empty<string>();
}
return await _orderProcessingService.ProcessNextRecurringPaymentAsync(recurringPayment); Type guard
async Task<bool> RecurringCustomerExistsAsync(RecurringPayment rp)
{
var order = await _orderService.GetOrderByIdAsync(rp.InitialOrderId);
return order is not null
&& await _customerService.GetCustomerByIdAsync(order.CustomerId) is not null;
} Try / catch
try
{
var errors = await _orderProcessingService.ProcessNextRecurringPaymentAsync(recurringPayment);
}
catch (NopException ex) when (ex.Message == "Customer could not be loaded")
{
recurringPayment.IsActive = false;
await _orderService.UpdateRecurringPaymentAsync(recurringPayment);
} Prevention
- Before deleting a customer, deactivate their recurring payments (IsActive=false).
- In GDPR erasure flows, cascade-cancel subscriptions as part of the customer purge.
- Periodically audit for recurring payments whose customer has been removed.
When it happens
Trigger: The customer account was deleted (admin purge of inactive/guest accounts) while a recurring payment referencing their initial order is still active. Also possible after GDPR delete-me processing.
Common situations: Customer deletion routine that does not cancel their recurring payments; GDPR right-to-erasure fulfilment that removed the customer but left subscriptions running; guest-customer cleanup.
Related errors
- Initial order could not be loaded
- Order cannot be loaded
- 'Registered' role could not be loaded
- Billing address is not available
- Shipping address is not available
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/1eb382ed4c93add4.
Report an issue: GitHub.