nopSolutions/nopCommerce · error · NopException
You can't partially refund (offline) this order
Error message
You can't partially refund (offline) this order
What it means
Thrown by OrderProcessingService.PartiallyRefundOfflineAsync when CanPartiallyRefundOffline(order, amountToRefund) returns false. An offline partial refund is allowed only when OrderTotal > 0, a refundable remainder exists (OrderTotal - RefundedAmount > 0), amountToRefund does not exceed the remainder, and PaymentStatus is Paid or PartiallyRefunded. Unlike the online version, no payment-method capability check is performed because the gateway is bypassed.
Source
Thrown at src/Libraries/Nop.Services/Orders/OrderProcessingService.cs:2943
if (order.PaymentStatus == PaymentStatus.Paid ||
order.PaymentStatus == PaymentStatus.PartiallyRefunded)
return true;
return false;
}
/// <summary>
/// Partially refunds an order (offline)
/// </summary>
/// <param name="order">Order</param>
/// <param name="amountToRefund">Amount to refund</param>
/// <returns>A task that represents the asynchronous operation</returns>
public virtual async Task PartiallyRefundOfflineAsync(Order order, decimal amountToRefund)
{
ArgumentNullException.ThrowIfNull(order);
if (!CanPartiallyRefundOffline(order, amountToRefund))
throw new NopException("You can't partially refund (offline) this order");
//total amount refunded
var totalAmountRefunded = order.RefundedAmount + amountToRefund;
//update order info
order.RefundedAmount = totalAmountRefunded;
//mark payment status as 'Refunded' if the order total amount is fully refunded
order.PaymentStatus = order.OrderTotal == totalAmountRefunded ? PaymentStatus.Refunded : PaymentStatus.PartiallyRefunded;
await _orderService.UpdateOrderAsync(order);
//add a note
await AddOrderNoteAsync(order, $"Order has been marked as partially refunded. Amount = {amountToRefund}");
//raise event
await _eventPublisher.PublishAsync(new OrderRefundedEvent(order, amountToRefund));
//check order status
await CheckOrderStatusAsync(order);
View on GitHub (pinned to 64bdf2ff08)
Solutions
- Guard with: if (!_orderProcessingService.CanPartiallyRefundOffline(order, amountToRefund)) return; and report the reason.
- Clamp amountToRefund = Math.Min(amountToRefund, order.OrderTotal - order.RefundedAmount).
- Confirm PaymentStatus is Paid or PartiallyRefunded before enabling the action.
- For zero-total or fully-refunded orders, no partial refund is possible.
Example fix
// before
await _orderProcessingService.PartiallyRefundOfflineAsync(order, amount);
// after
var remaining = order.OrderTotal - order.RefundedAmount;
amount = Math.Min(amount, remaining);
if (!_orderProcessingService.CanPartiallyRefundOffline(order, amount))
return;
await _orderProcessingService.PartiallyRefundOfflineAsync(order, amount); Defensive patterns
Strategy: validation
Validate before calling
var remaining = order.OrderTotal - order.RefundedAmount;
amountToRefund = Math.Min(amountToRefund, remaining);
if (!_orderProcessingService.CanPartiallyRefundOffline(order, amountToRefund))
return;
await _orderProcessingService.PartiallyRefundOfflineAsync(order, amountToRefund); Prevention
- Clamp amountToRefund to OrderTotal - RefundedAmount.
- Confirm PaymentStatus is Paid or PartiallyRefunded.
- Skip for zero-total or fully-refunded orders.
When it happens
Trigger: Calling PartiallyRefundOfflineAsync when: amountToRefund > OrderTotal - RefundedAmount; OrderTotal == 0; remainder <= 0; or PaymentStatus not Paid/PartiallyRefunded.
Common situations: Amount exceeds remaining refundable total; order already fully refunded; order not Paid (Pending/Authorized); staff using offline partial refund on an order with no refundable remainder.
Related errors
- You can't refund this order
- Cannot do partial refund for order.
- Cannot do refund for order.
- You can't void this order
- Payment method couldn't be loaded
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/dfa83d592c476ad1.
Report an issue: GitHub.