Skip to content

Commit ac5f820

Browse files
layoutdclaude
andcommitted
Fix refund amount validation to prevent exceeding order total
The "Invalid refund amount" error occurred because calculated refund amounts slightly exceeded the available order total due to rounding errors in tax calculations. Changes: - Calculate maximum refundable amount (order total - already refunded) - Cap refund amount to maximum available before calling wc_create_refund() - Round both calculated refund and max refund to 2 decimal places - Improve error logging to show order total and already refunded amounts Example of the issue: - Order total: $24851.03 - Calculated refund (with 3 decimal tax): $24851.04 - Result: $0.01 over limit → "Invalid refund amount" error This fix ensures refunds never exceed the mathematically available amount, preventing WooCommerce validation errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent ae9b6a6 commit ac5f820

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

includes/Generator/Order.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -521,13 +521,26 @@ protected static function create_refund( $order, $force_partial = false ) {
521521
}
522522
}
523523

524+
// Round refund amount to 2 decimal places for currency precision
525+
$refund_amount = round( $refund_amount, 2 );
526+
527+
// Calculate maximum refundable amount (order total minus already refunded)
528+
$max_refund = $order->get_total() - $order->get_total_refunded();
529+
$max_refund = round( $max_refund, 2 );
530+
531+
// Cap refund amount to maximum available (prevents rounding errors from exceeding order total)
532+
if ( $refund_amount > $max_refund ) {
533+
$refund_amount = $max_refund;
534+
}
535+
524536
// Validate refund amount is greater than 0
525537
if ( $refund_amount <= 0 ) {
526538
error_log( sprintf(
527-
'Refund skipped for order %d: Invalid refund amount (%s). Order total: %s',
539+
'Refund skipped for order %d: Invalid refund amount (%s). Order total: %s, Already refunded: %s',
528540
$order->get_id(),
529541
$refund_amount,
530-
$order->get_total()
542+
$order->get_total(),
543+
$order->get_total_refunded()
531544
) );
532545
return false;
533546
}
@@ -556,10 +569,12 @@ protected static function create_refund( $order, $force_partial = false ) {
556569
);
557570
if ( is_wp_error( $refund ) ) {
558571
error_log( sprintf(
559-
"Refund creation failed for order %d:\nError: %s\nAmount: %s\nReason: %s\nLine Items: %s",
572+
"Refund creation failed for order %d:\nError: %s\nCalculated Amount: %s\nOrder Total: %s\nOrder Refunded Total: %s\nReason: %s\nLine Items: %s",
560573
$order->get_id(),
561574
$refund->get_error_message(),
562575
$refund_amount,
576+
$order->get_total(),
577+
$order->get_total_refunded(),
563578
$reason,
564579
print_r( $line_items, true )
565580
) );

0 commit comments

Comments
 (0)