WooCommerce orders report sent by e-mail - Blog | createIT

Get a free advice now!

    Pick the topic

    Developer OutsourcingWeb developingApp developingDigital MarketingeCommerce systemseEntertainment systems

    Thank you for your message. It has been sent.


    WooCommerce orders report sent by e-mail

    WooCommerce orders report sent by e-mail

    Nowadays, a lot of businesses sell things online. The key to an efficient online shopping experience is automation. WooCommerce, the most popular ecommerce solution, offers multiple integrations with third-party platforms: payments, invoicing systems or CRM. In most cases, the entire order list / reports / payment statuses are available via the Administrator Backend Panel. However, sometimes there is a need to generate an order report and to send it to the accountant’s e-mail. We can use WP Cron to achieve this.

    WooCommerce internal API call

    We will be using the WP_REST_Request() method to call Woo API version 3. We’re looking for orders that were created yesterday ( yesterday 00:00 – yesterday 23:59 ). Endpoint ‘/wc/v3/orders’ expects a date to be formatted in the ISO8601 format. WordPress Cron is running out of wp_user context, so we have to authenticate the user with the “administrator” role by triggering the wp_set_current_user() function. Only then will the internal WordPress API Call fetch proper data.

    Cron event

    The cron event will be scheduled to execute daily after 6.00 AM. The HTML Table with a summary, and basic order information will be sent by e-mail to the accountant or administrator. For better presentation, the tables have every other row colored.

    WooCommerce email report

    This PHP script can be used to create other reports. Just use a different WooCommerce API endpoint and fetch the needed data: about customers / products / refunds or stocks. Here is a cron event job that will generate the list of all WooCommerce orders from yesterday.

    // functions.php
     * Orders stats report
    add_action('ct_cron_yesterday_orders3', 'ct_report_orders');
    add_action('init', 'schedule_cron3');
    function schedule_cron3(){
        if( !wp_next_scheduled( 'ct_cron_yesterday_orders3' ) ) {
            wp_schedule_event( strtotime('06:00:00'), 'daily', 'ct_cron_yesterday_orders3' );
    function ct_report_orders(){
        // yesterday range
        $date1 = strtotime('yesterday -30days 00:00');
        $date2 = strtotime('yesterday 23:59');
        // converting Unix time to DateTime (ignoring timezones)
        $date1_datetime = new DateTime('@' .$date1);
        $date2_datetime = new DateTime('@' .$date2);
        $date1_ISO8601 = $date1_datetime->format(DateTime::ATOM);
        $date2_ISO8601 = $date2_datetime->format(DateTime::ATOM);
        // internal API call
        $request = new WP_REST_Request( 'GET', '/wc/v3/orders' );
        $request->set_query_params( [ 'status' => 'any', 'before' => $date2_ISO8601, 'after' => $date1_ISO8601 ] );
        $response = rest_do_request( $request );
        $server = rest_get_server();
        $data = $server->response_to_data( $response, false );
            return new WP_REST_Response( $data, 401 );
        $body = '';
            // prepare email
            $body = '<table cellpadding="0" cellspacing="0" width="640" align="left" border="1" bordercolor="#ccc">';
            $body .= '<tr><td style="padding:10px; background:#000; color:#ccc;">';
            $body .= '<p>'. count($data) .' Orders from: '. $date1_datetime->format('Y-m-d') . '</p>';
            $body .= '</td></tr>';
            $row_count = 1;
            foreach($data as $row){
                $row_style = 'style="background: #fff; padding:10px;"';
                if($row_count % 2 == 0){
                    $row_style = 'style="background: #f5f5f5; padding:10px;"';
                $body .= '<tr><td ' .$row_style. '>';
                $body .= 'Number: ' . $row['number'] .' -> ';
                $body .= 'Status: ' . $row['status'] .' -> ';
                $body .= 'Date: ' . $row['date_created'] .' -> ';
                $body .= json_encode(maybe_unserialize($row['shipping']));
                $body .= '</td></tr>';
            $body .= '</table>';
            // send email
            $to = get_bloginfo('admin_email');
            $subject = 'Orders Stats : '. get_site_url();
            $headers = array('Content-Type: text/html; charset=UTF-8');
            $res = wp_mail( $to, $subject, $body, $headers );
    function ct_cron_authenticate_user(){
        if ( defined( 'DOING_CRON' ) ){
            // Notice - CRON job is running out of user context
            // To call internal API endpoint we will - hardcode user_id and authenticate the user
            // user_id = 1 = admin (with administrator privileges)
            wp_set_current_user ( 1 );

    Testing the cron job

    Now we should wait until tomorrow morning to check if our script works. Or – there is a more clever way for testing cron job events – WP CLI provides a way to execute a single job by executing a command in a shell window:

    // WP CLI command
    wp cron event run ct_cron_yesterday_orders3

    Report from last month

    We can easily change the range of dates that are used to generate order report. To get a list of orders from the last 30 days, the following 2 lines should be used:

    // last 30 days range
    $date1 = strtotime('yesterday -30days 00:00');
    $date2 = strtotime('yesterday 23:59');

    Better WP-Cron

    The WordPress built-in Cron mechanism is not perfect, it does not run constantly, but is triggered only on page load. Then, a list of scheduled tasks will be checked and tasks due to run will be executed. As an example, if you scheduled a cron event to run daily after 6.00, but the first visitor will enter any page at 9:15, only then will your event be executed. If you need a more precise time schedule, it’s recommended to disable WP CRON, and set up a cron check in the hosting panel.

    // wp-config.php
    define('DISABLE_WP_CRON', true);

    Then configure CRON in the Linux / Hosting Panel. Cron should run every 5-10 minutes and call the file wp-cron.php. WordPress will check overdue tasks and que them to be executed. Cron configuration depends on the particular Panel version, but the most popular setups are:

    // Cron hosting setup
    // Option1
    cd ${HOME}/public_html; /usr/local/bin/php -q wp-cron.php
    // Option2
    */10 * * * *  cd ${HOME}/public_html; /usr/local/bin/php -q wp-cron.php
    // Option3
    /usr/bin/php /home/USERNAME/public_html/wp-cron.php >/dev/null 2>&1
    // Option4
    wget -q -O - https://yoursite.com/wp-cron.php >/dev/null 2>&1

    That’s it for today’s tutorial. Make sure to follow us for other useful tips and guidelines.

    0 response

    Add comment

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

    Popular news

    How to Get and Use the ChatGPT API
    • Dev Tips and Tricks

    How to Get and Use the ChatGPT API

    April 25, 2024 by createIT
    eCommerce growth – is your business ready?
    • Services
    • Trends

    eCommerce growth – is your business ready?

    April 8, 2024 by createIT
    Digital marketing without third-party cookies – new rules
    • Technology
    • Trends

    Digital marketing without third-party cookies – new rules

    February 21, 2024 by createIT
    eCommerce healthcheck
    • Services
    • Trends

    eCommerce healthcheck

    January 24, 2024 by createIT
    Live Visitor Count in WooCommerce with SSE
    • Dev Tips and Tricks

    Live Visitor Count in WooCommerce with SSE

    December 12, 2023 by createIT
    Calculate shipping costs programmatically in WooCommerce
    • Dev Tips and Tricks

    Calculate shipping costs programmatically in WooCommerce

    December 11, 2023 by createIT

    Be on the same page as the rest of the industry.

    Contact us