Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
204 views
in Technique[技术] by (71.8m points)

php - Woocommerce Refund Email

I have done a vast amount of searching and although I have found users that have asked how to achieve the following no examples of working solutions to the best of my knowledge exist.

The question is regarding the very popular Wordpress plugin "Woocommerce". The plugin comes with an email system to make life easier for the ecommerce site owner and the customer. One issue is that there is no email that is sent when a shop manager changes the order status to "Refunded". Someone has said this is because it is a manual process. This is true it is a process that the shop owner would do via there merchant account or paypal account. But once this is done and the shop owner then logs into their wordpress admin panel and changes an order status to Refunded it would be beneficial for an email to be generated and sent the customer.

This is something I've seen requested.

So I decided to modify a tutorial over at http://www.skyverge.com/blog/how-to-add-a-custom-woocommerce-email/#comment-553147

I am trying to have an email sent out when an orders order status is updated to "Refunded".

Here is the code to the initial plugin file

<?php
/**
 * Plugin Name: WooCommerce Custom Expedited Order Email
 * Plugin URI: http://www.skyverge.com/blog/how-to-add-a-custom-woocommerce-email/
 * Description: Demo plugin for adding a custom WooCommerce email that sends admins an email when an order is received with expedited shipping
 * Author: SkyVerge
 * Author URI: http://www.skyverge.com
 * Version: 0.1
 *
 * License: GNU General Public License v3.0
 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
 *
 */

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

/**
 *  Add a custom email to the list of emails WooCommerce should load
 *
 * @since 0.1
 * @param array $email_classes available email classes
 * @return array filtered available email classes
 */
function add_expedited_order_woocommerce_email( $email_classes ) {

    // include our custom email class
    require( 'includes/class-wc-expedited-order-email.php' );

    // add the email class to the list of email classes that WooCommerce loads
    $email_classes['WC_Expedited_Order_Email'] = new WC_Expedited_Order_Email();

    return $email_classes;

}
add_filter( 'woocommerce_email_classes', 'add_expedited_order_woocommerce_email' );

And here is a link to the code of my class

<?php

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

/**
 * A custom Expedited Order WooCommerce Email class
 *
 * @since 0.1
 * @extends WC_Email
 */
class WC_Expedited_Order_Email extends WC_Email {

    /**
 * Set email defaults
 *
 * @since 0.1
 */
    public function __construct() {

        // set ID, this simply needs to be a unique name
        $this->id = 'wc_expedited_order';

        // this is the title in WooCommerce Email settings
        $this->title = 'Refunded Order Email';

        // this is the description in WooCommerce email settings
        $this->description = 'Refunded Emails are sent when an order status has been changed to Refunded';

        // these are the default heading and subject lines that can be overridden using the settings
        $this->heading = 'Refunded Order';
        $this->subject = 'Refunded Order';

        // these define the locations of the templates that this email should use, we'll just use the new order template since this email is similar
        $this->template_html  = 'emails/admin-new-order.php';
        $this->template_plain = 'emails/plain/admin-new-order.php';

        // Trigger on new paid orders
        add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
        add_action( 'woocommerce_order_status_failed_to_processing_notification',  array( $this, 'trigger' ) );

        // Call parent constructor to load any other defaults not explicity defined here
        parent::__construct();

        // this sets the recipient to the settings defined below in init_form_fields()
        $this->recipient = $this->get_option( 'recipient' );

        // if none was entered, just use the WP admin email as a fallback
        if ( ! $this->recipient )
            $this->recipient = get_option( 'admin_email' );
    }

    /**
     * Determine if the email should actually be sent and setup email merge variables
     *
     * @since 0.1
     * @param int $order_id
     */
    public function trigger( $order_id ) {

        // bail if no order ID is present
        if ( ! $order_id )
            return;

        $order = new WC_Order( $order_id );

          //bail if not a refunded order
        if ( 'refunded' !== $order->status ) {
              return;
        }

        // setup order object
        $this->object = new WC_Order( $order_id );

        // bail if shipping method is not expedited
        //if ( ! in_array( $this->object->get_shipping_method(), array( 'Three Day Shipping', 'Next Day Shipping' ) ) )
            //return;

        // replace variables in the subject/headings
        $this->find[] = '{order_date}';
        $this->replace[] = date_i18n( woocommerce_date_format(), strtotime( $this->object->order_date ) );

        $this->find[] = '{order_number}';
        $this->replace[] = $this->object->get_order_number();

        if ( ! $this->is_enabled() || ! $this->get_recipient() )
            return;

        // woohoo, send the email!
        $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
    }

    /**
     * get_content_html function.
     *
     * @since 0.1
     * @return string
     */
    public function get_content_html() {
        ob_start();
        woocommerce_get_template( $this->template_html, array(
            'order'         => $this->object,
            'email_heading' => $this->get_heading()
        ) );
        return ob_get_clean();
    }


    /**
     * get_content_plain function.
     *
     * @since 0.1
     * @return string
     */
    public function get_content_plain() {
        ob_start();
        woocommerce_get_template( $this->template_plain, array(
            'order'         => $this->object,
            'email_heading' => $this->get_heading()
        ) );
        return ob_get_clean();
    }

    /**
     * Initialize Settings Form Fields
     *
     * @since 0.1
     */
    public function init_form_fields() {

        $this->form_fields = array(
            'enabled'    => array(
                'title'   => 'Enable/Disable',
                'type'    => 'checkbox',
                'label'   => 'Enable this email notification',
                'default' => 'yes'
            ),
            'recipient'  => array(
                'title'       => 'Recipient(s)',
                'type'        => 'text',
                'description' => sprintf( 'Enter recipients (comma separated) for this email. Defaults to <code>%s</code>.', esc_attr( get_option( 'admin_email' ) ) ),
                'placeholder' => '',
                'default'     => ''
            ),
            'subject'    => array(
                'title'       => 'Subject',
                'type'        => 'text',
                'description' => sprintf( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', $this->subject ),
                'placeholder' => '',
                'default'     => ''
            ),
            'heading'    => array(
                'title'       => 'Email Heading',
                'type'        => 'text',
                'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.' ), $this->heading ),
                'placeholder' => '',
                'default'     => ''
            ),
            'email_type' => array(
                'title'       => 'Email type',
                'type'        => 'select',
                'description' => 'Choose which format of email to send.',
                'default'     => 'html',
                'class'       => 'email_type',
                'options'     => array(
                    'plain'     => 'Plain text',
                    'html'      => 'HTML', 'woocommerce',
                    'multipart' => 'Multipart', 'woocommerce',
                )
            )
        );
    }


} // end WC_Expedited_Order_Email class

These are the only 2 files in my plugin. I have activated it and it appears as an email in the list of emails in the woo commerce email tab. Unfortunately no email is sent when the order status is updated.

Can anyone advise why this is failing to work?

I have had some feedback of an individual who said the following

"the actions that you're adding the trigger to are for pending/failed to processing order status changes - http://cld.wthms.co/cZzw You'd want these to be actions that are related to the refunded orders, like: add_action( 'woocommerce_order_status_refunded', array( $this, 'trigger' ) ); (for the exact one look around woocommerce's email classes)"

I am using Woocommerce 2.1.12

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The main problem is that the woocommerce_order_status_refunded hook is not registered by default with the send_transactional_email callback, so you can't use the above method to send emails automatically when the order status is changed to Refunded.

You can change that with the following:

/**
 * Register the "woocommerce_order_status_refunded" hook which is necessary to
 * allow automatic email notifications when the order is changed to refunded.
 * 
 * @see http://stackoverflow.com/a/26413223/2078474
 */
add_action( 'woocommerce_init', function() {
    add_action( 
        'woocommerce_order_status_refunded', 
        array( WC(), 'send_transactional_email' ),
        10, 
        10 
    );
});

Also make sure that you have enable it in the corresponding section in the Woo Settings -> Emails tab:

Enabled

By default the following actions are registered for automatic email notifications:

woocommerce_low_stock
woocommerce_no_stock
woocommerce_product_on_backorder
woocommerce_order_status_pending_to_processing
woocommerce_order_status_pending_to_completed
woocommerce_order_status_pending_to_on-hold
woocommerce_order_status_failed_to_processing
woocommerce_order_status_failed_to_completed
woocommerce_order_status_completed
woocommerce_new_customer_note
woocommerce_created_customer

Update:

Good news, @helgatheviking just got her WooCommerce pull request merged (see the comments below).

This means we should be able to use the new woocommerce_email_actions filter:

add_filter( 'woocommerce_email_actions', function( $email_actions ) {
    $email_actions[] = 'woocommerce_order_status_refunded';
    return $email_actions;
});

in WooCommerce 2.3+.

Similar should work for other non-default email actions, like woocommerce_order_status_cancelled.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...