Add Refund Requests for WooCommerce Customers

Time for a quick tutorial! Today’s Ask Sell with WP comes from Troy:

I’d like to give my customers a way to ask for a refund on an order with WooComm. Is there a way to add a link to the account page or emails to do this?

There certainly is smile To do so, I’m going to use Gravity Forms ($39+) with a bit of custom code for our WooCommerce account and order emails.

Gravity Forms will give me a form to process a refund request, and our custom code will add a “request refund” action to the order account area and order emails if the order has been paid for.

Let’s start with the form set up, then we’ll add our “request refund” links. The important thing to note here is that this form will only send you a refund request. It won’t automatically perform a refund for your customer without admin action, but it does give customers an easy way to contact you.

If you have a payment gateway that supports refunds from WooCommerce, automating this would be possible, but it would require a developer to build a custom integration for your payment gateway.

WooCommerce Refund Requests: Set up Refund Form

Our Gravity Form is going to let us add a form through which customers can request refunds. We’ll notify ourselves of this form being submitted so a store employee can process the refund and respond.

You’ll most likely need a field for the order number, a reason for the refund, a customer email address to reply to, and perhaps the product(s) that should be refunded. I like to forward these requests to a Help Scout mailbox to manage customer service efficiently.

First, let’s add a text field for “order number”, and then go to the “Advanced tab” for that field. Ensure the field can be populated dynamically, and use the parameter “order” for this.

Gravity Forms Order Number Field
Order Number Field

This will let us pre-populate this field for the customer when they click the “Request Refund” link.

You could optionally do the same thing for products. This isn’t required, but if you wanted to add a “Products” field, we can add a comma-separated list of products here from the order. Ensure this can be populated with a “products” parameter.

Gravity Forms Products Field
Product(s) Field (Optional)

Add any other fields you need to your Gravity form, then save the form. Now embed this on a page on your site, and be sure you note the page ID. You’ll need to know the ID so we can use this in our custom code snippet shortly.

Now that form is fully functional — customers can come to this page to request a refund. However, we’re going to make it pretty seamless to do so in a couple clicks by adding an action to the “My Orders” list and to order emails once the order has been paid for.

WooCommerce Refund Requests: Add Action to “My Orders”

In order to add these actions for customers, you’ll need to know how to add custom code to your site properly (I prefer the Code Snippets plugin).

The part where we add a custom action to the account page is pretty easy — WooCommerce gives us a hook to add our own action to this list, and we have access to the order data so we can add our refund request button only for paid orders.

function sww_add_account_refund_order_action( $actions, $order ) {

    if ( $order->is_paid() ) {
        $actions['refund_request'] = array(
            'url'  => sww_get_order_refund_request_url( $order ),
            'name' => __( 'Request Refund', 'my-textdomain' ),

    return $actions;
add_filter( 'woocommerce_my_account_my_orders_actions', 'sww_add_account_refund_order_action', 10, 2 );

Now notice one thing — I haven’t entered a URL here, just a function name. I’m going to use a helper function to generate my refund request URL. The reason I’m breaking this into its own function is because that way our email link can also use this function to generate the refund link.

Here’s what that helper function will look like:

function sww_get_order_refund_request_url( $order ) {

    // enter the ID for your page that contains the refund request form
    $page_id = 196;

    // now we'll build the right refund URL from it
    $refund_url = trailingslashit( get_page_link( $page_id ) ) . '?order=' . $order->get_order_number();
    $products   = array();

    foreach ( $order->get_items() as $item_id => $item ) {
        if ( $product = wc_get_product( $item['product_id'] ) ) {
            $products[] = $product->get_title();

    if ( ! empty( $products ) ) {
        $refund_url .= '&products=' . urlencode( implode( ', ', $products ) );

    return $refund_url;

I know it looks a bit intense, so for the code-minded people here, let’s look at what it does. First, we need an order so we can generate a refund request URL with that order’s data — we’ve already got that passed into the function from our order action code above.

Next, it takes that order and starts to build a URL to request a refund for that order. Here’s where you need the ID of your refund form’s page. Notice I have entered 196 for my page ID — you’ll enter the ID of your refund request page here instead.

The URL adds the order number here so this will pre-populate the “Order Number” field in our form. Then the snippet looks for products in the order — if it finds some, it adds a list of products to the URL. These products will be output in our “Product(s)” field in the form if you’ve chosen to allow this to be populated.

WooCommerce Refund Requests from "My Orders"
Order Actions

That’s all we need! This will add a “Refund Request” button for all orders that have been paid for. This button has a URL that takes the customer to the refund request form, and prefills both the order number, along with a list of products in the order to make it easy for the customer to tell you which product(s) s/he would like refunded (if you’ve added this to your form).

Now we could add a similar link to order emails if you’d like to.

We’ll leverage the helper function I used above, so be sure this code is used on your site if you want to add a “Refund Request” link to order emails as well.

We’ll do essentially the same thing with this snippet: get the order, and generate a refund request URL from the order data. We’ll add it to the order email if the order has been paid for.

WooCommerce gives us enough hooks in order emails to make this easy:

function sww_add_refund_request_email_link( $order ) {
    if ( $order->is_paid() ) {
        echo '<br /><a class="link" href="' . esc_url( sww_get_order_refund_request_url( $order ) ) . '">Request Refund</a>';
add_action( 'woocommerce_email_after_order_table', 'sww_add_refund_request_email_link', 15, 1 );

Remember, you need the helper function from the part above. If you’ve already added it, that’s all you need smile This link is now added after the order items table.

WooCommerce Refund Requests from order emails
Order Email Link

And we’re done! Now customers can request a refund from the account section or via an order email once they’ve paid for an order.

Add Customer Actions for WooCommerce Refund Requests

No matter which location the customer clicks a refund link from, it will take them to your refund request form from Gravity Forms and pre-fill the order data to make it easy to request a refund.

WooCommerce Refund Request form

Hope this gets you up and running with WooCommerce refund requests, Troy!

If you want to get this set up for both the account and order emails, be sure to use the full code snippet, including our helper function, to properly generate a refund request URL.

Cover photo credit: Stefan Baudy (CC BY 2.0 license)

Beka Rice
Beka is the head of product at Jilt. She works on app improvements, integration plugins, helping merchants improve recovery campaigns, and shares tutorials on reducing abandonment or improving recovery on our blog.


  1. I’ve never used Gravity Forms.
    Could the “Which Product(s)?” text field be split into a list of checkboxes to allow the person check the product(s) that they want the refund for?

    1. Hey Damien, if you had a small product catalog, you could use checkboxes. The reason I didn’t use this is because you can’t dynamically generate which products are shown in the checkbox; the form’s field has to exists on its own. You can only dynamically fill the field’s values, not the field itself. Therefore, if checkboxes existed already for all products, you could pass in which ones would be checked just fine; however, you can’t dynamically create the checkbox list for the form.

      1. Hi Beka

        Fantastic post – thank you! In response to the checkboxes question – this is exactly what I want to do, and I DO have a small enough catalogue to create individual checkbox items for all of my products.

        How do I implement this though?

        Then finally, do you know if it’s possible to hide products that aren’t included in that order? I’m picturing a scenario where the customer clicks through from the email link and is taken to the Request Returns page I’ve created, with it’s Gravity Form, showing the Order No, a text-area field where they can explain why they want to return these item(s) – and a checkbox list of the items they purchased in that order, where they can check the one’s they want to return.

        I’d really appreciate your help – you definitely seem to know what you’re talking about!

        Thanks again for the awesome post – Amber

  2. Really nice post.

    I just wonder if should be possible to set up this form using Contact Form 7 instead of Gravity Form?

    Have a nice day!

    1. Hey Diego, I’m pretty sure CF7 doesn’t give you a way to dynamically fill in a field like Gravity Forms does, so pre-filling the refund form wouldn’t be possible. While you could still add a link to a page with the refund form on it, you couldn’t dynamically fill any fields.

      1. The “Contact Form 7 Dynamic Text Extension” plugin could help.

        I have a form with the following:
        [dynamichidden dynamic-text-inflatable-name “inflatablename”]

        And the email has:
        Inflatable: [dynamic-text-inflatable-name]

        “inflatablename” is a shortcode that returns the post title.

        `add_shortcode(‘inflatablename’, ‘bbc_get_post_title’);
        function bbc_get_post_title() {
        global $post;

        return get_the_title($post->ID);


        So, maybe the Refund Request form could have a shortcode that looked for the ‘order=?’ parameter and retrieved the order contents (the code in the post could be adapted).

  3. Hello,
    This is great article! Thank you for detailed explain.
    I just want to know about guest’s checkouts. They just have refund options from an emails but else no option. How can we arrange for them? As far as I concerned guests just could track their orders from pages which [woocommerce_order_tracking] shortcode insterted.
    This article would be perfect If could we add this Refund button (or link) from that page below the Order Details section.
    And also i would like to ask “Warranty”. I can create new form fror warranty but i could not solve how can i add functionality customer’s order’s completed date and showing for them.
    Thank you again.

    1. Looks like the only place to easily add that to the order tracking form is here — this could use similar code to the email snippet, but this action gives you order ID, not order, so you’d need to add $order = wc_get_order( $order_id ) first before outputting the refund request link.

      And also i would like to ask “Warranty”. I can create new form fror warranty but i could not solve how can i add functionality customer’s order’s completed date and showing for them.

      Since you have access to the order in these hooks you can get the order info like completed date, but I’m afraid this isn’t something I have sample code for. I’d recommend reaching out to for these sort of customizations, they’re great for these sort of changes.

Leave a Reply

Your email address will not be published. Required fields are marked *