nopSolutions/nopCommerce · error · NopException
You can't mark this order as paid
Error message
You can't mark this order as paid
What it means
Thrown by OrderProcessingService.MarkOrderAsPaidAsync when CanMarkOrderAsPaid(order) returns false. The order cannot be marked paid if OrderStatus == Cancelled, or if PaymentStatus is already Paid, Refunded, or Voided. It prevents an admin from manually marking an order paid when it is in a terminal/cancelled payment state.
Source
Thrown at src/Libraries/Nop.Services/Orders/OrderProcessingService.cs:2590
if (order.PaymentStatus == PaymentStatus.Paid ||
order.PaymentStatus == PaymentStatus.Refunded ||
order.PaymentStatus == PaymentStatus.Voided)
return false;
return true;
}
/// <summary>
/// Marks order as paid
/// </summary>
/// <param name="order">Order</param>
/// <returns>A task that represents the asynchronous operation</returns>
public virtual async Task MarkOrderAsPaidAsync(Order order)
{
ArgumentNullException.ThrowIfNull(order);
if (!CanMarkOrderAsPaid(order))
throw new NopException("You can't mark this order as paid");
order.PaymentStatusId = (int)PaymentStatus.Paid;
order.PaidDateUtc = DateTime.UtcNow;
await _orderService.UpdateOrderAsync(order);
//add a note
await AddOrderNoteAsync(order, "Order has been marked as paid");
await CheckOrderStatusAsync(order);
if (order.PaymentStatus == PaymentStatus.Paid)
await ProcessOrderPaidAsync(order);
}
/// <summary>
/// Gets a value indicating whether refund from admin panel is allowed
/// </summary>
/// <param name="order">Order</param>
View on GitHub (pinned to 64bdf2ff08)
Solutions
- Guard with the helper: if (!_orderProcessingService.CanMarkOrderAsPaid(order)) return; or check status before calling.
- Make the mark-paid endpoint idempotent and disable the UI action when PaymentStatus == Paid.
- If the order was wrongly cancelled, investigate the cancel flow before marking paid rather than forcing payment.
- Ensure integrations only call MarkOrderAsPaidAsync for orders in Pending payment status.
Example fix
// before
await _orderProcessingService.MarkOrderAsPaidAsync(order);
// after
if (!_orderProcessingService.CanMarkOrderAsPaid(order))
return;
await _orderProcessingService.MarkOrderAsPaidAsync(order); Defensive patterns
Strategy: validation
Validate before calling
if (!_orderProcessingService.CanMarkOrderAsPaid(order))
return;
await _orderProcessingService.MarkOrderAsPaidAsync(order); Prevention
- Disable 'Mark as paid' when PaymentStatus is Paid/Refunded/Voided or order is Cancelled.
- Make the mark-paid endpoint idempotent.
- Integrations should only mark paid orders in Pending payment status.
When it happens
Trigger: Calling MarkOrderAsPaidAsync when order is Cancelled, or when PaymentStatus is Paid, Refunded, or Voided. Happens on duplicate 'Mark as paid' actions, marking paid a cancelled order, or marking paid an order that a refund/void already settled.
Common situations: Admin double-clicking 'Mark as paid'; an integration re-firing the paid event; attempting to mark paid an order that was refunded offline; marking paid a cancelled order.
Related errors
- Cannot do cancel for order.
- Cannot do capture for order.
- Cannot do refund for order.
- You can't refund this order
- Cannot do partial refund for order.
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/4ad625eeb8558e8d.
Report an issue: GitHub.