Closed anu-rock closed 2 years ago
Please find below my findings.
WooCommerce's email functionality is based on two classes: WC_Emails and WC_Email. They work together to offer the email functionality.
The WC_Email
represents a single email. All the emails that exist in WooCommerce extend from this class. For instance, the email that is sent to the merchant when a new order is created, WC_Email_New_Order, extends from WC_Email.
Each instance defines its own properties ( title, description, heading, subject…), its template, options and the trigger method that will handle the send action.
The templates used by emails are located by default under woocommerce/templates/emails/
folder. These templates can be overridden by making a copy to the desired active theme folder.
The WC_Emails
class encapsulates the email functionality. It is a singleton, and is available in the WooCommerce core class.
The WC_Emails
is responsible for handling the WC_Email
instances. It manages all the instances of WC_Email, defines a set of Wordpress actions that are common to all emails, exposes some public APIs that can be called to send the emails, and defines some hooks that can be used to trigger the emails.
WC_Emails
is able to work in synchronous and asynchronous mode. In synchronous mode, the email is sent in the same request. In asynchronous mode, the email is converted to a background task. WC_Emails
delegates this part to the WC_Background_Emailer class, which extends from WC_Background_Process.
To create the new email receipts reusing Woo’s functionality we can take advantage of the WC_Email
class.
To create the receipt emails we could create new classes extending from WC_Email
(ie. WC_Payments_Email_Receipt
). In this new class we define things like the title, description, subject, heading and also the email content and the template used to generate it. Since we are extending the WC_Email
class, the new email will share the same styles with the other emails, unless we decide to override the base styles with our own hooks.
In WC’s implementation, the templates used by emails inheriting from WC_Email
rely on certain hooks that are defined in the WC_Emails
class i.e. woocommerce_email_header
, woocommerce_email_footer
to name a few. If we do not override these hooks, the new emails will share the same functionality.
In this class we would also define the hooks that will trigger sending the email. Following our example, we could add an action ‘woocommerce_payments_new_receipt_notification
’ that will call the trigger method in the class, that will take care of sending the email and any other needed side effects. This action can then be called whenever we want to send this email.
We spoke before that the WC_Emails
is responsible for handling the emails. To do so, we need to make this class aware of our new email. We can achieve it by using a hook. During initialization, WC_Emails
class applies the woocommerce_email_actions
filter, allowing us to hook our own action. By convention, in our example we would use woocommerce_payments_new_receipt
, note the absence of the _notification
suffix. Once we hook into it, the WC_Emails will call the ‘woocommerce_payments_new_receipt_notification
’ whenever the woocommerce_payments_new_receipt
is invoked. It will do it in sync / async mode, depending on the configuration.
To summarize, we can take advantage of Woo's email functionality by using two mechanisms: inheritance and hooks. On one hand, we can create our own email classes extending from the WC_Email class. On the other hand, we can inject our emails into Woo by using the hooks available in the WC_Emails
class.
It would make sense for the following reasons:
On the other hand, since the email receipts are related to card readers, it can be more convenient to have everything in the same place. If that is the case, it would still be feasible to do it, but we will need to implement it ourselves from scratch.
It is also important to note that it is not mandatory to have the ‘customization’ in place to be able to use the email functionality. We could roll it out and implement the customization at a later stage.
To make our emails customizable from the WC Settings page we need to take two actions: we need to make the WC_Emails
class aware of them, and each email instance extending from WC_Email
needs to implement certain methods.
The WC_Emails
class will call the woocommerce_email_classes
hook upon initialization. This allows us to inject our own email classes.
Each instance extending from WC_Email
that is injected via this hook, should implement an init_form_fields
method that will be called from the WC Settings page to build the customization form. WC_Email
extends from WC_Settings_API
, and is able to store the customized settings.
Since we would extend the Woo core templates for the new emails, I do not think we will need input from the design team in this case. We would, in case we need to implement something specific for the receipts that is not currently supported, but it does not seem probable. In the case that we want to include the customization section in the card reader pages we would probably need some design guidelines.
@mgascam I think we have all the details we needed to successfully close the spike. Thanks for your thorough research :)
Since we would extend the Woo core templates for the new emails, I do not think we will need input from the design team in this case.
I have a couple of follow up questions:
Hi @anu-rock,
There is this function in WC_Emails::order_details
that generates the table output for the order, so I think it is a good option for us. Not only we can reuse functionality but also the design will be consistent.
WC_Emails::order_details
is just fetching theemails/email-order-details.php
template and passing a set of variables. In a similar way, we can create our own method receipt_details
and use the template file we created for the printed receipts. But I am not sure if the visual result would be nice in the email, since the design seems to be more suitable for the thermal printer?There is this function in WC_Emails::order_details that generates the table output for the order, so I think it is a good option for us. Not only we can reuse functionality but also the design will be consistent.
That makes perfect sense :) As long as we are embedding all data required for compliance, reusing the existing design with zero or minimal tweaks will certainly result in a consistent experience.
To help us effectively close this spike, could you update #3558 with useful next steps to successfully implement terminal email receipts?
Related: #3558
This spike is to validate the possibility of leveraging Woo core's existing email functionality for card reader receipts.
Through this spike, we would like to answer the following questions:
This discussion may be relevant p1644249115620559-slack-CGGCLBN58 to the spike.