nopSolutions/nopCommerce · error · NopException
You can't refund this order
Error message
You can't refund this order
What it means
Thrown by OrderProcessingService.RefundOfflineAsync when CanRefundOffline(order) returns false. An offline (manual) full refund is allowed only when OrderTotal > 0, RefundedAmount == 0 (no prior partial refunds), and PaymentStatus == Paid. Offline refunds bypass the payment gateway, so the order must be Paid and not already partially refunded.
Source
Thrown at src/Libraries/Nop.Services/Orders/OrderProcessingService.cs:2751
// return false;
if (order.PaymentStatus == PaymentStatus.Paid)
return true;
return false;
}
/// <summary>
/// Refunds an order (offline)
/// </summary>
/// <param name="order">Order</param>
/// <returns>A task that represents the asynchronous operation</returns>
public virtual async Task RefundOfflineAsync(Order order)
{
ArgumentNullException.ThrowIfNull(order);
if (!CanRefundOffline(order))
throw new NopException("You can't refund this order");
//amout to refund
var amountToRefund = order.OrderTotal;
//total amount refunded
var totalAmountRefunded = order.RefundedAmount + amountToRefund;
//update order info
order.RefundedAmount = totalAmountRefunded;
order.PaymentStatus = PaymentStatus.Refunded;
await _orderService.UpdateOrderAsync(order);
//add a note
await AddOrderNoteAsync(order, $"Order has been marked as refunded. Amount = {amountToRefund}");
//raise event
await _eventPublisher.PublishAsync(new OrderRefundedEvent(order, amountToRefund));
View on GitHub (pinned to 64bdf2ff08)
Solutions
- Guard with: if (!_orderProcessingService.CanRefundOffline(order)) return; and report the reason.
- If RefundedAmount > 0, use PartiallyRefundOfflineAsync(order, remaining) instead.
- Confirm PaymentStatus == Paid before showing the offline refund action.
- For free/zero-total orders, no refund is needed.
Example fix
// before
await _orderProcessingService.RefundOfflineAsync(order);
// after
if (!_orderProcessingService.CanRefundOffline(order))
return;
await _orderProcessingService.RefundOfflineAsync(order); Defensive patterns
Strategy: validation
Validate before calling
if (!_orderProcessingService.CanRefundOffline(order))
return;
await _orderProcessingService.RefundOfflineAsync(order); Prevention
- If RefundedAmount > 0, use PartiallyRefundOfflineAsync.
- Confirm PaymentStatus == Paid before offering offline refund.
- Skip for zero-total orders.
When it happens
Trigger: Calling RefundOfflineAsync when: OrderTotal == 0; RefundedAmount > 0; or PaymentStatus != Paid. Common when an admin tries an offline refund on an order that is not Paid or that was already partially refunded.
Common situations: Order still Pending or Authorized (not Paid); a partial refund already applied (use PartiallyRefundOfflineAsync); zero-total order; staff using offline refund because the gateway refund failed but the order is not in Paid state.
Related errors
- Cannot do refund for order.
- Cannot do partial refund for order.
- You can't partially refund (offline) this order
- You can't void this order
- Cannot do capture for order.
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/e69e05eabe58a761.
Report an issue: GitHub.