diff --git a/vendor/magento/module-customer-custom-attributes/Block/Checkout/AttributeMerger.php b/vendor/magento/module-customer-custom-attributes/Block/Checkout/AttributeMerger.php
index 69c4572a749..160cd621340 100644
--- a/vendor/magento/module-customer-custom-attributes/Block/Checkout/AttributeMerger.php
+++ b/vendor/magento/module-customer-custom-attributes/Block/Checkout/AttributeMerger.php
@@ -104,7 +104,7 @@ class AttributeMerger extends CheckoutAttributesMerger
$providerName = $result['provider'];
- if ($attributeConfig['formElement'] === 'select') {
+ if (in_array($attributeConfig['formElement'], ['select', 'multiselect'])) {
$result['deps'] = [$providerName];
$result['exports']['options'] =
'index = ' . $providerName . ':customAttributes.' . $attributeCode;
diff --git a/vendor/magento/module-customer-custom-attributes/Model/CustomerAddressCustomAttributesProcessor.php b/vendor/magento/module-customer-custom-attributes/Model/CustomerAddressCustomAttributesProcessor.php
new file mode 100644
index 00000000000..ad03fa75f0b
--- /dev/null
+++ b/vendor/magento/module-customer-custom-attributes/Model/CustomerAddressCustomAttributesProcessor.php
@@ -0,0 +1,38 @@
+getCustomAttributes();
+ if ($customerCustomAttributes) {
+ foreach ($customerCustomAttributes as $customAttribute) {
+ $customAttributeValue = $customAttribute->getValue();
+ if ($customAttributeValue && is_array($customAttributeValue)) {
+ if ($customAttributeValue['value'] !== null) {
+ $customAttribute->setValue($customAttributeValue['value']);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessCustomerBillingAddressCustomAttributes.php b/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessCustomerBillingAddressCustomAttributes.php
new file mode 100644
index 00000000000..49e73db5996
--- /dev/null
+++ b/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessCustomerBillingAddressCustomAttributes.php
@@ -0,0 +1,54 @@
+customerAddressCustomAttributesProcessor = $customerAddressCustomAttributesProcessor;
+ }
+
+ /**
+ * Process billing custom attribute before save for registered customer
+ *
+ * @param PaymentInformationManagementInterface $subject
+ * @param string $cartId
+ * @param PaymentInterface $paymentMethod
+ * @param AddressInterface|null $billingAddress
+ * @return void
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function beforeSavePaymentInformation(
+ PaymentInformationManagementInterface $subject,
+ string $cartId,
+ PaymentInterface $paymentMethod,
+ AddressInterface $billingAddress = null
+ ): void {
+ if ($billingAddress) {
+ $this->customerAddressCustomAttributesProcessor->execute($billingAddress);
+ }
+ }
+}
diff --git a/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessCustomerShippingAddressCustomAttributes.php b/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessCustomerShippingAddressCustomAttributes.php
new file mode 100644
index 00000000000..6b7e6f188d3
--- /dev/null
+++ b/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessCustomerShippingAddressCustomAttributes.php
@@ -0,0 +1,52 @@
+customerAddressCustomAttributesProcessor = $customerAddressCustomAttributesProcessor;
+ }
+
+ /**
+ * Process shipping custom attribute before save for registered customer
+ *
+ * @param ShippingInformationManagementInterface $subject
+ * @param string $cartId
+ * @param ShippingInformationInterface $addressInformation
+ * @return void
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function beforeSaveAddressInformation(
+ ShippingInformationManagementInterface $subject,
+ string $cartId,
+ ShippingInformationInterface $addressInformation
+ ): void {
+ $shippingAddress = $addressInformation->getShippingAddress();
+ if ($shippingAddress) {
+ $this->customerAddressCustomAttributesProcessor->execute($shippingAddress);
+ }
+ }
+}
diff --git a/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessGuestBillingAddressCustomAttributes.php b/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessGuestBillingAddressCustomAttributes.php
new file mode 100644
index 00000000000..0ead39b39fe
--- /dev/null
+++ b/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessGuestBillingAddressCustomAttributes.php
@@ -0,0 +1,56 @@
+customerAddressCustomAttributesProcessor = $customerAddressCustomAttributesProcessor;
+ }
+
+ /**
+ * Process billing custom attribute before save for guest
+ *
+ * @param GuestPaymentInformationManagementInterface $subject
+ * @param string $cartId
+ * @param string $email
+ * @param PaymentInterface $paymentMethod
+ * @param AddressInterface|null $billingAddress
+ * @return void
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function beforeSavePaymentInformation(
+ GuestPaymentInformationManagementInterface $subject,
+ string $cartId,
+ string $email,
+ PaymentInterface $paymentMethod,
+ AddressInterface $billingAddress = null
+ ): void {
+ if ($billingAddress) {
+ $this->customerAddressCustomAttributesProcessor->execute($billingAddress);
+ }
+ }
+}
diff --git a/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessGuestShippingAddressCustomAttributes.php b/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessGuestShippingAddressCustomAttributes.php
new file mode 100644
index 00000000000..6aacf6bbaa3
--- /dev/null
+++ b/vendor/magento/module-customer-custom-attributes/Model/Plugin/ProcessGuestShippingAddressCustomAttributes.php
@@ -0,0 +1,52 @@
+customerAddressCustomAttributesProcessor = $customerAddressCustomAttributesProcessor;
+ }
+
+ /**
+ * Process shipping custom attribute before save for guest
+ *
+ * @param GuestShippingInformationManagementInterface $subject
+ * @param string $cartId
+ * @param ShippingInformationInterface $addressInformation
+ * @return void
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function beforeSaveAddressInformation(
+ GuestShippingInformationManagementInterface $subject,
+ string $cartId,
+ ShippingInformationInterface $addressInformation
+ ): void {
+ $shippingAddress = $addressInformation->getShippingAddress();
+ if ($shippingAddress) {
+ $this->customerAddressCustomAttributesProcessor->execute($shippingAddress);
+ }
+ }
+}
diff --git a/vendor/magento/module-customer-custom-attributes/Plugin/ProcessCustomerCustomBooleanAttributeOptions.php b/vendor/magento/module-customer-custom-attributes/Plugin/ProcessCustomerCustomBooleanAttributeOptions.php
new file mode 100644
index 00000000000..172c041dedf
--- /dev/null
+++ b/vendor/magento/module-customer-custom-attributes/Plugin/ProcessCustomerCustomBooleanAttributeOptions.php
@@ -0,0 +1,58 @@
+isCustomAttributeBoolean($attribute) &&
+ !empty($meta['options'])) {
+ foreach ($meta['options'] as $key => $option) {
+ $meta['options'][$key]['value'] = (bool) $option['value'];
+ }
+ }
+ return $meta;
+ }
+
+ /**
+ * Check if custom attribute is boolean
+ *
+ * @param AttributeInterface $attribute
+ * @return bool
+ */
+ private function isCustomAttributeBoolean(AttributeInterface $attribute): bool
+ {
+ $isBoolean = (int) $attribute->getIsUserDefined() &&
+ $attribute->getFrontendInput() == 'boolean';
+ return (bool) $isBoolean;
+ }
+}
diff --git a/vendor/magento/module-customer-custom-attributes/etc/di.xml b/vendor/magento/module-customer-custom-attributes/etc/di.xml
index 5af83f2fdbe..8d8cfb2542e 100644
--- a/vendor/magento/module-customer-custom-attributes/etc/di.xml
+++ b/vendor/magento/module-customer-custom-attributes/etc/di.xml
@@ -84,4 +84,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/magento/module-customer-custom-attributes/etc/frontend/di.xml b/vendor/magento/module-customer-custom-attributes/etc/frontend/di.xml
index a3e2e5b6684..25700fa429d 100644
--- a/vendor/magento/module-customer-custom-attributes/etc/frontend/di.xml
+++ b/vendor/magento/module-customer-custom-attributes/etc/frontend/di.xml
@@ -13,4 +13,7 @@
+
+
+