8

Does anyone know whether it is possible to move the customer registration step to the checkout like in the original Magento 1 checkout? Looking for an extension that will do this for me or advice on how I could achieve this.

5
  • You can add steps to checkout by following here: devdocs.magento.com/guides/v2.0/howdoi/checkout/…
    – harri
    Nov 28, 2017 at 8:49
  • Once completing checkout magento also gives option now to create an account from the details provided during checkout on the success page.
    – harri
    Nov 28, 2017 at 8:50
  • @harri I know that's how it works but we have a client that wants the registration to happen the same time as the order being placed.
    – Jason
    Nov 28, 2017 at 9:03
  • @Jason Did you get any solution for this? Mar 26, 2018 at 12:23
  • Check here github.com/danslo/CleanCheckout
    – Sohel Rana
    Jun 3, 2018 at 14:52

1 Answer 1

2

I Would go about by creating a step in checkout this detects whether you are logged in or not and then shows the form accordingly.

Load the registration form into this step over ajax and modify the after register event detecting whether registration was made the checkout redirecting back to checkout rather than the dashboard.

I got as far as adding a working step that shows when not signed in for registration and redirecting the registration success back to checkout disabling the previous step for a smooth user experience.

Offering a login option if the user has an account but has not logged in at this stage would improve further here.

This is full code if you want to check over all of it was a lot to include in the answer:

https://github.com/harrigo/RegisterCheckout

Create a register form within controller:

As the checkout steps need some php to run to get the form url and key etc a controller will be needed so we can load this register form over ajax into the step.

<?php
namespace Harrigo\RegisterCheckout\Controller\Index;

use Magento\Framework\Controller\ResultFactory;

class Register extends \Magento\Framework\App\Action\Action
{
    protected $resultPageFactory;
    
    /**
     * Constructor
     * 
     * @param \Magento\Framework\App\Action\Context  $context
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory
    )
    {
        $this->resultPageFactory = $resultPageFactory;
        $this->_resultFactory = $context->getResultFactory();
        parent::__construct($context);
    }
    
    /**
     * Execute view action
     * 
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        //if (isset($_POST["cart"])) {
            $resultLayout = $this->resultFactory->create(ResultFactory::TYPE_LAYOUT);
            return $resultLayout;   
        //}
        //$this->_redirect('checkout/');

    }
}

Controller/Index/Register.php

The below renders the registration blocks within controller so we can then call over ajax into the checkout.

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
  <container name="root" label="Root">
            <block class="Magento\Framework\View\Element\Js\Components" name="customer_account_create_head_components" template="Magento_Customer::js/components.phtml"/>
            <block class="Magento\Customer\Block\Form\Register" name="customer_form_register" template="Harrigo_RegisterCheckout::register.phtml">
                <container name="form.additional.info" as="form_additional_info"/>
                <container name="customer.form.register.fields.before" as="form_fields_before" label="Form Fields Before" htmlTag="div" htmlClass="customer-form-before"/>
            </block>
            <block class="Magento\Cookie\Block\RequireCookie" name="require-cookie" template="Magento_Cookie::require_cookie.phtml">
                <arguments>
                    <argument name="triggers" xsi:type="array">
                        <item name="registerSubmitButton" xsi:type="string">.action.submit</item>
                    </argument>
                </arguments>
            </block>
            <block class="Magento\Framework\View\Element\Template" name="form_additional_info_customer" template="Magento_Customer::additionalinfocustomer.phtml"/>
  </container>
</layout>

/view/frontend/layout/harrigoregister_index_register.xml

Make sure to add routes.xml within the etc/frontend folder of the module.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
    <router id="standard">
        <route id="harrigoregister" frontName="harrigoregister">
            <module name="Harrigo_RegisterCheckout" />
        </route>
    </router>
</config>

Create a checkout step:

http://devdocs.magento.com/guides/v2.0/howdoi/checkout/checkout_new_step.html

As this is first step make sure to add the mixins just like I have done in module as the devdocs is incorrect here leading to every step showing:

<!--The 'step_code' value from the .js file should be used-->
<li id="registerstep" data-bind="fadeVisible: isVisible">
<div class="step-title" data-bind="i18n: 'Register'" data-role="title"></div>
    <div id="checkout-step-title"
         class="step-content"
         data-role="content">
        <form data-bind="submit: navigateToNextStep" novalidate="novalidate">
            <div class="actions-toolbar" id="shipping-method-buttons-container">
                <div class="primary">
                    <button data-role="opc-continue" type="submit" class="button action continue primary">
                        <span><!-- ko i18n: 'Continue as guest'--><!-- /ko --></span>
                    </button>
                </div>
            </div>
        </form>
    </div>  
    <div id="registerblock"></div>
</li>

This was failing if block hadn't loaded before the ajax call but ended up using something like this to get our registration form from the controller and spit it onto the step:

//waits for elements to load in checkout
function waitForElement(elementPath, callBack){
  window.setTimeout(function(){
    if($(elementPath).length){
      callBack(elementPath, $(elementPath));
    }else{
      waitForElement(elementPath, callBack);
    }
  },500)
}

//get crosssell products / newsletter
$.ajax({
  url: "/harrigoregister/index/register",
  type: "post",
  data: { 
    cart: "yes"
  },
  success: function(response) {
    waitForElement("#registerblock",function(){
                $("#registerblock").html(response);
        });
  },
  error: function(xhr) {
  }
});

There are a lot more steps here just follow the devdocs making sure to do the mixin step but use below for mixin as devdocs example doesn't work:

define(
    [
        'ko',
        'Magento_Customer/js/model/customer'
    ], function (ko, customer) {
        'use strict';

        var mixin = {

            initialize: function () {
                if(!customer.isLoggedIn()) {
                    this.isVisible = ko.observable(false);
                    this.visible = ko.observable(false); // set visible to be initially false to have your step show first
                }
                    this._super();
                
                return this;
            }
        };

        return function (target) {
            return target.extend(mixin);
        };
    }
);

Main differences were the payment and shipping steps use isVisible and Visible and devdocs only uses visible within example so isVisible needed to be added to fix. Also had to make adjustments for if the step was disabled.

Modify Registration Redirect:

https://magento.stackexchange.com/questions/131850/magento-2-redirect-user-to-specific-page-after-register

<?php

namespace Harrigo\RegisterCheckout\Plugin;

use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Registry;
use Magento\Framework\UrlInterface;

class Redirect
{
    protected $coreRegistry;

    protected $url;

    protected $resultFactory;


    public function __construct(Registry $registry, UrlInterface $url, ResultFactory $resultFactory)
    {
        $this->coreRegistry = $registry;
        $this->url = $url;
        $this->resultFactory = $resultFactory;
    }

    public function aroundGetRedirect ($subject, \Closure $proceed)
    {
        //need to check out if registration was from checkouit
        /** @var \Magento\Framework\Controller\Result\Redirect $result */

        if ($_POST['checkout'] = 'true') {
            $result = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
            $result->setUrl($this->url->getUrl('checkout'));
            return $result;
        }

        return $proceed();
    }
}

Rough example but also had to override the register.phtml to add the checkout post variable to determine the difference between the 2 forms. There where a lot of steps I didnt show but check the module i created for complete example.

1
  • hello @harri in this register form google recaptcha not working... i added mageplaza recaptcha plugin for this custom form and add action in custom form position => Form Post Paths => account/createpost/?checkout=yes added and CSS Selectors=> form-create-account after that v2 invisible recaptcha visible but after that register form not working... magento ver 2.3.3...can you help me please? Jun 17, 2022 at 10:41

Your Answer

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

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