Magento 2 – How to Add Custom Data in Order Email

customemailmagento2order-email

I am new to Magento. I want to override the new order email template and add custom details in the order email. Please help.

Steps I have done

1. I have created a new email template and assign it to a new order in from the admin panel and a section for custom details. it is working fine. But I don't know how to bind custom value

2. I have created an observer after order success action and save custom data in sales_order against order id.

  public function execute(\Magento\Framework\Event\Observer $observer)
  {
   /* get customer store and restaurant data */
   $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
   $customerSession = $objectManager->get('Magento\Customer\Model\Session');

   $c_id = $customerSession->getCustomer()->getId();
   $c_store_id = $customerSession->getCustomer()->getData('stores');

   $store= $objectManager->get('Vendor\Store\Model\Template');
   $store_name = ($store->load($c_store_id)->getName());
   $store_restaurant_id = ($store->load($c_store_id)->getRestaurantId());

   $restaurant = $objectManager->get('Vendor\Restaurant\Model\Template');
   $restaurant_name = ($restaurant->load($store_restaurant_id)->getName());

    $orderids = $observer->getOrderIds();
    $orderId = ""; 
 
        foreach($orderids as $orderid){
            $order = $this->_order->load($orderid);
                $orderId = $orderid;
        }
    // Here I am saving custom data     
    $order->setData('restaurant_name', $restaurant_name )
            ->setData('res_store_name', $store_name);
  }

Best Answer

(Update 2.3)

use transportObject Use transportObject instead of transport

$this->eventManager->dispatch(
    'email_order_set_template_vars_before',
    ['sender' => $this, 'transport' => $transportObject, 'transportObject' => $transportObject]
);

[Update] Add custom data in order email in Magento 2

At magento2 have an event which fire when order Prepare an email template with variables.

$this->eventManager->dispatch( 'email_order_set_template_vars_before', ['sender' => $this, 'transport' => $transport] );

So, at this event, you can add new parameter via transport to template

Just like: events.xml

<?xml version="1.0" encoding="utf-8"?>
<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="add_Custom_variable_to_Order" 
            instance="[Vendor]\[ModuleName]\Observer\ObserverforAddCustomVariable" />
    </event>
</config>

Observer file:

<?php
namespace [Vendor]\[ModuleName]\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class ObserverforAddCustomVariable implements ObserverInterface
{

    public function __construct(
    ) {
    }

    /**
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        /** @var \Magento\Framework\App\Action\Action $controller */
        $transport = $observer->getTransport();
        $transport['CustomVariable1'] = 'Your Value1 ';
        $transport['CustomVariable2'] = 'Your Value2';
    }
}

At the email template , you can get this custom variables CustomVariable1,CustomVariable2 using {{var CustomVariable1|raw}},{{var CustomVariable2|raw}}

Answer for saving custom data in sales_order at success page

Magento fire an event when a customer goes to order success page the event is :

checkout_onepage_controller_success_action

this event provides order id, So using this event you can save custom data in sales_order against order.

Also, in order save field you need to call repository \Magento\Sales\Api\OrderRepositoryInterface $orderRepositoryInterface and also add save() function for saving the data

   protected    $_orderRepositoryInterface ;
    public function __construct(
    ...
        \Magento\Sales\Api\OrderRepositoryInterface $orderRepositoryInterface
    ....
    ) {
    .......
        $this->_orderRepositoryInterface = $orderRepositoryInterface;
    }
    
    
    public function execute(\Magento\Framework\Event\Observer $observer)
      {
       /* get customer store and restaurant data */
       $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
       $customerSession = $objectManager->get('Magento\Customer\Model\Session');
    
       $c_id = $customerSession->getCustomer()->getId();
       $c_store_id = $customerSession->getCustomer()->getData('stores');
    
       $store= $objectManager->get('Vendor\Store\Model\Template');
       $store_name = ($store->load($c_store_id)->getName());
       $store_restaurant_id = ($store->load($c_store_id)->getRestaurantId());
    
       $restaurant = $objectManager->get('Vendor\Restaurant\Model\Template');
       $restaurant_name = ($restaurant->load($store_restaurant_id)->getName());
    
        $orderids = $observer->getOrderIds();
        $orderId = ""; 
    
            foreach($orderids as $orderid){
                $order = $this->_orderRepositoryInterface->getById($orderid);
                $order->setData('restaurant_name', $restaurant_name )
                     ->setData('res_store_name', $store_name); 
                $order->save()             
            }
        
      
      }