Download Free Magento Extension at here (click here)
Normally, Default Magento 2 already send order confirmation emails to customers immediately after they placing orders. This comfirmation give the customers the patience to wait for the delivery after they have spent their money. It's very helpful for customers satisfaction and hence improving the customers experience of your store!
However, sometime, you want to send another email to customers after the success. So we should have some customization to allow to send this email.
To an email on successful order payment, we need to tie Magento 2 observer with an event of checkout_onepage_controller_success_action.
Create a simple method isEnable() using OrderIdentity.php to ensure that order confirmation email is not sent twice.
Register event under events.xml using below code
Magezend\Sendemail\etc\frontend\events.xml
1
2
3
4
5
6
7
|
<?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="Magezend\Sendemail\Observer\SendMailOnOrderSuccess" />
</event>
</config>
|
Once the event is registered, create Observer class in the following file:
Magezend\Sendemail\Observer\SendMailOnOrderSuccess.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
<?php
namespace Magezend\Sendemail\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);
}
}
}
|
After adding observer code, an email will be sent to customers on successful order payment. To avoid order duplication Email, we need to create a plugin using the di.xml file.
Magezend\Sendemail\etc\di.xml
1
2
3
4
5
6
7
|
<?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="\Magezend\Sendemail\Plugin\Sales\Order\Email\Container\OrderIdentityPlugin"/>
</type>
</config>
|
Create another file along with ‘di.xml’ that is OrderIdentityPlugin.php to remove duplication of email.
Magezend\Sendemail\Plugin\Sales\Order\Email\Container\ OrderIdentityPlugin.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
<?php
namespace Magezend\Sendemail\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;
$this->checkoutSession->unsForceOrderMailSentOnSuccess();
}
return $returnValue;
}
}
|
There you go!
Now you can send an extra email to your customers only after the payment is successful.
Thank you!