In this quick tutorial I will show you how to add a link to the order edit page on the WooCommerce New Order email notifications, to the store administrator. It is a very simple, yet useful link to have since you can just click on it and go to the order, right from within your email. As I said, it is very simple to do, so I will just go right ahead and explain it.
Find the action hook
First thing we want to do is find the action hook we want to attach the function, which will output the link to. There are a few hooks that can work:
- woocommerce_email_before_order_table – will output before the Order details
- woocommerce_email_after_order_table – will output after the Order Details
- woocommerce_email_order_meta –ย will output after the Order Details and after the woocommerce_email_after_order_table hook.
Just pick one and lets continue.
Add the hook and function to the function.php file
Now that you picked the hook you want to output the link, just open your theme’s functions.php file and paste this at the end of the file.
As you can see I picked the woocommerce_email_after_order_table hook and added a function to it.
The function takes two parameters, the order object and if the email is to be send to the admin as a Boolean value.ย There is not much room for a breakdown here, all we do is check to make sure the admin:
// Only for admin emails if ( ! $is_admin ) { return; }
Then build the anchor link linking to the Order Edit page. Save it and place a new order. The link should look something like this:
That’s it. Hope you found this tutorial useful. If you have an idea of a tutorial you want to see, just let me know in the comments below.
Comments 59
Did you ever find the answer to this? I am working on the same issue, trying to trigger a status update via a link in the new order notification for admins.
Author
Hi Javier,
As I mentioned before, the status update is possible, but you need to make sure it is secure to update the order from a link. Only specific users should be able to make changes to the order, so making it possible to do it from a link opens it up to everybody.
Aside from the security, here is what you need to do:
1. Add your parameter to the admin link i.e. “&prefix-change-status=completed”
2. Hook into “init” or “admin_init” or any loading look and watch for the “Order Edit screen + prefix-change-status” page.
3. Once loaded, update the order status.
Again, consider security because anybody that knows about the above steps can change the status of all your orders if they are not properly secured.
Hello,
Thank you for the tutorial.
In my case, when a user makes an order, the order is put on hold (I force the status) and add a confirmation link (as per your tutorial) in the new order email to the shop admin. The purpose of the link is to have the order accepted by the shop before it’s processed. So when clicked it should change the status so that the normal Woocommerce flow can start.
I have been trying to use the suggested “init” hook and add the parameter “&prefix-change-status=processing” but nothing happens. Also tried to catch the value as a parameter. No success. I must be close but I am stuck.
The link part in the email is ok but I can’t manage to change the order status from on hold to processing. When I click the link I get a 404 and the status is not changed. Also the new order recipient is not admin so I also tried replacing the admin_url() and did not work.
Could you give me some more hints or maybe point me to a tutorial please?
Thank you for your time.
Author
Hi Max,
Here is the simplest way to do this: https://gist.github.com/vanbo/850025ed4b531620c706c7685dd11fb2
The link should point to the edit order screen and have the
&prefix-change-status=processing
added to itHi Ivan, T
Thank you very much for the script! Now I don’t get the 404 error anymore however, the order status is still not being updated. I’ve tried to change a few things to try to make it work (like hard coding the status in the function) but did not succeed & unfortunately I am not very good with WP code! Maybe you have some ideas? Thanks again.
Author
Hi Max,
I did test it and it does change the order status. Keep in mind that the URL needs to point to the order edit screen and needs the “prefix-change-status=[status]” added as well. You also need to be logged in to the site because otherwise, WP will simply direct you to the login page.
The URL should something like this: https://vanbo.dev/wp-admin/post.php?post=1235468&action=edit&prefix-change-status=processing
Hi,
I’m triying something like you.
I want to trying to trigger a status update via a link in the new order notification for provider.
The problem is that always goes to credentials page. Can I change the state for a order whithout pass for login?
Thanks in advance
Joan
@Joan Navarro, You can, but if the request is not authenticated in any way, then anybody can update your order status.
This is so close to the solution I’m looking for… I want to edit my “New Customer” email (recipient: customer). In that email, the new customer is sent a link to login to my site at mydomain/my-account. However I’d like to change that link to lead the new customer elsewhere. Is this possible ? I’m a PHP noob though :/
Author
Hi Chris,
In your case, you would have to edit the “templates\emails\customer-new-account.php” template. Just copy the template to “yourtheme/woocommerce/emails/customer-new-account.php” and edit the URL.
Very cool thanks! Is it possible, instead of going to individual order page, to go to the Orders page, but with the modal for the inidvidual order popped up (like who you click the eye icon on orders page)?
I am currently using a plugin with push message that sends me to individual order page, in his .js code it seems this is the bit that sends me there:
window.open(oraksoft_js_data.admin_url+”post.php?post=”+response+”&action=edit”);
What should i change here to get to Orders page instead, Orders page, but with the modal for the inidvidual order popped up?
Any help appreciated ๐
Author
Hi Tam,
This will be kinda tricky and will require additional Javascript loaded on the Orders page. You can URL pass parameters to the orders page and have your JS to watch for them and trigger the WC ajax to load the order in the modal. Have a look at how WC opens the modal and try to mimic the process.
Hello, am I wrong if I think that the link to order is already in Woocommerce new order notification for admin ? Then I do not understand why this post ? Thank you.
Awesome solution it works.
Would it be possible to have the link not get you to the edit page, but issue the ‘order complete’ command?
(as if the admin manually clicked the order complete button instead of the ‘view order’ button).
would it work if i somehow just edit the admin url it gives and get:
https://www.mywebsite.nl/wp-admin/admin-ajax.php?action=woocommerce_mark_order_status&status=completed&order_id=625&_wpnonce=ec33d27c50
like change:
admin_url( ‘post.php?post=’ . absint( $order->id ) . ‘&action=edit’ )
to:
admin_url( ‘post.php?post=’ . absint( $order->id ) . ‘woocommerce_mark_order_status&status=completed’ )
or something?
Author
The Ajax link will most likely not work because the nonce will not pass. But, yes, you can do that in a very similar manner. Add your parameters to the edit order link and hook into the loading page to change the status. Anybody with that link will be able to change the status, so make your verifications before you perform the action. Verify your parameters and make sure that the intended user is logged in and is changing the status.
i dont really know which things to add to the edit order link (the $link object in your example right?).
Maybe something from the WC_Order class?
$new_status = ‘complete’;
update_status( $new_status, $note = ”, $manual = false )
or something?
I just want to have a link in the ‘order received’ mail the admin gets, that allows him to instantly trigger the ‘confirm order’ command.
Thanks for the quick responde by the way!
or maybe something like this?
$link .= ‘get_view_order_url() . ‘”>’. $order->get_order_number() . ‘&action=woocommerce_mark_order_status&status=completed’ ) .'” >’;
I havent tested this yet and if it would work despite the wpnonce code.
i think i only need the hook for the order page to work now.
i think the solution is to call my custom function:
function updateStatus($order_id){
$order = new WC_Order($order_id);
$order->update_status( ‘completed’ );
}
but i dont know where to plug it in yet
Author
If you just want to update your order status, you can hook into the “admin_init” and update the order status as soon as the edit order page loads.
To update the order status all you need to do is get the order object and call the update_status method:
$order = wc_get_order($order_id);
$order->update_status(‘completed’);
Again, consider security when you perform this as well.
Hi Vanbo.
First of all big thanks to helping out.
Im using the code below, which you wrote below in another post. That works just great – the title in the order confirmation email links perfectly to the product. So far so good.
Now what I would like, is the title to link to a specific listing (and not the product itself) where this product is listed.
What code would I need for this?
Just to show you one example the permalink of a listing is: link
Here is the code you wrote that im using now:
add_filter( ‘woocommerce_order_item_name’, ‘display_product_title_as_link’, 10, 2 );
function display_product_title_as_link( $item_name, $item ) {
$_product = get_product( $item[‘variation_id’] ? $item[‘variation_id’] : $item[‘product_id’] );
$link = get_permalink( $_product->id );
return ‘‘. $item_name .’‘;
}
THANKS A LOT – I really appreciate it.
Hi guys! I really need your help.
Im dealing with a big issue.
I need to access our Orders with no admin access. Just with a random permalink. This is posible? How can i do this?
Thank you very much!
Hi Vanbo,
I’ve been trying to figure out a way to add the order notes in to the “Order Completed” email. I have found some code online but nothing has worked. Do you have any idea how I could make this work? It sounds simple but can’t get it to work. This way, I could easily add the shipment tracking information by simply typing a note.
Any help is much appreciated!
Luuk
Author
Hi Luuk,
You already have the WC_Order object passed to the hooks, all you have to do is take all customer notes and display them.
$order->get_customer_order_notes();
will get you an array of all notes. Just loop through them and display any info you want.Hello,
I have installed woocommerce with the ability to add one product to cart and buy it.
Now I would like to add the email that the customer receives a different custom link for each product (for creating an upsell offer) you can do this?
Thank you
Can this be done for the email received by a customer who ordered via guest checkout? I would assume it would have the order key in the URL? (Ex. …?key=wc_order_123b12fd12d12).
Author
Hi John,
Don’t see a reason why it can’t. I assume you want to point the link to the Thank You page? In any case, you have all the information you need, in order to build the correct link, in the
$order
object. All you need to do is know where you want to point the user to and build the link.Note: have in mind that if you want to point the user to a “View Order Page” it will most likely not work because WC requires credentials for all “My Account” pages
Hi Vanbo. I’m wondering what code I would need to add to a new order notification e-mail, so that I, as an adminstrator, can add the permalink to the e-mail, so that it can take me straight to the product page from the admin e-mail. Thanks.
Author
Hi Stephen,
you will need to use another hook “woocommerce_order_item_name”, which echoes the order item name. However, this hook does not provide the
$sent_to_admin variable
, so you don’t know which email you are manipulating.Or you can use
'woocommerce_order_item_meta_start'
to just add an additional link to the product edit page. This one also does not have the$sent_to_admin variable
, so you might be left with the only option of overwriting the template and adding the$sent_to_admin variable
as the last passed variable to one of the hooks. It won’t affect the overall workings of the code, but it will pass the needed variable.I guess you can also keep it simpler and perform your own loop through the order items and add the links to each of the items edit page.
Jeff Berman asked, in an earlier comment, about how to add a link to customer emails that will take the customer to see their order (myurl/my-account/view-order/xxx/). I was trying to do the same and struggled with that. He couldn’t get it to work. I finally managed it by adding this code to the email template:
printf( __( ‘Order: %s’, ‘woocommerce’), ‘get_view_order_url() . ‘”>’. $order->get_order_number() .’‘ );
I am just sharing in the hope to benefit others who want to do the same.
The code got broken when it published the reply.
Maybe this works:
printf( __( 'Order: %s', 'woocommerce'), 'get_view_order_url() . '">'. $order->get_order_number() .'' );
Hey ya. Great tip. If i wanted to add this to other notifications such as the customer note, can you share what i need to add to make that work? Cheers
Author
Hi Anthony,
All you need to do is change the action you use. Instead of using “
woocommerce_email_after_order_table
” as it is shown in the example, use “woocommerce_email_customer_details
” or any of the actions used in the perticular email template(just open the template and see what actions are called there).Hello vanbo,
thank you for the tutorial,very helpful!
Do you know if it is possible to have the customer not be directed to Paypal when he chose this as the payment method, but instead have him directed to the regular thankyou page and then have a pa-now link to Paypal being inserted in the order-processed email?
Looking forward to your answer,
Mara
Hi,
I would like to remove the bank account info that is displayed in the order-processing-email when chosen payment method is cash in advance. I know this is set though
woocommerce_email_before_order_table โ action
and
public function email_instructions( $order, $sent_to_admin, $plain_text = false ) {
if ( ! $sent_to_admin && ‘bacs’ === $order->payment_method && $order->has_status( ‘on-hold’ ) ) {
if ( $this->instructions ) {
echo wpautop( wptexturize( $this->instructions ) ) . PHP_EOL;
}
$this->bank_details( $order->id );
}
}
So only the bank details need to be removed, not the instructions. This should be possible with a remove_action, but I am just learning PHP, could you help me with this? I would greatly appreciate it. Thank you very much!
Author
Hi Sab,
I wrote a quick tutorial on exactly how to remove those details. Here is the link to it: http://www.vanbodevelops.com/tutorials/remove-bank-details-from-woocommerce-order-emails
Hi,
thank you so much for this! I thought it would be much simpler by just using a small remove_action, but I guess there is more involved ๐ Again, I cannot thank you enough!
Thanks for this.
I’m trying to add links to my email that let the customer update order statuses.
For example when a new order is placed we add a link to the order confirmation emails to update the status to “approved” or “cancelled”. I have made custom statuses but don’t know to let the customer update them by simply clicking a link in the email? Can you help please?
Author
Hi WC-zastore,
This link will need to point to an endpoint of your store, at which you will need to authenticate the user, checking if the user is logged in or having some sort of hashing or even other authentication to make sure only this user can change the order status. You will need to pass the order number, the status you need to change along with the authentication data, through the URL. After authentication, all you need is to change the order status to the one passed through the link.
Hi Vanbo,
I found you through a Google search,
I cant seem to find an answer to this anywhere.
I hope you are able to guide me as I am a new Woocommerce user.
I have the latest version and am using a Verada child theme with a Woocommece templates folder in there.
I’m stuck on how to display the product full description (the_content) in the admin email. I have worked out a way to show it in the single items page the Cart but not the order email sent to admin.
Regards.
Author
Hi maximoau,
to display the full product description you will need to add this code below the
$is_admin
check.https://gist.github.com/vanbo/2a27671a9ca7af7850cc
Hi Vanbo,
I would like to add the link to the customer new order but I donโt know how to do that!
Can you help me?
Alex
Author
Hi Alex,
Please note the admin check above:
It is the one that prevents your link to go to the customer. If you want it sent to the customer only, you will need the check to be
. If you want it to both admin and customer just remove the whole code part.
if you want the link added to the customer email just
Finally got it!! ๐
http://www.codeshare.io/pYyis
Do you know how I could make the Order: #xxx text that goes to the customer in their order e-mails link to the view order page for that order?
myurl/my-account/view-order/xxx/
Author
Hi Jeff,
yes, you can do that by surrounding the text with a link point to the View Order Url.
The Url is in
. However the Order #xxx, does not have a filter to it, so you will have to transfer the “templates\emails\admin-new-order.php” template to your theme and edit this part from there.
The correct line should be line 7, find the:
and edit it to look like this:
It will link the #xxxx part to the view order page.
Thank you very much for the fast reply. My apologies for not clarifying. My admin email already includes a functional link on Order: #XXX, which goes to myurl/wp-admin/post.php?post=XXX&action=edit.
I basically want the same type of functionality for the e-mails the customer receives. Assuming this would be for customer-processing-order.php and customer-completed-order.php.
Thanks again so much!
Author
Hi Jeff,
the same thing applied for the other email templates. Just open the templates for the customer ( complete and processing ) emails and edit the $order->get_order_number() by putting a link around it as I showed you.
Somehow, I can’t seem to figure it out. lol ๐
The native code is:
get_order_number(); ?>
I feel like I’ve tried a bunch of variations, but everything I do seems to not kick out an e-mail at all. Part of the problem is not being a coder, haha.
Thanks again ๐
Hi Vanbo,
I would like to add the customer comments (order_comments) to the new order notifications e-mail, but I don’t know how to do that!
I think I can use your code, but I don’t know exactly how to change the code for this.
Can you help me?
Tamara
Author
Hi Tamara,
you have the $order object, so you can use the
to get the customer comments. It returns and array of objects for
please help me … your source scritp here not run ok
I need toinsert a word into order email admin
Author
I’ll be happy to help Silvio, but just “doesn’t work”, doesn’t tell me what you need help with.
Just copy and paste the code above in your functions.php file and you will get the link.
`echo` anything inside the function and it will appear on the Admin New Order email.
Hi Vanbo, my question is similar to this article, actually I want to add the product/item link in the Processing Order email which User receives when order. When an order is placed an Order Email sent, I want that product clickable and when user clicks it redirects to the detail product page. Is there any way, how the product title be clickable and moves to its detail page. Thanks
Author
Hi Sohaib, yes you can certainly send the title as a link. Just use the “woocommerce_order_item_name” filter.
It should look something like this ( please test it before hand ).
Hi, thank for your help throught this post. I just wanted to add the variation description to the new order email but i cannot find how to do it, do you have any idea?
In the deafult mail arrives only the “main” product description but not the variation description that i put in the product variation.
Thank you very much
Author
Hi Angelo,
There is a method
get_variation_description()
, which returns the variation description. It is only available for Variation product, so you will have to make sure that you are dealing with a variation and just echo this method.So in the example
$_product
will be your object, but you need to make sure that this is initialized with the “variation_id”(if there is one). Then justecho $_product->get_variation_description();
Thank you v ery much for your response.
I tried to implement the snippet but when i put it in function.php…it crashes… do you think is ok?
add_filter( 'woocommerce_order_item_name', 'product_variation', 10, 2 );
function product_variation ( $item_name, $item ) {
if ( $item['variation_id'] ){
$_product = get_product($item['variation_id']);
$_final_name = $item_name . โโ . $_product->get_variation_description();
}else{
$_product = get_product($item['product_id']);
$_final_name = $item_name
}
return $_final_name;
}
THANK YOU! finally i win my little code battle! here is the final code:
add_filter( 'woocommerce_order_item_name', 'display_product_title_as_link', 10, 2 );
function display_product_title_as_link( $item_name, $item ) {
$_product = get_product( $item['variation_id'] ? $item['variation_id'] : $item['product_id'] );
$link = get_permalink( $_product->id );
$_var_description ='';
if ( $item['variation_id'] ) {
$_var_description = $_product->get_variation_description();
}
return ''. $item_name .''. $_var_description ;
}