2

I need to add some fields to the shipping address form from checkout page, and then save them in database. Please tell me how to do this thing?

3

3 Answers 3

4

A quick example shows how to add a custom field in checkout page and save it into database.

First of all, because the necessary information of quote table will be transferred to sales order, so we should create our new custom field custom_test in quote and sales_order tables:

app/code/Vendor/Module/Setup/UpgradeSchema.php

<?php

namespace Vendor\Module\Setup;

use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;

class UpgradeSchema implements UpgradeSchemaInterface
{
    /**
     * Upgrades DB schema for a module
     *
     * @param SchemaSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        $quoteAddressTable = 'quote';
        $orderTable = 'sales_order';

        //Quote address table
        $setup->getConnection()
            ->addColumn(
                $setup->getTable($quoteAddressTable),
                'custom_test',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    'length' => 255,
                    'comment' =>'Custom Test'
                ]
            );
        //Order address table
        $setup->getConnection()
            ->addColumn(
                $setup->getTable($orderTable),
                'custom_test',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    'length' => 255,
                    'comment' =>'Custom Test'

                ]
            );

        $setup->endSetup();
    }
}

Add our custom field to checkout page app/code/Vendor/Module/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="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">
                                                            <!--Our custom test fieldset here-->
                                                            <item name="children" xsi:type="array">
                                                                <item name="customer_test" xsi:type="array">
                                                                    <item name="sortOrder" xsi:type="string">300</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Create fieldset.xml

app/code/Vendor/Module/etc/fieldset.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:DataObject/etc/fieldset.xsd">
    <scope id="global">
        <fieldset id="sales_convert_quote">
            <field name="custom_test">
                <aspect name="to_order" />
            </field>
        </fieldset>
    </scope>
</config>

Basically, this fieldset is used for defining the attribute which will be copied from quote object to order object automatically.

Don't forget to create registration.php and etc/module.xml

app/code/Vendor/Module/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_Module',
    __DIR__
);

app/code/Vendor/Module/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="Vendor_Module" setup_version="1.0.0"/>
</config>

Run setup upgrade command: php bin/magento setup:upgrade. Now, we can see our new custom field in checkout page and database quote and sales_order.

After that, now we can create more functions to work with quote and order objects.

5
  • After I installed your module, the custom field show up in tables quote_address and sales_order_address, but it not appear in frontend shipping address form.
    – user42234
    Jul 17, 2016 at 9:03
  • I made some changes to this module and now I can see the custom field in frontend but I can't save it in db. I checked for errors in var directory and all is well.Please help me!
    – user42234
    Jul 18, 2016 at 12:54
  • I will check! How you fixed the custom field on the frontend? Jul 18, 2016 at 13:06
  • I think the problem appears when I click the next button, Custom checkout field is not sent in post data request, If you check the console you will see this. I don't know why this is happening. You can check this in the new version of module: github.com/rlaa/custom-checkout-fields/blob/master/…
    – user42234
    Jul 19, 2016 at 8:55
  • 1
    Hi, may i know how this save to database part work? I dont see any code which can save to the database in your code. I've do exactly as you, but ignore the UpgradeSchema.php and fieldset.xml. Does that 2 files are everything it need to save to database?
    – fudu
    Sep 13, 2018 at 15:55
3

I deleted the view directory and I added the following files: app/code/Vendor/Module/etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
        <plugin name="vendor_add_custom_field" type="Vendor\Module\Plugin\Checkout\Model\Checkout\LayoutProcessor" sortOrder="100"/>
    </type>
</config>

app/code/Vendor/Module/etc/extension_attributes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Checkout\Api\Data\ShippingInformationInterface">
        <attribute code="custom_test" type="string"/>
    </extension_attributes>
</config>

app/code/Vendor/Module/Plugin/Checkout/Model/Checkout/LayoutProcessor.php

<?php
namespace Vendor\Module\Plugin\Checkout\Model\Checkout;


class LayoutProcessor

{
    public function afterProcess(
        \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
        array  $jsLayout
    ) {



        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children']['custom_test'] = [
            'component' => 'Magento_Ui/js/form/element/abstract',
            'config' => [
                'customScope' => 'shippingAddress',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/input',
                'options' => [],
                'id' => 'custom_test'
            ],
            'dataScope' => 'shippingAddress.custom_test',
            'label' => 'Custom test',
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' => [],
            'sortOrder' => 252,
            'id' => 'custom_test'
        ];

        return $jsLayout;
    }

}

after that run: php bin/magento setup:upgrade, php bin/magento cache:clean

2
  • 3
    Hi @rla i have followed the above steps but its values are not saving in sales_order and quote tables May 22, 2018 at 5:04
  • It's not working. Feb 11, 2020 at 11:16
0

Download module from GitHub and make changes as per requirements.

Magento2 Checkout Custom Form

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.