I want email will be sent only one time when payment will be successful, don't want to stop the sending process of order confirmation email
Magento – how to stop order confirmation email in magento 2.0
magento2order-email
Related Solutions
I think a better approach would be to add any additional functionality that your are trying to achieve to magento order email. By creating your own order email will limit functionality such as "resend order email".
But if you want continue take a look at send(Order $order, $forceSyncMode = false)
in magento2/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php
In your custom module create 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">
<preference for="\Magento\Sales\Model\Order\Email\Sender\OrderSender" type="Company\ModuleName\Model\Order\Email\Sender\OrderSender"/>
</config>
I was facing same issue but I found alternative solution like I turned off Magento default Order Confirmation email and Send Order Confirmation Email When Order is being placed Successfully.
Here are the step to follow :
Create Observer Event which being called after order placed :
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="<vendor_name>\OrderSuccessMail\Observer\SendMailOnOrderSuccess" />
</event>
</config>
Observer: SendMailOnOrderSuccess.php
<?php
namespace <vendor_name>\OrderSuccessMail\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);
}
}
}
Here $this->orderSender->send($order, true); called which extends abstract class method() which check if Order confirmation email is enabled from backend or not so we need create plugin for that
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="\<vendor_name>\OrderSuccessMail\Plugin\Sales\Order\Email\Container\OrderIdentityPlugin"/>
</type>
</config>
OrderIdentityPlugin.php
<?php
namespace <vendor_name>\OrderSuccessMail\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;
}
}
Here in above plugin we have checked if confirmation is enabled from backend config or not, If yes then It works as default but if No then our custom email Confirmation order will be sent.
Hope it helps.
Best Answer
You can do it easily with
disable
the order confirmation email from admin andenable
invoice email from admin.So it will send email at the time on invoice (payment received) only and not sent the order confirmation email.
Order email setting, Set it to No :
Invoice Email setting, Set it to Yes ::
You can change the invoice email content as per your need.