How to change the order confirmation email template programmatically

In this article I’ll show you How to change the order confirmation email template programmatically. Order confirmation emails play a pivotal role in the customer experience for e-commerce websites. Order confirmation emails are often the first direct interaction a customer has with a brand post-purchase, and their importance cannot be overstated.

An order confirmation email template is a crucial element for any e-commerce website for several reasons:

  • Customer Reassurance:
    Confirms that the order has been received and is being processed, providing customers with peace of mind.
  • Professionalism and Trust:
    Conveys a sense of professionalism and reliability, which can strengthen trust and loyalty.
  • Clear Communication:
    Details of the order, such as items purchased, prices, shipping address, and expected delivery date, are clearly communicated to avoid any confusion.
  • Branding Opportunity:
    Reinforces brand identity through the use of logos, color schemes, and consistent messaging, enhancing brand recognition.
  • Reduction in Customer Inquiries:
    Provides all necessary information about the order, reducing the need for customers to contact support with questions.
  • Marketing and Upselling:
    Includes recommendations for related products, special offers, or future discounts to encourage repeat purchases.
  • Legal and Compliance:
    Serves as a formal record of the transaction for both the customer and the business, which can be crucial for disputes or audits.
  • Order Tracking and Updates:
    Includes links or information on how customers can track their order status, ensuring they are informed throughout the process.
  • Encourages Engagement:
    Encourages customers to engage with the brand on social media or to leave reviews, fostering a sense of community and feedback loop.

In Magento 2, a default email template is provided to send to customers when an order has been placed. While we can easily customize this template, there are situations where different email templates may need to be sent based on specific order attributes. For example, if an order has a particular attribute, we might need to send Template A; otherwise, Template B should be sent. To achieve this, we need to implement this customization in our custom module.

How to change the order confirmation email template programmatically?

Step 1: Let’s assume you have created a simple module. Now you need to make a preference to override the core class where order confirmation email template is being send.
Create a di.xml file at app/code/Vendor/Module/etc directory and paste the code below.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
	<preference for="Magento\Sales\Model\Order\Email\Sender\OrderSender" type="Vendor\Module\Model\Order\Email\Sender\OrderSender" />
</config>

Here I have defined the preference to override the class OrderSender within this class there is one method name preparedTempalte from where order confirmation email template is send so we will override this method. Preference is a overridden method in Magento 2.

Step 2: Now implement preference and change the order confirmation email template if order has particular has specific attribute assign.

<?php

declare(strict_types=1);

namespace Vendor\Module\Model\Order\Email\Sender;

use Magento\Payment\Helper\Data as PaymentHelper;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Email\Container\OrderIdentity;
use Magento\Sales\Model\Order\Email\Container\Template;
use Magento\Sales\Model\Order\Email\Sender;
use Magento\Sales\Model\ResourceModel\Order as OrderResource;
use Magento\Sales\Model\Order\Address\Renderer;
use Magento\Framework\Event\ManagerInterface;
use Magento\Framework\DataObject;

/**
 * Sends order email to the customer.
 *
 * @api
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class OrderSender extends \Magento\Sales\Model\Order\Email\Sender\OrderSender
{
    /**
     * Prepare email template with variables
     *
     * @param Order $order
     * @return void
     */
    protected function prepareTemplate(Order $order)
    {
        $transport = [
            'order' => $order,
            'order_id' => $order->getId(),
            'billing' => $order->getBillingAddress(),
            'payment_html' => $this->getPaymentHtml($order),
            'store' => $order->getStore(),
            'formattedShippingAddress' => $this->getFormattedShippingAddress($order),
            'formattedBillingAddress' => $this->getFormattedBillingAddress($order),
            'created_at_formatted' => $order->getCreatedAtFormatted(2),
            'order_data' => [
                'customer_name' => $order->getCustomerName(),
                'is_not_virtual' => $order->getIsNotVirtual(),
                'email_customer_note' => $order->getEmailCustomerNote(),
                'frontend_status_label' => $order->getFrontendStatusLabel()
            ]
        ];
        $transportObject = new DataObject($transport);

        /**
         * Event argument `transport` is @deprecated. Use `transportObject` instead.
         */
        $this->eventManager->dispatch(
            'email_order_set_template_vars_before',
            ['sender' => $this, 'transport' => $transportObject, 'transportObject' => $transportObject]
        );

        $this->templateContainer->setTemplateVars($transportObject->getData());

        //prepareTemplate function logic of parent class and remove calling of parent class
        $this->templateContainer->setTemplateOptions($this->getTemplateOptions());

        if ($order->getCustomerIsGuest()) {
            $templateId = $this->identityContainer->getGuestTemplateId();
            $customerName = $order->getBillingAddress()->getName();
        } else {
            if ($order->getHasDeliveryDate()) {
                $templateId = 99 //Define your template ID which you want to send if order has Deliery date or you can make admin configuration and fetch it's value here
            } else {
                $templateId = $this->identityContainer->getTemplateId();
            }
            $customerName = $order->getCustomerName();
        }

        $this->identityContainer->setCustomerName($customerName);
        $this->identityContainer->setCustomerEmail($order->getCustomerEmail());
        $this->templateContainer->setTemplateId($templateId);
    }
}

Here I have used one order attribute name delivery_date, if order has delivery date then I will send custom email template to customer otherwise it will send default email template to the customer.

That’s it, now you have to execute below commands and place an order with customer order attribute.

bin/magento setup:di:compile
bin/magento cache:clean

I hope this blog clearly explains How to change the order confirmation email template programmatically in Magento 2. If I missed anything or you need additional information, please feel free to leave a comment on this blog. I will respond with a proper solution.

You may also like this:

Rate this post