In my case, it redirects to an empty cart page because the sessions were cleared. I had to implement a plugin to grab the order id and display the success page.
I had to add these to re-grab the order id and then take them to the success page.
Add this to your payment success controller:
use Magento\Framework\Encryption\EncryptorInterface; use Magento\Framework\Url\EncoderInterface; $resultRedirect = $this->resultRedirectFactory->create(); if ($orderId && is_numeric($orderId)) { /** @var EncryptorInterface $encryptor */ $encryptedOrderId = $this->encryptor->encrypt($orderId); // Redirect to success page with encrypted order id $urlEncodedOrderId = $this->urlEncoder->encode($encryptedOrderId); $resultRedirect->setPath('checkout/onepage/success',['order_id' => $urlEncodedOrderId]); } else { $resultRedirect->setPath('checkout/onepage/success'); } return $resultRedirect;
Then inject a plugin:
In your etc/di.xml
<type name="Magento\Checkout\Controller\Onepage\Success"> <plugin name="checkout.success" type="NameSpace\ModuleName\Plugin\Checkout\Controller\Onepage\Success" sortOrder="1"/> </type>
And your plugin class:
namespace NameSpace\ModuleName\Plugin\Checkout\Controller\Onepage; use Magento\Framework\Encryption\EncryptorInterface; class Success { /** * @var \Magento\Framework\Registry */ protected $_coreRegistry; /** * @var \Magento\Checkout\Model\Session */ protected $_checkoutSession; /** @var \Magento\Sales\Model\OrderFactory **/ protected $_orderFactory; /** @var \Magento\Framework\Url\DecoderInterface */ protected $decoder; /** * Success constructor. * @param \Magento\Framework\Registry $coreRegistry * @param \Magento\Checkout\Model\Session $checkoutSession * @param \Magento\Sales\Model\OrderFactory $orderFactory * @param EncryptorInterface $encryptor * @param \Magento\Framework\Url\DecoderInterface $decoder */ public function __construct( \Magento\Framework\Registry $coreRegistry, \Magento\Checkout\Model\Session $checkoutSession, \Magento\Sales\Model\OrderFactory $orderFactory, \Magento\Framework\Encryption\EncryptorInterface $encryptor, \Magento\Framework\Url\DecoderInterface $decoder ) { $this->_coreRegistry = $coreRegistry; $this->_checkoutSession = $checkoutSession; $this->_orderFactory = $orderFactory; $this->encryptor = $encryptor; $this->decoder = $decoder; } /** * @param \Magento\Checkout\Controller\Onepage\Success $subject */ public function beforeExecute(\Magento\Checkout\Controller\Onepage\Success $subject) { $order_Id = $subject->getRequest()->getParam('order_id', false); if (!$order_Id) { return; } $decodedOrderId = $this->decoder->decode($order_Id); $orderId = $this->encryptor->decrypt($decodedOrderId); if ($orderId && is_numeric($orderId)) { $order = $this->_orderFactory->create()->load($orderId); if ($order && $order->getId()) { $this->_checkoutSession->setLastQuoteId($order->getQuoteId()); $this->_checkoutSession->setLastSuccessQuoteId($order->getQuoteId()); $this->_checkoutSession->setLastOrderId($order->getId()); $this->_checkoutSession->setLastRealOrderId($order->getIncrementId()); $this->_checkoutSession->setLastOrderStatus($order->getStatus()); } } } }
Hope this helps.
I am keen to understand why sessions are being cleared. This only happens with third-party payment modules. I strongly suspect it is server related. The same instance in my localhost works.