How to Send Magento 2 Order Confirmation Email After Payment Success
In the normal scenario, after you set up order confirmation Email in the Magento 2 customers receive order confirmation Email immediately after the order is placed. As online purchases don’t allow them to get their products instantly, the confirmation gives them the patience to wait for the delivery after they have spent their money! Such a service is helpful for customer satisfaction and hence improving the customer experience of your store!
Default Magento automatically sends a confirmation Email once the order is placed. But the question is what if the payment is done via a third party payment gateway or what if the card is declined and payment fails? Default Magento 2 falls short in such a situation. So I have come up with custom code to allow to send order confirmation Email after payment success in Magento 2.
To send email confirmation 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
[Package_Name]\[Module_Name]\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="[Package_Name]\[Module_Name]\Observer\SendMailOnOrderSuccess" /> </event> </config> |
Once the event is registered, create Observer class in the following file:
[Package_Name]\[Module_Name]\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 [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); } } } |
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.
[Package_Name]\[Module_Name]\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="\[Package_Name]\[Module_Name]\Plugin\Sales\Order\Email\Container\OrderIdentityPlugin"/> </type> </config> |
Create another file along with ‘di.xml’ that is OrderIdentityPlugin.php to remove duplication of email.
[Package_Name]\[Module_Name]\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 [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; $this->checkoutSession->unsForceOrderMailSentOnSuccess(); } return $returnValue; } } |
There you go!
Now you may start sending the order confirmation Emails to your customers only after the payment is successful. ?
You may contact me if you need customization in the code to add further functionalities.
Doubts for the same is welcomed in the comments section.
Start Emailing today itself. We’d love to hear how your order Emails are now organized in a better way. ☺
Review the post with 5 stars if found helpful.
Thank you!
Sanjay Jethva
Sanjay is the co-founder and CTO of Meetanshi with hands-on expertise with Magento since 2011. He specializes in complex development, integrations, extensions, and customizations. Sanjay is one the top 50 contributor to the Magento community and is recognized by Adobe.
His passion for Magento 2 and Shopify solutions has made him a trusted source for businesses seeking to optimize their online stores. He loves sharing technical solutions related to Magento 2 & Shopify.
52 Comments
Hello sanjay,
I have issue with Payu and paytm both ,when customer press back button or fail payment order confirmation is send any solution please suggest is this help
Hello Nitish,
First, you need to check by adding log
OR
You can stop order confirmation by default :
Admin -> Stores -> Configuration -> Sales -> Sales Email -> Order -> Enabled
Send the order confirmation programmatically, only when order success page event fired
Thank You
Hi
I try to implement this functionality on the magento 2.3.3 but its not working properly. I got the email from when I place an order. I am trying this code for PayUIndia_Payu payment method.
Thanks.
Hello Jay,
Please add the log and check
Thank You
In B2b payment.i receive email before and after payment successfull.how to cancel before email.
Hello Asma Banu,
You need to check by adding a log.
Thank You
Hello Sanjay,
This is compatible with Magento 2.4.0 ?
I have tried your solution, still m getting the email triggering twice one at checkout and another at payment success.
On Disable Default Email from the Admin Back end, It’s stop sending email at both checkout and on payment success.
Your Quick response will be appreciated as we are stuck with this to make the Site Live.
Hello Wajahat,
It seems like there’s some issue with session variable setting.
Please add a log and check
Thank You
I am getting error as per following screenshot.
https://prnt.sc/14ikd96
Can you tell me, what is problem there?
Hello Bhavik,
There’s an error of namespace.
You may have passed the wrong path in the namespace.
Thank You.
I want to use this code for Paytabs payment extension, but it’s not working. It’s not sending emails.
Hello Mohammed,
Please put the log and check if the newly created file is called or not.
Thank you.
Hello Sanjay,
I have tried your solution, still m getting the email triggering twice one at checkout and another at payment success.
On Disable Default Email from the Admin Back end, It’s stop sending email at both checkout and on payment success.
I’m using Tap Payment Gateway, does this solution works for this Tap Payment Gateway?
Your Quick response will be appreciated as we are stuck with this to make the Site Live.
Hello Vaibhav,
Yes, it’s working with all the payment gateways.
Please check if any of your extensions’ files have a code for sending emails. If so, please remove it and try again.
Thanks.
Hello, I have done all the steps, but it generates the following exception:syntax error, unexpected ‘namespace’ (T_NAMESPACE)
Hello, please check if you replaced [Package_Name]\[Module_Name] with extension name?
I have tried all the above scenarios but still, my email is getting triggered. Could you please help
Hello Ravi,
Please put the log and check if the newly created file is called or not.
Thanks.
Hi Sanjay,
Using the above code, email is triggered twice and if the email order is disabled from admin no email is triggered . If enabled email is triggered twice which shouldn’t be.
How to fix this ?
Hello Rakesh,
If you are sending email from your extension as well, then the email is triggered twice.
Thanks.
What is [Package_Name]\[Module_Name]?
Hello,
Here, [Package_Name] is the extension provider company’s name and [Module_Name] is the extension name.
Thank you.
Hi, good solution thanks.
But I need to know if it will send confirmation email also when using offline payment methods. In this cases payment is not success but email should be sent, for example when paying by bank transfer.
thanks in advance
Hello Daniel,
If you do not want to send an email for the offline payment method, you can set a condition of payment method used in the order placement.
Thanks.
Hi,
Can we send an Email Confirmation after the order is placed and paid successfully?
Not based on checkout_onepage_controller_success_action, As we use mobile Apps too.
We are using Etisalat and Paypal as Payment Gateways.
Hello Shiva,
You can check status or similar other parameters in order’s object to know if an order is placed and paid successfully and then decide to send the email or not.
https://drops.meetanshi.com/AIRECU – Check here for the Magento root script as well as the pdf generated. The data is dynamically generated.
Thanks.
Is there any way to send the mail without using the checkout_onepage_controller_success_action event?
Regards!
Hey, Sorry, there is no other way.
Thanks
Hi there, we have tried to implement the above solution on Magento 2.3.0 but it’s not working. we are still receiving emails when we place an order. We are using PayStack as a our Payment Getway.
Hello,
You need to debug in our plugin class or third party PayStack gateway.
Thanks.
above code is possible to cc avenue payment gateway
Hi keerthi,
No, the above solution will not work for CCAvenue payment gateway.
i need to send mail after success payment. my payment gateway is ccavenue.
Is possible send order mail copy to admin ?
Magento 2 allows sending a copy of order email. It can be done through:
Store >> Settings >> Configuration >> Sales >> Sales Email >> Send Order Email Copy To
How to send email on click of place order button without using events
Hello Neha,
I’m afraid you cannot send emails without using events!
The “Place Order” function in the JS is executed and you need to perform one of its actions to send the mail.
Thanks.
This solution was workign on our M 2.2.3 store but not on 2.3.2 store
Hello Ranjeet,
You may be using a 3rd party payment gateway.
With the release of Magento 2.3.2, that payment gateway needs to be customized.
On doing so, you won’t be needing the above solution.
Thanks.
Hi, Emails are not going even after payment success after the above code added.
Please put a log and check for the issue you are having. It works fine when we tested.
I want to send an email to admin instead of customer. where can i make the changes?
Hi Mohit,
It’s not possible to simply make minor changes in the code and make it work. For your requirement, you need to custom code from scratch. Do Contact Us if you want any professional help in this case.
Thank you for sharing this. However, this solution is not working for us. We still get an email when the order isn’t payed or cancelled. We use a payment provider (Icepay).
Hey John,
In this case, you need to custom code or configure the Icepay method to send order confirmation Email after the successful payment.
Hi is there anyway this can be enabled for payflow pro credit card payment only? I am not sure but payflow credit card payment is not sending any order email to customer/admin out site. I don’t know if this is a magento default, but when it is payflow express we are getting an email for customer but for admin it took so long.
You don’t need to apply our solution to solve your issue, there is something wrong in your store. Refer https://github.com/magento/magento2/issues/17875 to try solving your issue.
How i can Cancel follow-up emails after successful order
Hi,
Your solution is working fine for me but with one issue. Now I can’t send order emails from the backend. Could you please suggest a way to resolve this issue?
Thanks,
Nasir Perwaiz.
Hi Nasir,
Please try to rename the below file and check again.
[Package_Name]\[Module_Name]\etc\di.xml
I have tried this solution, But it’s not working for me. I got the email from when I place an order
For which payment method you want to enable this code?