• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Damien Carbery - Website Development

Getting You Online & Keeping You There

Getting You Online & Keeping You There Get Started
  • Home
  • Services
  • Maintenance Plans
  • Portfolio
  • Blog
  • About Me
  • Contact
You are here: Home / Website Development / Attach files to WooCommerce order email

Attach files to WooCommerce order email

Published: May 17, 2021 (Updated: September 13, 2023)

Attach files to WooCommerce order email
Upload files to an order to attach them to the WooCommerce Order Completed email.

Update 26 August 2022: Shane asked how to upload files so that they are not public. I suggested using the wp-content/uploads/woocommerce_uploads directory as it is .htaccess protected. Over a few emails Shane dived into the WooCommerce source and found a solution with the plupload_default_params and upload_dir filters – essentially if the upload is from a WooCommerce order then the files are uploaded to the protected woocommerce_uploads directory.

As this functionality is not needed by everyone I converted the code (version 0.3) to the a PHP class and used a true/false member variable to determine where to upload attachments. This update also included code to inform the admin when CMB2 is not active.

Update 4 January 2023: Gaja asked if the attachments could be shown in the customer’s View Order page in their account. It was an easy addition. Version 0.5 of the code includes this. See the screenshot near the end of the post.

Update 13 September 2023: Enabled HPOS support by changing get_post_meta() calls to $order->get_meta() versions.

CMB2 does not yet support HPOS but I reported it and they’ve developed a fix that should be in the next release.

I previously wrote about conditionally attaching files to WooCommerce order email to the Completed order email.

A client asked how to attach custom photos of a product to the Completed order email. This meant that the list of files to attach to the email could not be a static list as it was for the other plugin. I copied and tweaked the meta box code form the Tracking Info to WooCommerce order post to allow for a list of files to be uploaded and associated with each order. CMB2 has the ‘file_list’ field type that allows the upload of multiple files. It is primarily intended for galleries but is perfect for this.

The files are attached via the ‘woocommerce_email_attachments‘ filter and checking that the email is the ‘customer_completed_order‘ one. The list of attachments is in the post meta and includes the attachment ID and url. The
url is not useful here as the path to the file is needed so it can be attached. The get_attached_file() API call retrieves this.

Screenshot of 'Order Attachments' meta box to upload files that will be attached to the 'Completed order' email.

Upload before sending email

For the shop manager, the most important thing is to note is that the files must be uploaded before the order is marked Complete.

View attachments in customer’s View Order page

Gaja asked if the attachments could be shown in the customer’s View Order page in their account. Someone asked the same question on a Facebook group. It wasn’t hard to add this. Version 0.5 of the code includes this new feature.

I added an ‘Attached documents‘ section below the address section.

Screenshot of the new section in the View Order page that lists the attached documents.

The code

The settings for the ‘file_list‘ field limits it to image uploads (‘query_args‘ parameter). This can be commented out or edited to allow for different file types.

Related Posts

Conditionally attach files to WooCommerce order email

Attach a file to the WooCommerce Order Completed email if a specific product or variation is in the order.

Add Tracking Info to WooCommerce order

Use CMB2 to add a custom metabox to add tracking information to WooCommerce orders. The information is then added to the "Completed Order" email.

Defer WooCommerce emails for a few minutes

Defer WooCommerce emails for a specified time after the normal delivery time.

Reader Interactions

Comments

  1. Felix says

    October 6, 2021 at 10:54 pm

    Hey, is there a way to make this usable to add files to an order note and then send this to a customer? these files are individual per order and can change up to once a day. i would like to use woo to keep track of what was sent when. thanks

    Reply
    • damien says

      October 7, 2021 at 3:21 am

      @Felix – Maybe the code could be changed to attach the files when you add a note to the order – on line 36, change ‘customer_completed_order’ to ‘customer_note’. To keep track, your note would have to say what was in the email, it would not be a record of the files sent.

      Reply
  2. Hugo says

    February 11, 2022 at 3:11 pm

    Hi,

    I tried implementing your code but I’m not sure what went wrong. I edited out the query_args parameter because I wanted to attach a PDF file. Upon testing with the last part back in the code, I just got an empty space with ‘ ‘ in the email body.

    Can you help me? Cheers

    Reply
  3. Hugo says

    February 11, 2022 at 5:18 pm

    Actually you can ignore my previous comment, I didn’t realize that by “the files must be uploaded before the order is marked Complete” you meant one has to do it in two steps, I was uploading the file and marking the order as complete at the same time before hitting the update button on the order ^^’

    Reply
    • damien says

      February 11, 2022 at 5:28 pm

      @Hugo – Yes, it has to be done in two steps. There’s an underlying issue that others have found in my tracking info code where the tracking info has to be added and then change order status. It’s on my todo list to investigate that. The solution to that may benefit the situation you see.

      Reply
      • 2023gonnarock says

        December 26, 2022 at 5:47 pm

        Hi @damien, just to confirm so I would need to (1) Select files and click Update (2) mark the order as complete and click Update. Is this what you meant? Thanks!

        Reply
        • damien says

          December 27, 2022 at 12:10 pm

          @2023gonnarock – That’s exactly it. This is because WooCommerce sends the emails before CMB2 saves the PDF info. 

          There is a filter that will delay sending emails for 10 seconds:

          // Defer emails for 10 seconds to allow time for CMB2 to save the tracking data. add_filter( 'woocommerce_defer_transactional_emails', '__return_true' );

          You can add that to the init() function to see if it works. Comment out if it doesn’t and stick with the two step approach.

          Reply
  4. Shane says

    July 15, 2022 at 5:55 pm

    Hi,

    I am trying to find a way so that the files being attached are not public, in my case the customer can order an assessment and i want to be able to attach that assessment to the order but it contains personal information.

    Any ideas how to do this?

    Reply
    • damien says

      July 16, 2022 at 12:01 pm

      @Shane: Mmm, tough one.

      I know that WooCommerce puts uploads under wp-content/uploads/woocoommerce_uploads which it protects with a .htaccess file. This means that the files cannot be accessed directly and have to go through the WooCommerce download script. This concept could be an option.

      I had a quick look at how it gets the uploaded file there – it uses the 'upload_dir' filter (from wp-includes/functions.php) in woocommerce/includes/admin/class-wc-admin-post-types.php.

      So, you could probably do something similar – the post type would be a 'shop_order'. There’s probably another filter to allow your new uploads directory to be visible to the CMB2 File Upload panel.

      If there isn’t too much data maybe you could store it with order meta and have an extra tab or section in the order details that the customer views.

      Reply
  5. Giuseppe says

    December 13, 2022 at 4:10 pm

    Hi, some questions: 1) should the code be placed in the function.php file (in the child theme)? 2) can coexist together with this other : https://www.damiencarbery.com/2020/01/add-tracking-info-to-woocommerce-order/

    Reply
    • damien says

      December 13, 2022 at 5:14 pm

      @Giuseppe:

      1) You can copy the code (except the opening https://www.damiencarbery.com/2018/10/how-to-use-my-code-snippets/

      2) The code should be able to coexist with the tracking info code. It works on the email content and the other code changes the attachments.

      Please do let me know if it does work for you.

      Reply
      • giuseppe says

        December 13, 2022 at 5:44 pm

        Thanks for the reply. Actually I have already entered the two codes and everything works perfectly.

        Just one detail: in your tracking code I had to eliminate this line because it didn’t let me send any order emails.

        // Defer emails for 10 seconds to allow time for CMB2 to save the tracking data. add_filter( 'woocommerce_defer_transactional_emails', '__return_true' );

        Reply
        • damien says

          December 14, 2022 at 2:01 pm

          @Giuseppe: Thanks for the update. That add_filter() line should add the order email to the WooCommerce/Status/Scheduled Actions/Pending list. Is wp-cron active?

          The 10 second delay is to allow shop managers enter the tracking info and update the status to Completed at the same time (without it the Order Completed email is sent before the tracking info is saved and therefore it is not available to add to the email). If this does happen to you then it is okay to comment out that line.

          Reply
          • Giuseppe says

            December 14, 2022 at 2:56 pm

            Hi, yes I understood its function but I saw that leaving it no woocommerce email is sent. If I delete that row, everything works fine: first entering the tracking data and then changing the order status to complete. wp-cron is active.

  6. Giuseppe says

    December 15, 2022 at 7:50 am

    I installed your 2 snippets as plugins (not in the function.php file) and everything works fine.

    – but eliminating that line of code that I told you:

    // Defer emails for 10 seconds to allow time for CMB2 to save the tracking data. add_filter( 'woocommerce_defer_transactional_emails', '__return_true' );

    My concern now is: with future updates of woocommerce, will you release updates of your plugins? For example, even the CMB plugin (https://it.wordpress.org/plugins/cmb2/) hasn’t been updated for 10 months.

    Hello and thanks for your work.

    Reply
    • damien says

      December 15, 2022 at 3:32 pm

      @Giuseppe – The hooks and filters I use will probably not change in WooCommerce so my code will continue to work. CMB2 has not been updated because it does not need to be updated to work.

      If one of my plugins stops working please tell me and I will investigate it. I don’t have time to check my snippets each time WooCommerce or WordPress release an update.

      Reply
  7. Igor says

    December 19, 2022 at 11:39 am

    How can I integrate this code into woocommerce to make it work properly?

    I need it to attach pdf files in addition to photos is it possible?

    Reply
    • damien says

      December 19, 2022 at 2:03 pm

      @Igor – All my code snippets are written as small plugins that you can upload and activate. Please look at the information at: https://www.damiencarbery.com/2018/10/how-to-use-my-code-snippets/

      The code already supports images and PDF files.

      Reply
  8. Anthony says

    December 22, 2022 at 11:06 am

    Hello thank you for the code, It saved my day

    I realized that sometimes the PDF is attached while at other times it fails. Is there a need to allow a few seconds delay between attach an update the status of order to complete?

    Reply
    • damien says

      December 27, 2022 at 12:09 pm

      @Anthony – It is best to attach the files and save/update the order, then update the status and save again. This is because WooCommerce sends the emails before CMB2 saves the PDF info. 

      There is a filter that will delay sending emails for 10 seconds:

      // Defer emails for 10 seconds to allow time for CMB2 to save the tracking data. add_filter( 'woocommerce_defer_transactional_emails', '__return_true' );

      You can add that to the init() function to see if it works. Comment out if it doesn’t and stick with the two step approach.

      Reply
  9. Rock says

    December 23, 2022 at 3:22 pm

    Damien amazing piece of code, exactly what I was looking for. I just have one question. Is possible to get rid off this classic Wordpress media uploader and fire browser native OS window for uploading files and upload them inside subfolder woocommerce_upload/invoices? So they are not visible in media library?

    Best, Rok

    Reply
    • damien says

      December 27, 2022 at 10:56 pm

      @Rok – I don’t know how to hide items in Media Library. When you upload files to woocommerce_uploads directory they will be listed in Media Library but cannot be viewed because of the .htaccess file in the directory.

      Media Library is created with Backbone.js which, AFAIK, uses REST API to get the media items (probably /wp-json/wp/v2/media). I could not understand the JS involved. I used a REST API log plugin but it did not list any REST API accesses. I suggest asking on wordpress.stackexchange.com.

      Reply
  10. Gaja says

    January 3, 2023 at 12:23 pm

    Hi,

    Is it possible to show the attachment in woo-commerce account ? To downlaod directly from the customer’s account ?

    Regards, Gaja

    Reply
    • damien says

      January 4, 2023 at 9:36 am

      @Gaja – Thanks for the prompt – I have been planning to update the code to implement this. I have added code to include an ‘Attached Documents’ sections in the customer’s View Order page (version 0.5 of the plugin code). See screenshot at the end of the post.

      Reply
  11. Constantin Alin says

    January 4, 2023 at 2:26 pm

    Hi there! After activating the module, the block for uploading files does not appear on the order page. Any solution?

    Reply
    • damien says

      January 5, 2023 at 11:21 am

      @Constantin: Please ensure that CMB2 plugin is active.

      Reply
  12. sacar says

    February 17, 2023 at 7:43 am

    Can we put a checkbox option that will make the plugin update the order status to “completed” as well?

    Reply
    • damien says

      February 20, 2023 at 9:29 am

      @sacar – You can select the Completed status from the dropdown on the left of the screen and click Update.

      Reply

Leave a Reply Cancel reply

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


The reCAPTCHA verification period has expired. Please reload the page.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

Blog Categories

  • Being Green
  • Food
  • Grammar
  • Just Strange
  • Laziness
  • Personal
  • Portfolio
  • Race Reports
  • Shudder
  • Typo
  • Website Development
  • WooCommerce Tips
  • Facebook
  • Twitter

Copyright © 2013–2023 Damien Carbery · Using Genesis Framework · Privacy Policy