Search code examples
phpwordpresswoocommerceorders

Remove refund row(s) from WooCommerce order details table


I want to remove the refund row from the WooCommerce order details table

Existing code copied from /order/order-details.php WooCommerce template file:

<?php 
    foreach ( $order->get_order_item_totals() as $key => $total ) { 
        ?>
            <tr>
                <th class="row" scope="row"><?php echo esc_html( $total['label'] ); ?></th>
                <td class="row" scope="row"><?php echo ( 'payment_method' === $key ) ? esc_html( $total['value'] ) : wp_kses_post( $total['value'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></td>
            </tr>
        <?php 
    }
?>

For this I use the following filter hook:

function customize_woocommerce_get_order_item_totals( $total_rows, $order, $tax_display ) {
    unset($total_rows['refund']);
    return $total_rows;
} 
add_filter( 'woocommerce_get_order_item_totals', 'customize_woocommerce_get_order_item_totals', 10, 3 );

This does not give any error messages, but also not the desired result. The row is not deleted. Any advice?


Solution

  • When we look at /includes/class-wc-order.php in detail we see the following function is used in WooCommerce for adding the total refunds row(s).

    /**
     * Add total row for refunds.
     *
     * @param array  $total_rows  Total rows.
     * @param string $tax_display Tax to display.
     */
    protected function add_order_item_totals_refund_rows( &$total_rows, $tax_display ) {
        $refunds = $this->get_refunds();
        if ( $refunds ) {
            foreach ( $refunds as $id => $refund ) {
                $total_rows[ 'refund_' . $id ] = array(
                    'label' => $refund->get_reason() ? $refund->get_reason() : __( 'Refund', 'woocommerce' ) . ':',
                    'value' => wc_price( '-' . $refund->get_amount(), array( 'currency' => $this->get_currency() ) ),
                );
            }
        }
    }
    

    Since an order can consist of several refunds, 'refund_' . $id is used opposite 'refund'


    So to remove it, you have to use a loop. So you get:

    function filter_woocommerce_get_order_item_totals( $total_rows, $order, $tax_display ) {
        // Get the Order refunds (array of refunds)
        $order_refunds = $order->get_refunds();
    
        // NOT empty
        if ( ! empty( $order_refunds) ) {
            // Unset
            foreach ( $order_refunds as $id => $refund ) {
                unset( $total_rows[ 'refund_' . $id ] );
            }
        }
    
        return $total_rows;
    }
    add_filter( 'woocommerce_get_order_item_totals', 'filter_woocommerce_get_order_item_totals', 10, 3 );