Automattic / woocommerce-payments

Accept payments via credit card. Manage transactions within WordPress.
https://wordpress.org/plugins/woocommerce-payments/
Other
173 stars 69 forks source link

Spike: Use WooCommerce email system for card reader receipts #3640

Closed anu-rock closed 2 years ago

anu-rock commented 2 years ago

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:

  1. Can Woo's email functionality be reused to send email receipts? I'm assuming there are APIs to access that functionality.
  2. Given that we have one place (card readers page) to customize both print and email receipts, does it make sense to allow merchants to manage the receipt email notifications and template in wp-admin → WooCommerce → Settings → Emails?
  3. If the answer to question 2 is yes, what rough steps would be required to support it?
  4. Would we need inputs from the design team when leveraging Woo's email system?

This discussion may be relevant p1644249115620559-slack-CGGCLBN58 to the spike.

mgascam commented 2 years ago

Please find below my findings.

1. Can Woo's email functionality be reused to send email receipts? I'm assuming there are APIs to access that functionality.

WooCommerce's email functionality is based on two classes: WC_Emails and WC_Email. They work together to offer the email functionality.

WC_Email

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.

WC_Emails

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.

Reusing Woo’s email functionality

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.

2. Given that we have one place (card readers page) to customize both print and email receipts, does it make sense to allow merchants to manage the receipt email notifications and template in wp-admin → WooCommerce → Settings → Emails?

It would make sense for the following reasons:

  1. Emails other than the Woo core ones are managed there, like the Subscriptions emails. Merchants might be used to find the email customization options there. It seems beneficial to have all emails centralized in one place.
  2. It is relatively easy to add our emails to the settings page. Please find more information on how to do it in the next section.

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.

3. If the answer to question 2 is yes, what rough steps would be required to support it?

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.

Would we need inputs from the design team when leveraging Woo's email system?

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.

anu-rock commented 2 years ago

@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:

  1. How do you propose we display order details (line items, etc.) in the email? Within the email itself or as an attachment?
  2. Do you think we'll be able to reuse the design we have for printed receipts?
mgascam commented 2 years ago

Hi @anu-rock,

  1. I would follow the same approach that we have now for the email that we are sending when a new order is created, the order details are shown in the body of the email:

Screen Shot 2022-02-22 at 18.19.37.png

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.

  1. As stated before, I think we could reuse the design that is currently used in the New Order email. But we could also reuse the design that we have for the printed receipts quite easily. The aforementioned function 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?
anu-rock commented 2 years ago

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?