Here's a simple method that can be used to make any required address field optional.
First create a plugin for Magento\Checkout\Block\Checkout\LayoutProcessor
. Define the class as follow:
<?php
namespace Vendor\Module\Plugin;
class LayoutProcessor
{
public function afterProcess(
\Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
$jsLayout
) {
// Make fields not required
$nameLayout = [
'validation' => [
'required_entry' => false
]
];
// Change in shipping address
$firstnameField = &$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['firstname'];
$lastnameField = &$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['lastname'];
$firstnameField = array_merge($firstnameField, $nameLayout);
$lastnameField = array_merge($lastnameField, $nameLayout);
// Change in billing address
foreach ($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children']['payments-list']['children'] as &$child)
{
if (isset($child['children']['form-fields'])) {
$child['children']['form-fields']['children']['firstname'] =
array_merge($child['children']['form-fields']['children']['firstname'], $nameLayout);
$child['children']['form-fields']['children']['lastname'] =
array_merge($child['children']['form-fields']['children']['lastname'], $nameLayout);
}
}
return $jsLayout;
}
}
All this does is change the first and last name fields to optional in the checkout address forms. However, if the fields are left blank, the various address verifications that occur on the server-side will fail so there's one more step to get around the verification.
We'll make a plugin for the getFirstname
and getLastname
methods of Magento\Quote\Model\Quote\Address
as follows:
<?php
namespace Vendor\Module\Plugin;
class Address
{
public function afterGetFirstname(
\Magento\Quote\Model\Quote\Address $subject,
$result
) {
if (empty(trim($result))) {
return "N/A";
}
return $result;
}
public function afterGetLastname(
\Magento\Quote\Model\Quote\Address $subject,
$result
) {
if (empty(trim($result))) {
return "N/A";
}
return $result;
}
}
In this plugin we check if the address has a first and last name associated with it. If not then we emit a placeholder value to satisfy the verification. This is much simpler than having to override all the classes involved in address verification.
With these two plugins in place, the first and last name fields in checkout will be optional.