# "Request a Refund" Button for Customers

> Adds a "Request refund" button to recent completed orders in My Account; clicking it notes the request on the order and emails the shop owner.

- Type: PHP
- Runs: Run everywhere
- Category: [WooCommerce](https://wpide.com/library/category/woocommerce/)
- Requires: WooCommerce
- Tags: woocommerce, refunds, my-account, customers
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/woo-refund-request-button/

## Code

```php
$wpide_refund_days = 30; // Days after completion that refunds can be requested.

add_filter( 'woocommerce_my_account_my_orders_actions', function ( $actions, $order ) use ( $wpide_refund_days ) {
    $completed = $order->get_date_completed();

    if ( $order->has_status( 'completed' ) && $completed && ( time() - $completed->getTimestamp() ) < $wpide_refund_days * DAY_IN_SECONDS && ! $order->get_meta( '_wpide_refund_requested' ) ) {
        $actions['wpide-refund'] = array(
            'url'  => wp_nonce_url( add_query_arg( 'wpide_refund_request', $order->get_id(), wc_get_account_endpoint_url( 'orders' ) ), 'wpide_refund_' . $order->get_id() ),
            'name' => 'Request refund',
        );
    }

    return $actions;
}, 10, 2 );

add_action( 'template_redirect', function () {
    if ( empty( $_GET['wpide_refund_request'] ) || ! is_user_logged_in() ) {
        return;
    }

    $order_id = absint( $_GET['wpide_refund_request'] );
    $nonce    = isset( $_GET['_wpnonce'] ) ? sanitize_key( wp_unslash( $_GET['_wpnonce'] ) ) : '';
    $order    = wc_get_order( $order_id );

    if ( ! $order || ! wp_verify_nonce( $nonce, 'wpide_refund_' . $order_id ) || ! current_user_can( 'view_order', $order_id ) ) {
        wc_add_notice( 'Sorry, that refund request could not be sent.', 'error' );
    } elseif ( ! $order->get_meta( '_wpide_refund_requested' ) ) {
        $order->update_meta_data( '_wpide_refund_requested', time() );
        $order->add_order_note( 'The customer requested a refund from their account.' );
        $order->save();

        $mailer = WC()->mailer();
        $body   = sprintf( '%1$s asked for a refund on order #%2$s. Open the order: %3$s', $order->get_formatted_billing_full_name(), $order->get_order_number(), $order->get_edit_order_url() );
        $mailer->send( get_option( 'admin_email' ), sprintf( 'Refund request for order #%s', $order->get_order_number() ), $mailer->wrap_message( 'Refund request', wpautop( esc_html( $body ) ) ) );

        wc_add_notice( 'Thanks, we have received your refund request and will be in touch shortly.' );
    }

    wp_safe_redirect( wc_get_account_endpoint_url( 'orders' ) );
    exit;
} );
```

## Notes

The button shows only within the return window you set and disappears once a request is sent; you still issue refunds from the order screen.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find ""Request a Refund" Button for Customers" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
