Add Steps Before and After Shipping and Payment Review

Add Steps Before and After Shipping and Payment Review
()
Customizing checkout page has always been trend to gain more sales. More you ease your customer, more you gain sales on your store. From day to day, the checkout process is improving and merchants are demanding simpler but most effective checkout process.The checkout steps are important part of gaining customer attention to your store. Magento, by default, already includes two checkout consists of two steps:
  • Shipping Information
  • Review and Payment Information
Let’s say we want a customer to create an account or login before proceeding to checkout and after placing order the success page should be shown at same page.Okay, so we begin with initializing the extension.
Arsal/CheckoutSteps/etc/module.xml
<?xml version="1.0" ?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Arsal_CheckoutSteps" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Checkout" />
        </sequence>
    </module>
</config>

Register our module:
Arsal/CheckoutSteps/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Arsal_CheckoutSteps',
    __DIR__
);

First we are going to create customer step which will allow only the logged in customer to place order. We will provide a login form for guest customer at this step.We will use js ui component to create our custom step. The code inside component will tell magento about our step.
Let’s go ahead and create checkout layout xml first. We will declare our component inside this layout which will push our custom step to the checkout page.Create a file checkout_index_index.xml inside our frontend layout:
Arsal/CheckoutSteps/view/frontend/layout/checkout_index_index.xml:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="customer-account-step" xsi:type="array">
                                            <item name="component" xsi:type="string">uiComponent</item>
                                            <item name="sortOrder" xsi:type="string">1</item>
                                            <item name="children" xsi:type="array">
                                                <item name="customerAccount" xsi:type="array">
                                                    <item name="component" xsi:type="string">Arsal_CheckoutSteps/js/view/customer-step</item>
                                                    <item name="provider" xsi:type="string">checkoutProvider</item>
                                                    <item name="sortOrder" xsi:type="string">1</item>
                                                    <item name="children" xsi:type="array">
                                                        <!-- your login form goes here -->
                                                    </item>
                                                </item>
                                            </item>
                                        </item>

                                        <item name="shipping-step" xsi:type="array">
                                            <item name="sortOrder" xsi:type="string">2</item>
                                        </item>
                                        <item name="billing-step" xsi:type="array">
                                            <item name="sortOrder" xsi:type="string">3</item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

We have just declare our component inside layout. Now to create and display our custom step we need to create this component inside our web directory. Create custom-step.js
Arsal_CheckoutSteps/view/frontend/web/js/view/customer-step.js

define(
    [
        'jquery',
        'ko',
        'uiComponent',
        'underscore',
        'Magento_Checkout/js/model/step-navigator',
        'Magento_Customer/js/model/customer',
        'mage/translate'
    ],
    function (
        $,
        ko,
        Component,
        _,
        stepNavigator,
        customer,
        $t
    ) {
        'use strict';

        return Component.extend({
            defaults: {
                template: 'Arsal_CheckoutSteps/customerstep'
            },

            isVisible: ko.observable(false),
            customerTitle: 'Customer Login',

            /**
             *
             * @returns {*}
             */
            initialize: function () {
                this._super();



                if (!customer.isLoggedIn()) {
                    this.isVisible(true);
                    stepNavigator.registerStep(
                        'customer-step',
                        null,
                        $t('Customer'),
                        this.isVisible,
                        _.bind(this.navigate, this),
                        8
                    );
                } else {
                    this.isVisible(false);
                }

                return this;
            },


            navigate: function() {},

            /**
             * @returns void
             */
            navigateToNextStep: function () {
                if (!customer.isLoggedIn()) {
                    stepNavigator.next();
                }
            }
        });
    }
);

Inside the component customer-step we have told magento to register our custom step only when customer is logged in to the system.
Now create renderer template of the component. Create customerstep.html template file inside your web directory.
Arsal/CheckoutSteps/view/frontend/web/template/customerstep.html
<li id="customer-step" data-bind="fadeVisible: isVisible">
    <div class="step-title" data-bind="i18n: customerTitle" data-role="title"></div>
    <div id="customer-step-title"
         class="step-content"
         data-role="content">

        <form data-bind="submit: navigateToNextStep" novalidate="novalidate" class="form form-shipping-address">
            <fieldset class="fieldset">
                <!-- ko foreach: getRegion('customer-fields') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
                <!--/ko-->
            </fieldset>
        </form>
    </div>
</li>

Our first step has been created with empty content:Now let’s go a head and content inside our template.
Remember: The template already contains the region renderer with name “customer-fields”. All we have to do is to modify checkout_index_index.xml:After modification our checkout_index_index.xml looks like now:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="customer-account-step" xsi:type="array">
                                            <item name="component" xsi:type="string">uiComponent</item>
                                            <item name="sortOrder" xsi:type="string">1</item>
                                            <item name="children" xsi:type="array">
                                                <item name="customerAccount" xsi:type="array">
                                                    <item name="component" xsi:type="string">Arsal_CheckoutSteps/js/view/customer-step</item>
                                                    <item name="provider" xsi:type="string">checkoutProvider</item>
                                                    <item name="sortOrder" xsi:type="string">1</item>
                                                    <item name="children" xsi:type="array">
                                                        <item name="customer-fields" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="before-login-form" xsi:type="array">
                                                                    <item name="component" xsi:type="string">uiComponent</item>
                                                                    <item name="displayArea" xsi:type="string">before-login-form</item>
                                                                    <item name="children" xsi:type="array" />
                                                                </item>
                                                                <item name="additional-login-form-fields" xsi:type="array">
                                                                    <item name="component" xsi:type="string">uiComponent</item>
                                                                    <item name="displayArea" xsi:type="string">additional-login-form-fields</item>
                                                                    <item name="children" xsi:type="array">
                                                                        <!-- Add your custom components here -->
                                                                    </item>
                                                                </item>
                                                            </item>
                                                            <item name="component" xsi:type="string">Arsal_CheckoutSteps/js/view/account</item>
                                                            <item name="displayArea" xsi:type="string">customer-fields</item>
                                                            <item name="tooltip" xsi:type="array">
                                                                <item name="description" xsi:type="string">Enter your email associated with store.</item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>

                                        <item name="shipping-step" xsi:type="array">
                                            <item name="sortOrder" xsi:type="string">2</item>
                                        </item>
                                        <item name="billing-step" xsi:type="array">
                                            <item name="sortOrder" xsi:type="string">3</item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

According to above layout we need to add another component which will be responsible for creating a login form for us.
Create account.js component inside your web directory:
Arsal/CheckoutSteps/view/frontend/web/js/view/account.js
define(
    [
        'jquery',
        'uiComponent',
        'ko',
        'Magento_Customer/js/model/customer',
        'Magento_Customer/js/action/login',
        'Magento_Checkout/js/model/quote',
        'Magento_Checkout/js/checkout-data',
        'Magento_Checkout/js/model/full-screen-loader',
        'mage/validation'
    ], function (
        $,
        Component,
        ko,
        customer,
        loginAction,
        quote,
        checkoutData,
        fullScreenLoader
    ) {
        'use strict';

        return Component.extend({
            defaults: {
                template: 'Arsal_CheckoutSteps/form/account',
                email: checkoutData.getInputFieldEmailValue(),
            },
            emailFocused: false,
            forgotPasswordUrl: window.checkoutConfig.forgotPasswordUrl,
            createNewAccountUrl: window.checkoutConfig.registerUrl,

            /**
             * Initializes observable properties of instance
             *
             * @returns {Object} Chainable.
             */
            initObservable: function () {
                this._super()
                    .observe(['email','emailFocused']);

                return this;
            },

            /**
             * Log in form submitting callback.
             *
             * @param {HTMLElement} loginForm - form element.
             */
            login: function (loginForm) {
                var loginData = {},
                    formDataArray = $(loginForm).serializeArray();

                formDataArray.forEach(function (entry) {
                    loginData[entry.name] = entry.value;
                });

                if ($(loginForm).validation() && $(loginForm).validation('isValid')) {
                    fullScreenLoader.startLoader();
                    loginAction(loginData, window.checkoutConfig.checkoutUrl).always(function () {
                        fullScreenLoader.stopLoader();
                    });
                }
            }
        });
    }
);

Now create its renderer template:
Arsal/CheckoutSteps/view/frontend/web/template/form/account.html
<!-- ko foreach: getRegion('before-login-form') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
<form class="form form-login"  data-bind="submit:login"
      method="post">
    <fieldset id="customer-account-fieldset" class="fieldset">
        <div class="field required">
            <label class="label" for="customer-email">
                <span data-bind="i18n: 'Email Address'"></span>
            </label>
            <div class="control _with-tooltip">
                <input class="input-text"
                       type="email"
                       data-bind="
                            textInput: email,
                            hasFocus: emailFocused,
                            mageInit: {'mage/trim-input':{}}"
                       name="username"
                       data-validate="{required:true, 'validate-email':true}"
                       id="customer-email" />
                <!-- ko template: 'ui/form/element/helper/tooltip' --><!-- /ko -->
            </div>
        </div>

        <div class="field">
            <label class="label" for="customer-password">
                <span data-bind="i18n: 'Password'"></span>
            </label>
            <div class="control">
                <input class="input-text"
                       data-bind="
                                attr: {
                                    placeholder: $t('Password'),
                                }"
                       type="password"
                       name="password"
                       id="customer-password"
                       data-validate="{required:true}" autocomplete="off"/>
                <span class="note" data-bind="i18n: 'Sign in to continue.'"></span>
            </div>

        </div>
        <!-- ko foreach: getRegion('additional-login-form-fields') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
        <!-- /ko -->
        <div class="actions-toolbar">
            <input name="context" type="hidden" value="checkout" />
            <div class="primary">
                <button type="submit" class="action login primary" data-action="checkout-method-login"><span data-bind="i18n: 'Login'"></span></button>
            </div>
            <div class="secondary">
                <a class="action remind" data-bind="attr: { href: forgotPasswordUrl }">
                    <span data-bind="i18n: 'Forgot Your Password?'"></span>
                </a>
                <a class="action create" data-bind="attr: { href: createNewAccountUrl }">
                    <span data-bind="i18n: 'Create Your Account'"></span>
                </a>
            </div>
        </div>

    </fieldset>
</form>

Now our Layout should look like so:This form is completely functional, thanks to our components.
Now try loging into your account via these field, this will log you into your account and will auto refresh to display changes. The loaded page exlude this step as per our logic and will directly display shipping step.Congragulations! you’ve completed your first objective. Now let’s keep going and add another step to our checkout to enhance the page.
Let’s modify checkout_index_index.xml again by adding our success component along with sort order:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="customer-account-step" xsi:type="array">
                                            <item name="component" xsi:type="string">uiComponent</item>
                                            <item name="sortOrder" xsi:type="string">1</item>
                                            <item name="children" xsi:type="array">
                                                <item name="customerAccount" xsi:type="array">
                                                    <item name="component" xsi:type="string">Arsal_CheckoutSteps/js/view/customer-step</item>
                                                    <item name="provider" xsi:type="string">checkoutProvider</item>
                                                    <item name="sortOrder" xsi:type="string">1</item>
                                                    <item name="children" xsi:type="array">
                                                        <item name="customer-fields" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="before-login-form" xsi:type="array">
                                                                    <item name="component" xsi:type="string">uiComponent</item>
                                                                    <item name="displayArea" xsi:type="string">before-login-form</item>
                                                                    <item name="children" xsi:type="array" />
                                                                </item>
                                                                <item name="additional-login-form-fields" xsi:type="array">
                                                                    <item name="component" xsi:type="string">uiComponent</item>
                                                                    <item name="displayArea" xsi:type="string">additional-login-form-fields</item>
                                                                    <item name="children" xsi:type="array">
                                                                        <!-- Add your custom components here -->
                                                                    </item>
                                                                </item>
                                                            </item>
                                                            <item name="component" xsi:type="string">Arsal_CheckoutSteps/js/view/account</item>
                                                            <item name="displayArea" xsi:type="string">customer-fields</item>
                                                            <item name="tooltip" xsi:type="array">
                                                                <item name="description" xsi:type="string">Enter your email associated with store.</item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>

                                        <item name="shipping-step" xsi:type="array">
                                            <item name="sortOrder" xsi:type="string">2</item>
                                        </item>
                                        <item name="billing-step" xsi:type="array">
                                            <item name="sortOrder" xsi:type="string">3</item>
                                        </item>

                                        <item name="success" xsi:type="array">
                                            <item name="component" xsi:type="string">uiComponent</item>
                                            <item name="sortOrder" xsi:type="string">4</item>
                                            <item name="children" xsi:type="array">
                                                <item name="orderSuccess" xsi:type="array">
                                                    <item name="component" xsi:type="string">Arsal_CheckoutSteps/js/view/success-step</item>
                                                    <item name="provider" xsi:type="string">checkoutProvider</item>
                                                    <item name="sortOrder" xsi:type="string">1</item>
                                                    <item name="config" xsi:type="array">
                                                        <item name="template" xsi:type="string">Arsal_CheckoutSteps/successStep</item>
                                                        <item name="title" xsi:type="string">Thank you for your purchase!</item>
                                                    </item>
                                                    <item name="children" xsi:type="array" />
                                                </item>
                                            </item>
                                        </item>

                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

As per layout we need to create component success-step and template successStep
Let’s create our component first:
Arsal/CheckoutSteps/view/frontend/web/js/view/success-step.js
define(
    [
        'jquery',
        'ko',
        'uiComponent',
        'underscore',
        'Magento_Checkout/js/model/step-navigator',
        'Magento_Checkout/js/model/quote',
        'Magento_Customer/js/model/customer',
        'mage/translate',
        'mage/url',
        'Magento_Checkout/js/model/full-screen-loader'
    ],
    function (
        $,
        ko,
        Component,
        _,
        stepNavigator,
        quote,
        customer,
        $t,
        url,
        fullScreenLoader
    ) {
        'use strict';

        return Component.extend({

            isVisible: ko.observable(true),
            title: 'Success Page',

            initialize: function (config) {
                this._super();

                stepNavigator.registerStep(
                    'success-step',
                    null,
                    $t('Success'),
                    this.isVisible,
                    _.bind(this.navigate, this),
                    22
                );

                if (config.title !== undefined) {
                    this.title = config.title;
                }

                return this;
            },

            navigate: function() {},

            /**
             * @returns void
             */
            navigateToNextStep: function () {
                fullScreenLoader.startLoader();
                window.location.replace(url.build(''));
            },

            getOrderText: function () {
                return 'Your order has been placed Successfully. Click Continue to proceed with shopping'
            },

            getOrderViewUrl: function () {
                return url.build('sales/order/history');
            }
        });
    }
);

Create template file successStep
Arsal/CheckoutSteps/view/frontend/web/template/successStep.html
<li id="customer-step" data-bind="fadeVisible: isVisible">
    <div class="step-title" data-bind="i18n: title" data-role="title"></div>
    <div id="success-step-title"
         class="step-content"
         data-role="content">

        <form data-bind="submit: navigateToNextStep" novalidate="novalidate" class="form">
            <fieldset class="fieldset">
                <div class="checkout-success">
                    <p data-bind="text: getOrderText()"></p>
                    <div class="view-orders">
                        <a class="action view-orders" data-bind="attr: { href: getOrderViewUrl() }, text: 'View Your Orders'"></a>
                    </div>
                </div>
            </fieldset>
            <div class="actions-toolbar">
                <div class="primary">
                    <button data-role="opc-continue" type="submit" class="button action continue primary">
                        <span><!-- ko i18n: 'Continue Shopping'--><!-- /ko --></span>
                    </button>
                </div>
            </div>
        </form>
    </div>
</li>

Until now we are good. But we are still facing an issue here. The issue is accessing the last step i.e success step after placing order.
This arises the difficulty level. To consider solution to this we have multiple options, like:
  1. Extend default.js component present in Magento_Checkout/js/view/payment/default.js and add our logic to afterPlaceOrder method.
  2. Extend / customize Magento_Checkout/js/action/redirect-on-success.js action and add custom logic to deal with navigator.
Both steps are valid and you may choose any of above to deal with navigator. For simplicity we will go with point 2 i.e. customize redirect-on-success action.Before doing that we need to map the action js. To do so lets go inside our frontend directory and create requirejs-config.js
Arsal/CheckoutSteps/view/frontend/requirejs-config.js
var config = {
    map: {
        '*' : {
            'Magento_Checkout/js/action/redirect-on-success':
                'Arsal_CheckoutSteps/js/action/redirect-on-success'
        }
    }
};

Now according to our requirejs-config create an action js file:
Arsal/CheckoutSteps/view/frontend/web/js/action/redirect-on-success
define(
    [
        'Magento_Checkout/js/model/step-navigator'
    ],
    function (stepNavigator) {
        'use strict';

        return {
            execute: function () {
                stepNavigator.next();
            }
        }
    }
);


This action file is great help to us and thus prove best in redirecting magento to our next step.To further enhance the Order success step, we would continue by declaring and creating the controller. Create routes.xml:
Arsal/CheckoutSteps/etc/frontend/routes.xml
<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="checkoutsteps" frontName="checkoutsteps">
            <module name="Arsal_CheckoutSteps" />
        </route>
    </router>
</config>

Now create a controller “Success”:
Arsal/CheckoutSteps/Controller/Index/Success.php
<?php
namespace Arsal\CheckoutSteps\Controller\Index;

use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Checkout\Model\Session;
class Success extends Action
{

    /**
     * @var JsonFactory $resultJsonFactory
     */
    protected $resultJsonFactory;

    /**
     * @var Session $checkoutSession
     */
    private $checkoutSession;

    /**
     * @var OrderRepositoryInterface $orderRepository
     */
    private $orderRepository;

    /**
     * Success constructor.
     * @param Context $context
     * @param JsonFactory $resultJsonFactory
     * @param Session $session
     * @param OrderRepositoryInterface $orderRepository
     */
    public function __construct(
        Context $context,
        JsonFactory $resultJsonFactory,
        Session $session,
        OrderRepositoryInterface $orderRepository
    ) {
        parent::__construct($context);
        $this->resultJsonFactory = $resultJsonFactory;
        $this->checkoutSession = $session;
        $this->orderRepository = $orderRepository;
    }

    
    public function execute()
    {

        /** @var \Magento\Framework\Controller\Result\Json $resultJson */
        $resultJson = $this->resultJsonFactory->create();
        $orderId = $this->checkoutSession->getData('last_order_id');
        $response = [];
        if (!empty($orderId)) {
            $order = $this->orderRepository->get($orderId);
            $items = [];
            foreach ($order->getItems() as $item) {
                $items[] = $item->getData();
            }
            $response = [
                'orderId'       =>  $order->getIncrementId(),
                'orderItems'    =>  $items,
                'shippingAddress'   =>  $order->getShippingAddress()->getData(),
                'billingAddress'   =>  $order->getBillingAddress()->getData(),
                'grandTotal'        =>  $order->getBaseGrandTotal(),
                'shippingTotal'        =>  $order->getBaseShippingAmount(),
            ];
        }

        $resultJson->setData($response);
        return $resultJson;
    }
}

Now open up your component “success-step.js” and update with the following code:
Arsal/CheckoutSteps/view/frontend/web/js/view/success-step.js
define(
    [
        'jquery',
        'ko',
        'uiComponent',
        'underscore',
        'Magento_Checkout/js/model/step-navigator',
        'Magento_Checkout/js/model/quote',
        'Magento_Catalog/js/price-utils',
        'Magento_Customer/js/model/customer',
        'mage/translate',
        'mage/url',
        'Magento_Checkout/js/model/full-screen-loader',
        'mage/storage'
    ],
    function (
        $,
        ko,
        Component,
        _,
        stepNavigator,
        quote,
        priceUtils,
        customer,
        $t,
        url,
        fullScreenLoader,
        storage
    ) {
        'use strict';

        return Component.extend({

            isVisible: ko.observable(false),
            order: ko.observable([]),
            displayOrderInfo: ko.observable(false),
            title: 'Success Page',
            orderId: ko.observable(),
            shippingAddress: ko.observable(false),

            initialize: function (config) {
                this._super();

                var self = this;

                this.isVisible.subscribe(function (value) {
                    if (value) {
                        fullScreenLoader.startLoader();
                        storage.post(
                            url.build('checkoutsteps/index/success'), JSON.stringify([])
                        ).always(
                            function (response) {
                                fullScreenLoader.stopLoader();
                                if (response && response.orderId !== undefined) {
                                    self.order(response);
                                    self.orderId(response.orderId);
                                    self.displayOrderInfo(true);
                                    var customerData = window.checkoutConfig.customerData;
                                    if (
                                        customerData !== undefined
                                        && customerData.addresses !== undefined
                                        && customerData.addresses[0] !== undefined
                                        && customerData.addresses[0].length
                                        && customerData.addresses[0].inline !== undefined
                                    )  {
                                        self.shippingAddress(customerData.addresses[0].inline);
                                    }
                                    else {
                                        self.__setAddress(response.shippingAddress, self);
                                    }

                                }
                            }
                        )
                    }
                });


                stepNavigator.registerStep(
                    'success-step',
                    null,
                    $t('Success'),
                    this.isVisible,
                    _.bind(this.navigate, this),
                    22
                );

                if (config.title !== undefined) {
                    this.title = config.title;
                }

                return this;
            },

            navigate: function() {},

            /**
             * @returns void
             */
            navigateToNextStep: function () {
                fullScreenLoader.startLoader();
                window.location.replace(url.build(''));
            },

            getOrderText: function () {
                return 'Your order has been placed Successfully.'
            },

            getOrderViewUrl: function () {
                return url.build('sales/order/history');
            },

            getQuoteItems: function() {
                return window.checkoutConfig.quoteItemData;
            },

            getTotalsData: function() {
                return window.checkoutConfig.totalsData.total_segments;
            },

            getFormattedPrice: function (price) {
                return priceUtils.formatPrice(price, quote.getPriceFormat());
            },

            __setAddress: function ($addressObj, instance) {
                if (instance === undefined) {
                    instance = this;
                }
                var addressString = '';
                addressString += $addressObj.firstname + ' ' + $addressObj.lastname + ', ';
                addressString += $addressObj.street + ', ';
                if ($addressObj.city !== undefined) {
                    addressString = $addressObj.city + ', ';
                }

                if ($addressObj.region !== undefined) {
                    addressString += $addressObj.region + ' ';
                }
                if ($addressObj.postCode !== undefined) {
                    addressString += $addressObj.postCode + ' ';
                }
                addressString += $addressObj.country_id;

                if ($addressObj.address_type === 'shipping') {
                    instance.shippingAddress(addressString);
                }
            }
        });
    }
);

Now update your template “successStep” accordingly:
Arsal/CheckoutSteps/view/frontend/web/template/successStep.html
<li id="customer-step" data-bind="fadeVisible: isVisible">
    <div class="step-title" data-bind="i18n: title" data-role="title"></div>
    <div id="success-step-title"
         class="step-content"
         data-role="content">

        <form data-bind="submit: navigateToNextStep" novalidate="novalidate" class="form">
            <fieldset class="fieldset">
                <div class="checkout-success">
                    <p data-bind="text: getOrderText()"></p>
                    <div data-bind="fadeVisible: displayOrderInfo, attr: { class: 'order-information' }">
                        <p>Your Order Id is: #<strong data-bind="text: orderId"></strong></p>
                        <div class="address-section">
                            <div class="shipping-address" data-bind="fadeVisible: shippingAddress">
                                <h3 data-bind="text: 'Shipping Address'"></h3>
                                <p data-bind="text: shippingAddress"></p>
                            </div>
                        </div>
                        <div class="product-information">
                            <h3 data-bind="text: 'Product Information'"></h3>
                            <ul data-bind="foreach: getQuoteItems()">
                                <li>
                                    <ul>
                                        <li>
                                            <img data-bind="attr: {src: thumbnail, alt: name, title: name}" />
                                        </li>
                                        <li>
                                            <div data-bind="text: name"></div>
                                            <div class="sku">
                                                SKU: <span data-bind="text: sku"></span>
                                            </div>
                                            <div class="qty">
                                                Qty: <span data-bind="text: qty"></span>
                                            </div>
                                            <div class="Price">
                                                Price: <span data-bind="text: $parent.getFormattedPrice(price)"></span>
                                            </div>
                                            <div class="tax-amount">
                                                Tax: <span data-bind="text: $parent.getFormattedPrice(tax_amount)"></span>
                                            </div>
                                            <div class="row-total">
                                                Row Total: <span data-bind="text: $parent.getFormattedPrice(row_total_incl_tax)"></span>
                                            </div>
                                        </li>
                                    </ul>
                                </li>
                            </ul>
                        </div>
                        <div class="order-summary">
                            <ul data-bind="foreach: getTotalsData()">
                               <li>
                                   <span data-bind="text: title"></span>
                                   <span data-bind="text: $parent.getFormattedPrice(value)"></span>
                               </li>
                            </ul>
                        </div>
                    </div>
                    <div class="view-orders">
                        <a class="action view-orders" data-bind="attr: { href: getOrderViewUrl() }, text: 'View Your Orders'"></a>
                    </div>

                </div>
            </fieldset>
            <div class="actions-toolbar">
                <div class="primary">
                    <button data-role="opc-continue" type="submit" class="button action continue primary">
                        <span><!-- ko i18n: 'Continue Shopping'--><!-- /ko --></span>
                    </button>
                </div>
            </div>
        </form>
    </div>
</li>

The module is available on github:
https://github.com/arsalanworld/checkout-steps

How useful was this post?

Click on a star to rate it!

Average rating / 5. Vote count:

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

8 Comments

  • Wonderful post! We will be linking to this great post on our site. Keep up the good writing.

  • I dugg some of you post as I thought they were very useful very beneficial

    • thank you, I am glad you found the posts helpful.

  • Awesome post! Keep up the great work! 🙂

  • Wow great. Thanks alot for this. Appreciated!

Leave a Reply

Your email address will not be published. Required fields are marked *