Is their any way we can override Magento\Sales\Model\Order\Email\Sender.php model in magento 2 module ?

I have created below files


<?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" type="Mod\Sales\Model\Order\Email\Sender" />


I have added log in

protected function prepareTemplate(Order $order)
        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/prepareTemplate.log');
        $logger = new \Zend\Log\Logger();

but log did not generated.

Any thoughts ?

  • Any corrections ?
    – devhs
    Commented Feb 24, 2021 at 5:25
  • Do you still need any help?
    – ZealousWeb
    Commented Mar 4, 2021 at 7:18

2 Answers 2



Updated the Observer Class

If you want to override the model Magento\Sales\Model\Order\Email\Sender\OrderSender just to extend the method prepareTemplate in order to add or modify email order template variables or change the template id, then its not the recommended approach.

Better observe the event email_order_set_template_vars_before and in your observer method add or modify the order email template variables as per your requirement.

Sample code added below


<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="email_order_set_template_vars_before">
        <observer name="email_order_set_template_vars_observer" instance="Vendor\Module\Observer\OrderEmailSetTemplateVars" />

Observer class - app/code/Vendor/Module/Observer/OrderEmailSetTemplateVars.php


namespace Vendor\Module\Observer;

use Magento\Framework\Event\ObserverInterface;
use Psr\Log\LoggerInterface;
use Magento\Framework\App\ObjectManager;
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\ResourceModel\Order as OrderResource;
use Magento\Sales\Model\Order\Address\Renderer;
use Magento\Framework\DataObject;

class OrderEmailSetTemplateVars extends \Magento\Sales\Model\Order\Email\Sender implements ObserverInterface 
     * @var LoggerInterface
    protected $logger;
     * @var Template
    protected $templateContainer;

     * @var PaymentHelper
    protected $paymentHelper;

     * @var OrderResource
    protected $orderResource;

     * Global configuration storage.
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
    protected $globalConfig;

     * @var Renderer
    protected $addressRenderer;

     * Application Event Dispatcher
     * @var ManagerInterface
    protected $eventManager;

     * @param Template $templateContainer
     * @param OrderIdentity $identityContainer
     * @param Order\Email\SenderBuilderFactory $senderBuilderFactory
     * @param \Psr\Log\LoggerInterface $logger
     * @param Renderer $addressRenderer
     * @param PaymentHelper $paymentHelper
     * @param OrderResource $orderResource
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
     * @param ManagerInterface $eventManager
    public function __construct(
        Template $templateContainer,
        OrderIdentity $identityContainer,
        \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory,
        \Psr\Log\LoggerInterface $logger,
        Renderer $addressRenderer,
        PaymentHelper $paymentHelper,
        OrderResource $orderResource,
        \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
    ) {
        parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger, $addressRenderer);
        $this->paymentHelper = $paymentHelper;
        $this->orderResource = $orderResource;
        $this->globalConfig = $globalConfig;
        $this->addressRenderer = $addressRenderer;
        $this->identityContainer = $identityContainer;
        $this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
        $this->templateContainer = $templateContainer;

    public function execute(\Magento\Framework\Event\Observer $observer)
        $this->logger->debug('Observer '.__CLASS__.' called.');
        $transportObject = $observer->getEvent()->getTransport();
//        $transportObject = $observer->getEvent()->getTransportObject();
        $order = $transportObject->getOrder(); 
        $this->logger->debug('Order Id: ' . $order->getId());
        // you can use get this var in your order email template
        $transportObject->setData('test_var','Test Value'); // or $transportObject->getTestVar('Test Value');
        // get order's shipping method and set the email template based on that
        $shippingMethod = $order->getShippingMethod();
        $this->logger->debug('Order Shipping Method  ' . $shippingMethod);
        if ($this->templateContainer) {

            if ($order->getCustomerIsGuest()) {
                $templateId = $this->identityContainer->getGuestTemplateId();
                $customerName = $order->getBillingAddress()->getName();
            } else {
                $templateId = $this->identityContainer->getTemplateId();
                $customerName = $order->getCustomerName();
            if ($shippingMethod == 'freeshipping_freeshipping') {
                $templateId = 10; // set your template id here based on the shipping method
            $orderEmailTemplateId = $this->templateContainer->getTemplateId();
            $this->logger->debug('set order email template id based on shipping method : ' . $orderEmailTemplateId);
  • Hi, thanks for the answer but i need to implement a functionality that checks for shipping method & based on that shipping method i need to use different email template as order confirmation. Any thoughts on that ? Thanks
    – devhs
    Commented Feb 24, 2021 at 6:34
  • My requirement is to send custom email template based on order shipping method
    – devhs
    Commented Feb 24, 2021 at 6:37
  • @devhs updated the code. it checks the order shipping method and sets the order confirmation email template accordingly.
    – Haijerome
    Commented Feb 24, 2021 at 6:43
  • Great Thanks, let me check & update.
    – devhs
    Commented Feb 24, 2021 at 6:46
  • I can see a method prepareTemplate() which sets the template id for the order, Magento2/vendor/magento/module-sales/Model/Order/Email/Sender.php also same method available in Magento2/vendor/magento/module-sales/Model/Order/Email/Sender/OrderSender.php Can you please tell me what's the difference between these two methods & which runs at the end or before event dispatch? Thanks
    – devhs
    Commented Feb 24, 2021 at 6:56

We can't rewrite the method of an abstract class, in this case, it is \Magento\Sales\Model\Order\Email\Sender

Instead of that, we need to find the actual class that is being used, likely it is Magento\Sales\Model\Order\Email\Sender\OrderSender

  • Yes, is their any way i can implement according to requirement which is to send custom email template based on order shipping method.
    – devhs
    Commented Feb 24, 2021 at 6:37
  • let me check... Commented Feb 24, 2021 at 8:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.