Magento 2 Add extra billing or shipping field to the checkout

Tools

  1. Mage2gen.com
  2. Knockout Chrome Extension

Examples

  1. https://github.com/experius/Magento-2-Module-Experius-ExtraCheckoutAddressFields
  2. https://github.com/experius/Magento-2-Module-Experius-ExtraCheckoutAddressFieldsTest

Steps

  1. Add address attribute via setup script
  2. Add the attributes to the extension attributes of the Address api
  3. Change the input field name and data scope to {address}.custom_attributes.{attribute_code}
  4. Add javascript mixins to transport custom_attributes values to extension_attributes values
  5. Write a plugin to save the extension_attributes data to your database destination

Params

  1. Vendor name: Experius
  2. Module name: CodeBlogAddressAttributeToCheckout
  3. Attribute name: example

Start with a basic module: download here

Step 1: Add address attribute via setup script

Create File: Setup/InstallData.php

Checkpoint 1: Address field should show in the checkout.

Step 2: Add the attributes to the extension attributes of the Address api

Create File: etc/extension_attributes.xml

Checkpoint 2: The following files are generated

var/generation/Magento/Quote/Api/Data/AddressExtension.php
var/generation/Magento/Quote/Api/Data/AddressExtensionInterface.php

It should contain getters and setters for your address attribute. In this case. setExample(), getExample()

Step 3: Change the input field name and data scope to {address}.custom_attributes.{attribute_code}

Warning: this is not pretty.

Create File: etc/frontend/di.xml

This adds an extra layout processor to the Magento checkout onepage block. Its gives us the possibility to change the form fields before the checkout is loaded.

Create File: Block/Checkout/LayoutProcessor.php

This our own layout processor. The $result param in the process method contains a array with all the fields that will be rendered on the checkout page.

Checkpoint 3: the name attribute from the input field should now contain custom_attributes

Modify file: etc/module.xml

Add a sequence so our module is loaded after the Magento Checkout module and our layout processor is triggered after the one from the magento checkout module

Step 4: Add javascript mixins to transport custom_attributes values to extension_attributes values

The javascript of the checkout looks for extra fields with name customer_attributes and includes them in the postdata to the checkout api
The api looks for extra fields to save in the extension_attributes. So we have to transport them from custom_attributes to extension_attributes.

What is a javascript mixin? Its the javascript equivalent of plugin (interceptor). Thats how i see it being a backend developer 🙂

Create file: view/frontend/requirejs-config.js

Register the mixins

Create file: view/frontend/web/js/action/create-shipping-address-mixin.js

For the logged in customers the create shipping addres mixin is needed and it requires a key value content. Only in this case 🙁

Create file: view/frontend/web/js/action/set-billing-address-mixin.js

Create file: view/frontend/web/js/action/set-shipping-information-mixin.js

Checkpoint 4: Enable your browsers inspector, monitor ajax calls. When you save the shipping or billing address the example value should now be in both the custom_attributes and extension_attributes when you look at the post data

Step 5 Write a plugin to save the extension_attributes data to your database destination

Create file: etc/di.xml

This registers your plugin classes

Create file: Plugin/Magento/Quote/Model/BillingAddressManagement.php

Create file: Plugin/Magento/Quote/Model/ShippingAddressManagement.php

Checkpoint 5: Place your order. Check the quote_address table in the database. You should see the entered value in the example field in the example column