2

I'm using Airpay Payment Gateway. I'm able to checkout and redirect to payment provider page. Money gets deducted. But

  1. After payment, it redirects to homepage instead of order success page and logs out of session. I need to login again
  2. When i go to orders section, it is showing payment pending

When i check the same with COD orders, it redirects to success page with order ID.

We have provided call back url to payment provider as site.com/index.php/checkout/onepage/success/

Is this a issue with the payment gateway provider end or do i need to change anything else in magento. We are using 2.3.5 version

1
  • 1
    In my case, it redirects to an empty cart page because the sessions were cleared. I had to implement a new mechanism to grab the session/order again and show the success page. I am keen to understand why sessions are being cleared. This only happens with third party payment modules. Oct 8, 2020 at 1:53

2 Answers 2

2

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.

1

I was able to fix this issue by setting checkoutSession in the response page.

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());
        }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.