Magento – custom place order redirect with ORDERID

magento2payment-gatewaypayment-methods

I'm implementing a new payment method for magento2

here is my js code :

define(
[
    'jquery',
    'Magento_Checkout/js/view/payment/default',
    'Magento_Checkout/js/action/place-order',
    'Magento_Checkout/js/action/select-payment-method',
    'Magento_Customer/js/model/customer',
    'Magento_Checkout/js/checkout-data',
    'Magento_Checkout/js/model/payment/additional-validators',
    'mage/url',
],
function (
    $,
    Component,
    placeOrderAction,
    selectPaymentMethodAction,
    customer,
    checkoutData,
    additionalValidators,
    url) {
        'use strict';

        return Component.extend({
            defaults: {
                // template: 'YOUR_NAME_SPACE_Testpayment/payment/testpayment'
                template: 'Magento_SamplePaymentGateway/payment/form'

            },
            placeOrder: function (data, event) {
                if (event) {
                    event.preventDefault();
                }

                placeOrder = placeOrderAction(this.getData(), false, this.messageContainer);

                    $.when(placeOrder).fail(function () {
                        self.isPlaceOrderActionAllowed(true);
                    }).done(this.afterPlaceOrder.bind(this));
                    return true;
                }
                return false;
            },



            afterPlaceOrder: function () {
                window.location.replace(url.build('mymodule/startpayment/ORDER_ID/'));
            },



        });
    }
);

First question … how can I fill that ORDER_ID (how to get the order_id after order placed)

2nd question : am I doing it right (logically) …?

I want to redirect to my module then redirect to bank page for doing payment then redirect back to my shop for saving transaction data
is it logically correct way in Magento 2 when payment should be done on an external site?

Best Answer

In your payment method renderer you can overwrite the afterPlaceOrder function, which gets called directly after successfully placing the order.

Basically you should be able to get away with the following JS code:

define([
    'Magento_Checkout/js/view/payment/default',
    'Magento_Checkout/js/action/redirect-on-success',
    'mage/url'
], function (Component, redirectOnSuccessAction, url) {
    'use strict';

     return Component.extend({
     defaults: {
         template: 'Magento_SamplePaymentGateway/payment/form'
     },

     afterPlaceOrder: function () {
            redirectOnSuccessAction.redirectUrl = url.build('mymodule/startpayment/');
            this.redirectAfterPlaceOrder = true;
      },
    });
});

Then in you StartPayment controller you rely on the \Magento\Checkout\Model\Session and can retrieve the order object via \Magento\Checkout\Model\Session::getLastRealOrder() and then redirect to the bank page with the relevant data from the order.

namespace MyVendor\MyModule\Controller\StartPayment;

use Magento\Checkout\Model\Session;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use Magento\Sales\Model\Order;

class Index extends Action
{
    /** @var Session */
    private $checkoutSession;

    /**
     * @param Context $context
     * @param CreateHostedCheckout $hostedCheckout
     * @param Session $checkoutSession
     */
    public function __construct(
        Context $context,
        Session $checkoutSession
    ) {
        parent::__construct($context);
        $this->checkoutSession = $checkoutSession;
    }

    /**
     * Initialize redirect to bank
     *
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        /** @var Order $order */
        $order = $this->checkoutSession->getLastRealOrder();

        /** do stuff here */

        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
        $resultRedirect->setUrl('BANK_URL');

        return $resultRedirect;
    }
}