"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.
Opens WPIDE on
Code
$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 add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.