Magento – How to change the order of the billing address fields on checkout page in Magento 2

checkoutknockoutjsmagento-2.1magento2onepage-checkout

I want to change the ordering of Address fields for both shipping address and billing address on checkout page

I have changed the order of shipping Address and is working fine (thanks to this answer)

The following is the content of My theme's checkout_index_index.xml layout file

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout" 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="shipping-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="shippingAddress" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="shipping-address-fieldset" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="country_id" xsi:type="array">
                                                                    <item name="sortOrder" xsi:type="string">85</item>
                                                                </item>
                                                                <item name="region_id" xsi:type="array">
                                                                    <item name="sortOrder" xsi:type="string">87</item>
                                                                </item>
                                                                <item name="city" xsi:type="array">
                                                                    <item name="sortOrder" xsi:type="string">90</item>
                                                                </item>
                                                                <item name="postcode" xsi:type="array">
                                                                    <item name="sortOrder" xsi:type="string">91</item>
                                                                </item>
                                                                <item name="telephone" xsi:type="array">
                                                                    <item name="sortOrder" xsi:type="string">94</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

But when I tried to update order of Billing address it did not changed. I have also checked the original checkout_index_index.xml layout file in Magento_Checkout module there is not fields in billing-step.

Do anyone know how to do this ?

Best Answer

Here is an example (using Plugin) for changing field order, disabling field or adding missing field to address.

File: etc/di.xml

<type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
    <plugin disabled="false" name="Vendor_Module_Plugin_Block_Checkout_LayoutProcessor" sortOrder="99"
                type="Vendor\Module\Plugin\Block\Checkout\LayoutProcessor"/>
</type>

File: Plugin/Block/Checkout/LayoutProcessor.php

<?php

namespace Vendor\Module\Plugin\Block\Checkout;

use Magento\Checkout\Block\Checkout\LayoutProcessor as MageLayoutProcessor;

class LayoutProcessor
{
    public function afterProcess(MageLayoutProcessor $subject, $jsLayout)
    {

        /* config: checkout/options/display_billing_address_on = payment_method */
        if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
            ['payment']['children']['payments-list']['children']
        )) {

            foreach ($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                     ['payment']['children']['payments-list']['children'] as $key => $payment) {

                /* company */
                if (isset($payment['children']['form-fields']['children']['company'])) {

                    $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                    ['payment']['children']['payments-list']['children'][$key]['children']['form-fields']['children']
                    ['company']['sortOrder'] = 0;
                }

                /* region & region_id */
                if (isset($payment['children']['form-fields']['children']['region'])) {

                    $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                    ['payment']['children']['payments-list']['children'][$key]['children']['form-fields']['children']
                    ['region']['visible'] = false;

                    $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                    ['payment']['children']['payments-list']['children'][$key]['children']['form-fields']['children']
                    ['region']['config']['componentDisabled'] = true;
                }
                if (isset($payment['children']['form-fields']['children']['region_id'])) {

                    $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                    ['payment']['children']['payments-list']['children'][$key]['children']['form-fields']['children']
                    ['region_id']['visible'] = false;

                    $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                    ['payment']['children']['payments-list']['children'][$key]['children']['form-fields']['children']
                    ['region_id']['config']['componentDisabled'] = true;
                }

                $method = substr($key, 0, -5);

                /* vat_id */
                $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['payments-list']['children'][$key]['children']['form-fields']['children']
                ['vat_id'] = [
                    'component' => 'Magento_Ui/js/form/element/abstract',
                    'config' => [
                        'customScope' => 'billingAddress' . $method,
                        'customEntry' => null,
                        'template' => 'ui/form/field',
                        'elementTmpl' => 'ui/form/element/input',
                        'tooltip' => null,
                    ],
                    'dataScope' => 'billingAddress' . $method . '.vat_id',
                    'dataScopePrefix' => 'billingAddress' . $method,
                    'label' => __('VAT number'),
                    'provider' => 'checkoutProvider',
                    'sortOrder' => 1,
                    'validation' => [],
                    'options' => [],
                    'filterBy' => null,
                    'customEntry' => null,
                    'visible' => true,
                ];
            }
        }

        /* config: checkout/options/display_billing_address_on = payment_page */
        if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
            ['payment']['children']['afterMethods']['children']['billing-address-form']
        )) {

            /* company */
            if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']
                ['children']['company']
            )) {
                $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']
                ['children']['company']['sortOrder'] = 0;
            }

            /* region & region_id */
            if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']
                ['children']['region'])) {

                $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']
                ['children']['region']['visible'] = false;

                $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']
                ['children']['region']['config']['componentDisabled'] = true;
            }
            if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']
                ['children']['region_id'])) {

                $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']
                ['children']['region_id']['visible'] = false;

                $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']
                ['children']['region_id']['config']['componentDisabled'] = true;
            }

            $method = 'shared';

            /* vat_id */
            $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
            ['payment']['children']['afterMethods']['children']['billing-address-form']['children']['form-fields']
            ['children']['vat_id'] = [
                'component' => 'Magento_Ui/js/form/element/abstract',
                'config' => [
                    'customScope' => 'billingAddress' . $method,
                    'customEntry' => null,
                    'template' => 'ui/form/field',
                    'elementTmpl' => 'ui/form/element/input',
                    'tooltip' => null,
                ],
                'dataScope' => 'billingAddress' . $method . '.vat_id',
                'dataScopePrefix' => 'billingAddress' . $method,
                'label' => __('VAT number'),
                'provider' => 'checkoutProvider',
                'sortOrder' => 1,
                'validation' => [],
                'options' => [],
                'filterBy' => null,
                'customEntry' => null,
                'visible' => true,
            ];
        }

        return $jsLayout;
    }
}