I'm using Magento 2.2. Order confirmation mail was sent when checkout button trigged. So, I disabled Order mail from the Backend. I only need to send order confirmation mail/invoice from my website itself automatically when payment is done. But I'm only getting mails from PayU about credit and debit payment details.
-
If you cant implement my solution please do comment.– Purushotam SangroulaJan 12, 2018 at 6:31
-
Use this free extension magecomp.com/magento-2-order-confirmation-email.html– Gaurav JainSep 13, 2019 at 5:28
3 Answers
I am just extending @anime answer and writing order email code
In your module create events.xml
in etc folder
<?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="checkout_onepage_controller_success_action">
<observer name="process_gateway_redirect" instance="Vendor\Module\Observer\EmailSenderAfterPayment" />
</event>
</config>
in your Observer
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Vendor\Module\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Store\Model\StoreManagerInterface;
class EmailSenderAfterPayment implements ObserverInterface
{
/**
* @param Observer $observer
* @return void
*/
private $storeManager;
protected $_checkoutSession;
protected $sender;
protected $order;
public function __construct(
StoreManagerInterface $storeManager,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Sales\Model\Order\Email\Sender\OrderSender $sender,
\Magento\Sales\Model\Order $order
) {
$this->storeManager = $storeManager;
$this->_checkoutSession = $checkoutSession;
$this->sender = $sender;
$this->order = $order;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$orderIds = $observer->getOrderIds();
$order = $this->order->load($orderIds[0]);
$this->sender->send($order, true); //pass second param if you want to send the email asynchronous - otherwise it will be send by running corresponding cron job
return;
}
}
-
Added the code. But still not working. In order, notification is as order confirmation mail has not been sent. I need to set it as sent after mail sent. How do i test this code in local system because i connected with ERp if i made any changes it will cause erp inventory. Jan 13, 2018 at 6:42
-
Hello @murtuza
$this->sender->send($order);
this will not send order email to admin as BCC. How can I send to admin ? May 30, 2018 at 13:58 -
-
1
If you want to send the email only after the successful payment then you must write code in observer for checkout_onepage_controller_success_action
event. Create app/code/Vendor/Module/etc/events.xml
<?xml version="1.0"?>
<!--
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="checkout_onepage_controller_success_action">
<observer name="process_gateway_redirect" instance="Vendor\Module\Observer\EmailSenderAfterPayment" />
</event>
</config>
Next create the observer at app/code/Vendor/Module/Observer/EmailSenderAfterPayment.php
:
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Vendor\Module\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Store\Model\StoreManagerInterface;
class EmailSenderAfterPayment implements ObserverInterface
{
/**
* @param Observer $observer
* @return void
*/
private $storeManager;
protected $_checkoutSession;
public function __construct(
StoreManagerInterface $storeManager,
\Magento\Checkout\Model\Session $checkoutSession
) {
$this->storeManager = $storeManager;
$this->_checkoutSession = $checkoutSession;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
// do write the email sender functions right here.
return;
}
}
In case you do not know to send email programmatically refer this link.
-
Added the code, But still not working. In order, notification is as order confirmation mail has not been sent. I need to set it as sent after mail sent. How do i test this code in local system because i connected with ERp if i made any changes it will cause erp inventory. Jan 13, 2018 at 6:41
As you specified in your question that you have disabled Order Confirmation email from backend, I have assumed the same and write code in such a way that email will not be sent twice even if you have enabled Order Confirmation email from backend. So, Order Confirmation Email will only send from the success page when you have disabled it from the backend.
I was facing the same issue but I found an alternative solution like I turned off Magento default Order Confirmation email and Send Order Confirmation Email When Order is being placed Successfully.
To send an email on the order success page, we need to bind observer with event checkout_onepage_controller_success_action. Here, We write our code send mail. To assure that email is not sent twice, I have created a plugin for isEnable() method of OrderIdentity.php class from Magento_Sales module.
First, you need to register the event using events.xml. Check the below code.
[Package_Name]\[Module_Name]\etc\frontend\events.xml
<?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="checkout_onepage_controller_success_action">
<observer name="checkout_onepage_controller_success_action_sendmail" instance="[Package_Name]\[Module_Name]\Observer\SendMailOnOrderSuccess" />
</event>
</config>
After registering for the event, We will create Observer Class.
[Package_Name]\[Module_Name]\Observer\SendMailOnOrderSuccess.php
<?php
namespace [Package_Name]\[Module_Name]\Observer;
use Magento\Framework\Event\ObserverInterface;
class SendMailOnOrderSuccess implements ObserverInterface
{
/**
* @var \Magento\Sales\Model\OrderFactory
*/
protected $orderModel;
/**
* @var \Magento\Sales\Model\Order\Email\Sender\OrderSender
*/
protected $orderSender;
/**
* @var \Magento\Checkout\Model\Session $checkoutSession
*/
protected $checkoutSession;
/**
* @param \Magento\Sales\Model\OrderFactory $orderModel
* @param \Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender
* @param \Magento\Checkout\Model\Session $checkoutSession
*
* @codeCoverageIgnore
*/
public function __construct(
\Magento\Sales\Model\OrderFactory $orderModel,
\Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender,
\Magento\Checkout\Model\Session $checkoutSession
)
{
$this->orderModel = $orderModel;
$this->orderSender = $orderSender;
$this->checkoutSession = $checkoutSession;
}
/**
* @param \Magento\Framework\Event\Observer $observer
* @return void
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
$orderIds = $observer->getEvent()->getOrderIds();
if(count($orderIds))
{
$this->checkoutSession->setForceOrderMailSentOnSuccess(true);
$order = $this->orderModel->create()->load($orderIds[0]);
$this->orderSender->send($order, true);
$this->checkoutSession->unsForceOrderMailSentOnSuccess();
}
}
}
After adding observer, an order cofirmation email will send on the order success page, if we have enabled order confirmation email from Stores > Configuration > Sales > Sales Email > Order. But, now order confirmation sent twice if we enable this field. So, we need to create plugin to avoid this scenario.
To create plugin, you need to use di.xml.
[Package_Name]\[Module_Name]\etc\di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Sales\Model\Order\Email\Container\OrderIdentity">
<plugin name="change_is_enable_method" type="\[Package_Name]\[Module_Name]\Plugin\Sales\Order\Email\Container\OrderIdentityPlugin"/>
</type>
</config>
[Package_Name]\[Module_Name]\Plugin\Sales\Order\Email\Container
OrderIdentityPlugin.php
<?php
namespace [Package_Name]\[Module_Name]\Plugin\Sales\Order\Email\Container;
class OrderIdentityPlugin
{
/**
* @var \Magento\Checkout\Model\Session $checkoutSession
*/
protected $checkoutSession;
/**
* @param \Magento\Checkout\Model\Session $checkoutSession
*
* @codeCoverageIgnore
*/
public function __construct(
\Magento\Checkout\Model\Session $checkoutSession
)
{
$this->checkoutSession = $checkoutSession;
}
/**
* @param \Magento\Sales\Model\Order\Email\Container\OrderIdentity $subject
* @param callable $proceed
* @return bool
*/
public function aroundIsEnabled(\Magento\Sales\Model\Order\Email\Container\OrderIdentity $subject, callable $proceed)
{
$returnValue = $proceed();
$forceOrderMailSentOnSuccess = $this->checkoutSession->getForceOrderMailSentOnSuccess();
if(isset($forceOrderMailSentOnSuccess) && $forceOrderMailSentOnSuccess)
{
if($returnValue)
$returnValue = false;
else
$returnValue = true;
}
return $returnValue;
}
}