diff --git a/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php b/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php
index 646137310cb51..1b2c744419891 100644
--- a/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php
+++ b/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php
@@ -5,6 +5,7 @@
*/
namespace Magento\Checkout\Block\Checkout;
+use Magento\Checkout\Helper\Data;
use Magento\Framework\App\ObjectManager;
class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcessorInterface
@@ -29,6 +30,11 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso
*/
private $options;
+ /**
+ * @var Data
+ */
+ private $checkoutDataHelper;
+
/**
* @param \Magento\Customer\Model\AttributeMetadataDataProvider $attributeMetadataDataProvider
* @param \Magento\Ui\Component\Form\AttributeMapper $attributeMapper
@@ -133,23 +139,12 @@ public function process($jsLayout)
if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children']
)) {
- if (!isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
- ['payment']['children']['payments-list']['children'])) {
- $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
- ['payment']['children']['payments-list']['children'] = [];
- }
-
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
- ['payment']['children']['payments-list']['children'] =
- array_merge_recursive(
- $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
- ['payment']['children']['payments-list']['children'],
- $this->processPaymentConfiguration(
- $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
- ['payment']['children']['renders']['children'],
- $elements
- )
- );
+ ['payment']['children'] = $this->processPaymentChildrenComponents(
+ $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
+ ['payment']['children'],
+ $elements
+ );
}
if (isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
@@ -168,6 +163,44 @@ public function process($jsLayout)
return $jsLayout;
}
+ /**
+ * Appends billing address form component to payment layout
+ * @param array $paymentLayout
+ * @param array $elements
+ * @return array
+ */
+ private function processPaymentChildrenComponents(array $paymentLayout, array $elements)
+ {
+ if (!isset($paymentLayout['payments-list']['children'])) {
+ $paymentLayout['payments-list']['children'] = [];
+ }
+
+ if (!isset($paymentLayout['afterMethods']['children'])) {
+ $paymentLayout['afterMethods']['children'] = [];
+ }
+
+ // The if billing address should be displayed on Payment method or page
+ if ($this->getCheckoutDataHelper()->isDisplayBillingOnPaymentMethodAvailable()) {
+ $paymentLayout['payments-list']['children'] =
+ array_merge_recursive(
+ $paymentLayout['payments-list']['children'],
+ $this->processPaymentConfiguration(
+ $paymentLayout['renders']['children'],
+ $elements
+ )
+ );
+ } else {
+ $component['billing-address-form'] = $this->getBillingAddressComponent('shared', $elements);
+ $paymentLayout['afterMethods']['children'] =
+ array_merge_recursive(
+ $component,
+ $paymentLayout['afterMethods']['children']
+ );
+ }
+
+ return $paymentLayout;
+ }
+
/**
* Inject billing address component into every payment component
*
@@ -183,75 +216,102 @@ private function processPaymentConfiguration(array &$configuration, array $eleme
if (empty($paymentComponent['isBillingAddressRequired'])) {
continue;
}
- $output[$paymentCode . '-form'] = [
- 'component' => 'Magento_Checkout/js/view/billing-address',
- 'displayArea' => 'billing-address-form-' . $paymentCode,
- 'provider' => 'checkoutProvider',
- 'deps' => 'checkoutProvider',
- 'dataScopePrefix' => 'billingAddress' . $paymentCode,
- 'sortOrder' => 1,
- 'children' => [
- 'form-fields' => [
- 'component' => 'uiComponent',
- 'displayArea' => 'additional-fieldsets',
- 'children' => $this->merger->merge(
- $elements,
- 'checkoutProvider',
- 'billingAddress' . $paymentCode,
- [
- 'country_id' => [
- 'sortOrder' => 115,
- ],
- 'region' => [
- 'visible' => false,
- ],
- 'region_id' => [
- 'component' => 'Magento_Ui/js/form/element/region',
- 'config' => [
- 'template' => 'ui/form/field',
- 'elementTmpl' => 'ui/form/element/select',
- 'customEntry' => 'billingAddress' . $paymentCode . '.region',
- ],
- 'validation' => [
- 'required-entry' => true,
- ],
- 'filterBy' => [
- 'target' => '${ $.provider }:${ $.parentScope }.country_id',
- 'field' => 'country_id',
- ],
- ],
- 'postcode' => [
- 'component' => 'Magento_Ui/js/form/element/post-code',
- 'validation' => [
- 'required-entry' => true,
- ],
- ],
- 'company' => [
- 'validation' => [
- 'min_text_length' => 0,
- ],
- ],
- 'fax' => [
- 'validation' => [
- 'min_text_length' => 0,
- ],
- ],
- 'telephone' => [
- 'config' => [
- 'tooltip' => [
- 'description' => __('For delivery questions.'),
- ],
- ],
- ],
- ]
- ),
- ],
- ],
- ];
+ $output[$paymentCode . '-form'] = $this->getBillingAddressComponent($paymentCode, $elements);
}
unset($configuration[$paymentGroup]['methods']);
}
return $output;
}
+
+ /**
+ * Gets billing address component details
+ *
+ * @param string $paymentCode
+ * @param array $elements
+ * @return array
+ */
+ private function getBillingAddressComponent($paymentCode, $elements)
+ {
+ return [
+ 'component' => 'Magento_Checkout/js/view/billing-address',
+ 'displayArea' => 'billing-address-form-' . $paymentCode,
+ 'provider' => 'checkoutProvider',
+ 'deps' => 'checkoutProvider',
+ 'dataScopePrefix' => 'billingAddress' . $paymentCode,
+ 'sortOrder' => 1,
+ 'children' => [
+ 'form-fields' => [
+ 'component' => 'uiComponent',
+ 'displayArea' => 'additional-fieldsets',
+ 'children' => $this->merger->merge(
+ $elements,
+ 'checkoutProvider',
+ 'billingAddress' . $paymentCode,
+ [
+ 'country_id' => [
+ 'sortOrder' => 115,
+ ],
+ 'region' => [
+ 'visible' => false,
+ ],
+ 'region_id' => [
+ 'component' => 'Magento_Ui/js/form/element/region',
+ 'config' => [
+ 'template' => 'ui/form/field',
+ 'elementTmpl' => 'ui/form/element/select',
+ 'customEntry' => 'billingAddress' . $paymentCode . '.region',
+ ],
+ 'validation' => [
+ 'required-entry' => true,
+ ],
+ 'filterBy' => [
+ 'target' => '${ $.provider }:${ $.parentScope }.country_id',
+ 'field' => 'country_id',
+ ],
+ ],
+ 'postcode' => [
+ 'component' => 'Magento_Ui/js/form/element/post-code',
+ 'validation' => [
+ 'required-entry' => true,
+ ],
+ ],
+ 'company' => [
+ 'validation' => [
+ 'min_text_length' => 0,
+ ],
+ ],
+ 'fax' => [
+ 'validation' => [
+ 'min_text_length' => 0,
+ ],
+ ],
+ 'telephone' => [
+ 'config' => [
+ 'tooltip' => [
+ 'description' => __('For delivery questions.'),
+ ],
+ ],
+ ],
+ ]
+ ),
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Get checkout data helper instance
+ *
+ * @return Data
+ * @deprecated
+ */
+ private function getCheckoutDataHelper()
+ {
+ if (!$this->checkoutDataHelper) {
+ $this->checkoutDataHelper = ObjectManager::getInstance()->get(Data::class);
+ }
+
+ return $this->checkoutDataHelper;
+ }
}
diff --git a/app/code/Magento/Checkout/Helper/Data.php b/app/code/Magento/Checkout/Helper/Data.php
index 2073ffe87d4d6..b54d3187949e4 100644
--- a/app/code/Magento/Checkout/Helper/Data.php
+++ b/app/code/Magento/Checkout/Helper/Data.php
@@ -8,6 +8,7 @@
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Quote\Model\Quote\Item\AbstractItem;
use Magento\Store\Model\Store;
+use Magento\Store\Model\ScopeInterface;
/**
* Checkout default helper
@@ -400,4 +401,17 @@ public function isCustomerMustBeLogged()
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
}
+
+ /**
+ * Checks if display billing address on payment method is available, otherwise
+ * billing address should be display on payment page
+ * @return bool
+ */
+ public function isDisplayBillingOnPaymentMethodAvailable()
+ {
+ return (bool) !$this->scopeConfig->getValue(
+ 'checkout/options/display_billing_address_on',
+ ScopeInterface::SCOPE_STORE
+ );
+ }
}
diff --git a/app/code/Magento/Checkout/Model/Adminhtml/BillingAddressDisplayOptions.php b/app/code/Magento/Checkout/Model/Adminhtml/BillingAddressDisplayOptions.php
new file mode 100644
index 0000000000000..831d4b41ec904
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/Adminhtml/BillingAddressDisplayOptions.php
@@ -0,0 +1,39 @@
+ 'Payment Method', 'value' => 0],
+ * ['label' => 'Payment Page', 'value' => 1]
+ * ]
+ */
+ public function toOptionArray()
+ {
+ return [
+ [
+ 'label' => __('Payment Method'),
+ 'value' => 0
+ ],
+ [
+ 'label' => __('Payment Page'),
+ 'value' => 1
+ ]
+ ];
+ }
+}
diff --git a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php
index 923e54aac9378..0544f3aae3912 100644
--- a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php
+++ b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php
@@ -296,6 +296,7 @@ public function getConfig()
$output['originCountryCode'] = $this->getOriginCountryCode();
$output['paymentMethods'] = $this->getPaymentMethods();
$output['autocomplete'] = $this->isAutocompleteEnabled();
+ $output['displayBillingOnPaymentMethod'] = $this->checkoutHelper->isDisplayBillingOnPaymentMethodAvailable();
return $output;
}
diff --git a/app/code/Magento/Checkout/Test/Unit/Block/Checkout/LayoutProcessorTest.php b/app/code/Magento/Checkout/Test/Unit/Block/Checkout/LayoutProcessorTest.php
new file mode 100644
index 0000000000000..1351213f990b5
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Unit/Block/Checkout/LayoutProcessorTest.php
@@ -0,0 +1,276 @@
+attributeDataProvider = $this->getMockBuilder(AttributeMetadataDataProvider::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['loadAttributesCollection'])
+ ->getMock();
+
+ $this->attributeMapper = $this->getMockBuilder(AttributeMapper::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['map'])
+ ->getMock();
+
+ $this->attributeMerger = $this->getMockBuilder(AttributeMerger::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['merge'])
+ ->getMock();
+
+ $this->dataHelper = $this->getMockBuilder(Data::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['isDisplayBillingOnPaymentMethodAvailable'])
+ ->getMock();
+
+ $options = $this->getMockBuilder(Options::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->layoutProcessor = new LayoutProcessor(
+ $this->attributeDataProvider,
+ $this->attributeMapper,
+ $this->attributeMerger
+ );
+
+ $objectManager->setBackwardCompatibleProperty($this->layoutProcessor, 'checkoutDataHelper', $this->dataHelper);
+ $objectManager->setBackwardCompatibleProperty($this->layoutProcessor, 'options', $options);
+ }
+
+ /**
+ * @covers \Magento\Checkout\Block\Checkout\LayoutProcessor::process
+ */
+ public function testProcess()
+ {
+ $jsLayout = $this->getLayoutData();
+
+ $this->attributeDataProvider->expects(static::once())
+ ->method('loadAttributesCollection')
+ ->willReturn([]);
+
+ $this->dataHelper->expects(static::once())
+ ->method('isDisplayBillingOnPaymentMethodAvailable')
+ ->willReturn(true);
+
+ $this->attributeMerger->expects(static::exactly(2))
+ ->method('merge')
+ ->willReturnMap([
+ ['payment1_1' => $this->getBillingComponent('payment1_1')],
+ ['payment2_1' => $this->getBillingComponent('payment2_1')],
+ ]);
+
+ $actual = $this->layoutProcessor->process($jsLayout);
+
+ static::assertArrayHasKey(
+ 'payment1_1-form',
+ $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']
+ ['payment']['children']['payments-list']['children']
+ );
+ static::assertArrayHasKey(
+ 'payment2_1-form',
+ $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']
+ ['payment']['children']['payments-list']['children']
+ );
+ static::assertArrayNotHasKey(
+ 'payment2_2-form',
+ $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']
+ ['payment']['children']['payments-list']['children']
+ );
+ static::assertArrayHasKey(
+ 'afterMethods',
+ $actual['components']['checkout']['children']['steps']['children']['billing-step']
+ ['children']['payment']['children']
+ );
+ static::assertEmpty(
+ $actual['components']['checkout']['children']['steps']['children']['billing-step']
+ ['children']['payment']['children']['afterMethods']['children']
+ );
+ }
+
+ /**
+ * @covers \Magento\Checkout\Block\Checkout\LayoutProcessor::process
+ */
+ public function testProcessWithBillingAddressOnPaymentPage()
+ {
+ $jsLayout = $this->getLayoutData();
+
+ $this->attributeDataProvider->expects(static::once())
+ ->method('loadAttributesCollection')
+ ->willReturn([]);
+
+ $this->dataHelper->expects(static::once())
+ ->method('isDisplayBillingOnPaymentMethodAvailable')
+ ->willReturn(false);
+
+ $this->attributeMerger->expects(static::once())
+ ->method('merge')
+ ->willReturn($this->getBillingComponent('shared'));
+
+ $actual = $this->layoutProcessor->process($jsLayout);
+
+ static::assertEmpty(
+ $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']
+ ['payment']['children']['payments-list']['children']
+ );
+
+ static::assertNotEmpty(
+ $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']
+ ['payment']['children']['afterMethods']['children']
+ );
+ static::assertArrayHasKey(
+ 'billing-address-form',
+ $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']
+ ['children']['afterMethods']['children']
+ );
+ }
+
+ /**
+ * Get mock layout data for testing
+ * @return array
+ */
+ private function getLayoutData()
+ {
+ return [
+ 'components' => [
+ 'checkout' => [
+ 'children' => [
+ 'steps' => [
+ 'children' => [
+ 'billing-step' => [
+ 'children' => [
+ 'payment' => [
+ 'children' => [
+ 'renders' => [
+ 'children' => [
+ 'payment1' => [
+ 'methods' => [
+ 'payment1_1' => [
+ 'isBillingAddressRequired' => true
+ ]
+ ]
+ ],
+ 'payment2' => [
+ 'methods' => [
+ 'payment2_1' => [
+ 'isBillingAddressRequired' => true
+ ],
+ 'payment2_2' => [
+ 'isBillingAddressRequired' => false
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ];
+ }
+
+ /**
+ * Get mock data for billing component
+ * @param string $paymentCode
+ * @return array
+ */
+ private function getBillingComponent($paymentCode)
+ {
+ return [
+ 'country_id' => [
+ 'sortOrder' => 115,
+ ],
+ 'region' => [
+ 'visible' => false,
+ ],
+ 'region_id' => [
+ 'component' => 'Magento_Ui/js/form/element/region',
+ 'config' => [
+ 'template' => 'ui/form/field',
+ 'elementTmpl' => 'ui/form/element/select',
+ 'customEntry' => 'billingAddress' . $paymentCode . '.region',
+ ],
+ 'validation' => [
+ 'required-entry' => true,
+ ],
+ 'filterBy' => [
+ 'target' => '${ $.provider }:${ $.parentScope }.country_id',
+ 'field' => 'country_id',
+ ],
+ ],
+ 'postcode' => [
+ 'component' => 'Magento_Ui/js/form/element/post-code',
+ 'validation' => [
+ 'required-entry' => true,
+ ],
+ ],
+ 'company' => [
+ 'validation' => [
+ 'min_text_length' => 0,
+ ],
+ ],
+ 'fax' => [
+ 'validation' => [
+ 'min_text_length' => 0,
+ ],
+ ],
+ 'telephone' => [
+ 'config' => [
+ 'tooltip' => [
+ 'description' => __('For delivery questions.'),
+ ],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/app/code/Magento/Checkout/etc/adminhtml/system.xml b/app/code/Magento/Checkout/etc/adminhtml/system.xml
index d4567a4382539..b3b3d11b568a3 100644
--- a/app/code/Magento/Checkout/etc/adminhtml/system.xml
+++ b/app/code/Magento/Checkout/etc/adminhtml/system.xml
@@ -21,6 +21,10 @@
Magento\Config\Model\Config\Source\Yesno
+
+
+ \Magento\Checkout\Model\Adminhtml\BillingAddressDisplayOptions
+
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js
index 31d52e5dd1d76..36518a4d615e1 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js
@@ -10,7 +10,6 @@ define(
'mage/storage',
'Magento_Checkout/js/model/error-processor',
'Magento_Customer/js/model/customer',
- 'Magento_Checkout/js/action/get-totals',
'Magento_Checkout/js/model/full-screen-loader',
'Magento_Checkout/js/action/get-payment-information'
],
@@ -20,7 +19,6 @@ define(
storage,
errorProcessor,
customer,
- getTotalsAction,
fullScreenLoader,
getPaymentInformationAction
) {
@@ -55,18 +53,12 @@ define(
serviceUrl, JSON.stringify(payload)
).done(
function () {
- var deferred = null;
+ var deferred = $.Deferred();
- if (!quote.isVirtual()) {
- getTotalsAction([]);
+ getPaymentInformationAction(deferred);
+ $.when(deferred).done(function () {
fullScreenLoader.stopLoader();
- } else {
- deferred = $.Deferred();
- getPaymentInformationAction(deferred);
- $.when(deferred).done(function () {
- fullScreenLoader.stopLoader();
- });
- }
+ });
}
).fail(
function (response) {
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js
index b9cf58b51b133..0c2e7fb01c701 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js
@@ -7,6 +7,7 @@
define(
[
'ko',
+ 'underscore',
'Magento_Ui/js/form/form',
'Magento_Customer/js/model/customer',
'Magento_Customer/js/model/address-list',
@@ -22,6 +23,7 @@ define(
],
function (
ko,
+ _,
Component,
customer,
addressList,
@@ -39,9 +41,13 @@ define(
var lastSelectedBillingAddress = null,
newAddressOption = {
+ /**
+ * Get new address label
+ * @returns {String}
+ */
getAddressInline: function () {
- return $t('New Address');
- },
+ return $t('New Address');
+ },
customerAddressId: null
},
countryData = customerData.get('directory-data'),
@@ -121,9 +127,8 @@ define(
useShippingAddress: function () {
if (this.isAddressSameAsShipping()) {
selectBillingAddress(quote.shippingAddress());
- if (window.checkoutConfig.reloadOnBillingAddress) {
- setBillingAddressAction(globalMessageList);
- }
+
+ this.updateAddresses();
this.isAddressDetailsVisible(true);
} else {
lastSelectedBillingAddress = quote.billingAddress();
@@ -142,15 +147,13 @@ define(
if (this.selectedAddress() && this.selectedAddress() != newAddressOption) {
selectBillingAddress(this.selectedAddress());
checkoutData.setSelectedBillingAddress(this.selectedAddress().getKey());
- if (window.checkoutConfig.reloadOnBillingAddress) {
- setBillingAddressAction(globalMessageList);
- }
} else {
this.source.set('params.invalid', false);
this.source.trigger(this.dataScopePrefix + '.data.validate');
+
if (this.source.get(this.dataScopePrefix + '.custom_attributes')) {
this.source.trigger(this.dataScopePrefix + '.custom_attributes.data.validate');
- };
+ }
if (!this.source.get('params.invalid')) {
var addressData = this.source.get(this.dataScopePrefix),
@@ -159,19 +162,16 @@ define(
if (customer.isLoggedIn() && !this.customerHasAddresses) {
this.saveInAddressBook(1);
}
- addressData.save_in_address_book = this.saveInAddressBook() ? 1 : 0;
+ addressData['save_in_address_book'] = this.saveInAddressBook() ? 1 : 0;
newBillingAddress = createBillingAddress(addressData);
// New address must be selected as a billing address
selectBillingAddress(newBillingAddress);
checkoutData.setSelectedBillingAddress(newBillingAddress.getKey());
checkoutData.setNewCustomerBillingAddress(addressData);
-
- if (window.checkoutConfig.reloadOnBillingAddress) {
- setBillingAddressAction(globalMessageList);
- }
}
}
+ this.updateAddresses();
},
/**
@@ -222,6 +222,26 @@ define(
*/
getCountryName: function (countryId) {
return countryData()[countryId] != undefined ? countryData()[countryId].name : '';
+ },
+
+ /**
+ * Trigger action to update shipping and billing addresses
+ */
+ updateAddresses: function () {
+ if (window.checkoutConfig.reloadOnBillingAddress ||
+ !window.checkoutConfig.displayBillingOnPaymentMethod
+ ) {
+ setBillingAddressAction(globalMessageList);
+ }
+ },
+
+ /**
+ * Get code
+ * @param {Object} parent
+ * @returns {String}
+ */
+ getCode: function (parent) {
+ return _.isFunction(parent.getCode) ? parent.getCode() : 'shared';
}
});
}
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html
index 377208aa1b8ee..23c02caa70b1a 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html
@@ -4,23 +4,29 @@
* See COPYING.txt for license details.
*/
-->
-
-
-
-
+
-
-
diff --git a/app/code/Magento/Vault/Model/Method/Vault.php b/app/code/Magento/Vault/Model/Method/Vault.php
index ce85936607192..41a2d6b0e26ef 100644
--- a/app/code/Magento/Vault/Model/Method/Vault.php
+++ b/app/code/Magento/Vault/Model/Method/Vault.php
@@ -457,13 +457,13 @@ public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount)
private function attachTokenExtensionAttribute(OrderPaymentInterface $orderPayment)
{
$additionalInformation = $orderPayment->getAdditionalInformation();
- if (empty($additionalInformation[PaymentTokenInterface::CUSTOMER_ID]) ||
- empty($additionalInformation[PaymentTokenInterface::PUBLIC_HASH])
- ) {
- throw new \LogicException('Customer id and public hash should be defined');
+ if (empty($additionalInformation[PaymentTokenInterface::PUBLIC_HASH])) {
+ throw new \LogicException('Public hash should be defined');
}
- $customerId = $additionalInformation[PaymentTokenInterface::CUSTOMER_ID];
+ $customerId = isset($additionalInformation[PaymentTokenInterface::CUSTOMER_ID]) ?
+ $additionalInformation[PaymentTokenInterface::CUSTOMER_ID] : null;
+
$publicHash = $additionalInformation[PaymentTokenInterface::PUBLIC_HASH];
$paymentToken = $this->tokenManagement->getByPublicHash($publicHash, $customerId);
diff --git a/app/code/Magento/Vault/Model/Ui/TokensConfigProvider.php b/app/code/Magento/Vault/Model/Ui/TokensConfigProvider.php
index 6a86ed694642c..060e16d1c3f1a 100644
--- a/app/code/Magento/Vault/Model/Ui/TokensConfigProvider.php
+++ b/app/code/Magento/Vault/Model/Ui/TokensConfigProvider.php
@@ -89,8 +89,10 @@ public function getConfig()
$componentProvider = $providers[$paymentCode];
$component = $componentProvider->getComponentForToken($token);
- $vaultPayments[$paymentCode . '_item_' . $i] = [
- 'config' => $component->getConfig(),
+ $config = $component->getConfig();
+ $vaultPaymentCode = !empty($config['code']) ? $config['code'] : $paymentCode;
+ $vaultPayments[$vaultPaymentCode . '_' . $i] = [
+ 'config' => $config,
'component' => $component->getName()
];
}
diff --git a/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php b/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php
index e5c8391102524..8bded498dab76 100644
--- a/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php
+++ b/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php
@@ -52,7 +52,7 @@ public function testAuthorizeNotOrderPayment()
/**
* @param array $additionalInfo
* @expectedException \LogicException
- * @expectedExceptionMessage Customer id and public hash should be defined
+ * @expectedExceptionMessage Public hash should be defined
* @dataProvider additionalInfoDataProvider
*/
public function testAuthorizeNoTokenMetadata(array $additionalInfo)
@@ -79,7 +79,7 @@ public function additionalInfoDataProvider()
return [
['additionalInfo' => []],
['additionalInfo' => ['customer_id' => 1]],
- ['additionalInfo' => ['public_hash' => 'df768aak12uf']],
+ ['additionalInfo' => ['public_hash' => null]],
];
}
diff --git a/app/code/Magento/Vault/Test/Unit/Model/Ui/TokensConfigProviderTest.php b/app/code/Magento/Vault/Test/Unit/Model/Ui/TokensConfigProviderTest.php
index 3e4b8b145af67..d5ac3cac9563d 100644
--- a/app/code/Magento/Vault/Test/Unit/Model/Ui/TokensConfigProviderTest.php
+++ b/app/code/Magento/Vault/Test/Unit/Model/Ui/TokensConfigProviderTest.php
@@ -95,7 +95,7 @@ public function testGetConfig()
$expectedConfig = [
'payment' => [
'vault' => [
- $vaultProviderCode . '_item_' . '0' => [
+ $vaultProviderCode . '_' . '0' => [
'config' => ['token_code' => 'code'],
'component' => 'Vendor_Module/js/vault_component'
]
diff --git a/app/code/Magento/Vault/view/frontend/web/js/view/payment/vault.js b/app/code/Magento/Vault/view/frontend/web/js/view/payment/vault.js
index cba9256f2a563..05d56e305f23e 100644
--- a/app/code/Magento/Vault/view/frontend/web/js/view/payment/vault.js
+++ b/app/code/Magento/Vault/view/frontend/web/js/view/payment/vault.js
@@ -31,7 +31,8 @@ define(
* @return {Boolean}
*/
typeComparatorCallback: function (typeA, typeB) {
- return typeA.indexOf(typeB) === 0;
+ // vault token items have the same name as vault payment without index
+ return typeA.substring(0, typeA.lastIndexOf('_')) === typeB;
}
}
);
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less
index ca69275441643..7731595870f06 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less
@@ -72,7 +72,6 @@
.payment-method-content {
display: none;
-
.lib-css(padding, 0 0 @indent__base @checkout-payment-method-content__padding__xl);
.fieldset {
&:not(:last-child) {
@@ -90,7 +89,7 @@
margin: 0 0 @indent__s;
}
- .payment-method-billing-address {
+ .checkout-billing-address {
margin: 0 0 @indent__base;
.primary {
@@ -106,15 +105,11 @@
.billing-address-details {
.lib-css(line-height, @checkout-billing-address-details__line-height);
.lib-css(padding, @checkout-billing-address-details__padding);
-
- .action-edit-address {
- &:extend(.abs-action-button-as-link all);
- }
}
}
.payment-method-note {
- & + .payment-method-billing-address {
+ & + .checkout-billing-address {
margin-top: @indent__base;
}
}
@@ -161,7 +156,7 @@
.lib-css(padding, 0 @checkout-payment-method-title-mobile__padding @indent__base);
}
- .payment-method-billing-address {
+ .checkout-billing-address {
.action-cancel {
margin-top: @indent__s;
}
@@ -175,12 +170,10 @@
.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
.checkout-payment-method {
- .payment-methods {
- .actions-toolbar {
- .primary {
- float: right;
- margin: 0;
- }
+ .actions-toolbar {
+ .primary {
+ float: right;
+ margin: 0;
}
}
@@ -214,7 +207,7 @@
}
}
- .payment-method-billing-address {
+ .checkout-billing-address {
.action-update {
float: right;
}
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less
index 3c3ee77ed00e0..85b2e96e6ea4a 100644
--- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less
@@ -89,7 +89,7 @@
margin: 0 0 @indent__s;
}
- .payment-method-billing-address {
+ .checkout-billing-address {
margin: 0 0 @indent__base;
.primary {
@@ -105,15 +105,11 @@
.billing-address-details {
.lib-css(line-height, @checkout-billing-address-details__line-height);
.lib-css(padding, @checkout-billing-address-details__padding);
-
- .action-edit-address {
- &:extend(.abs-action-button-as-link all);
- }
}
}
.payment-method-note {
- & + .payment-method-billing-address {
+ & + .checkout-billing-address {
margin-top: @indent__base;
}
}
@@ -160,7 +156,7 @@
.lib-css(padding, 0 @checkout-payment-method-title-mobile__padding @indent__base);
}
- .payment-method-billing-address {
+ .checkout-billing-address {
.action-cancel {
margin-top: @indent__s;
}
@@ -174,12 +170,10 @@
.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
.checkout-payment-method {
- .payment-methods {
- .actions-toolbar {
- .primary {
- float: right;
- margin: 0;
- }
+ .actions-toolbar {
+ .primary {
+ float: right;
+ margin: 0;
}
}
@@ -193,7 +187,7 @@
}
}
- .payment-method-billing-address {
+ .checkout-billing-address {
.action-update {
float: right;
}
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml
index 58612f7dee170..6e214d4c205aa 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml
@@ -19,6 +19,7 @@
- 15.00
braintree_paypal
+ braintree_paypal_vault
Yes
braintree, braintree_paypal, braintree_paypal_use_vault
Processing
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml
index 4b061fb2664b8..00eb9c4802db6 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml
@@ -16,6 +16,7 @@
Flat Rate
Fixed
braintree
+ braintree_cc_vault
credit_card_braintree
visa_braintree
Yes
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml
index 1aaa684db5c66..0f00ff93612b8 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml
@@ -16,6 +16,7 @@
Flat Rate
Fixed
braintree
+ braintree_cc_vault
credit_card_braintree
visa_braintree_3dsecure
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method.php
index 48f1b4a99823d..55351dbe5fd5e 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method.php
@@ -40,7 +40,7 @@ class Method extends Block
*
* @var string
*/
- protected $vaultCheckbox = '#%s_vault_enabler';
+ protected $vaultCheckbox = '#%s_enable_vault';
/**
* PayPal load spinner.
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml
index a71dd812b50f7..bde3837d71fda 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml
@@ -15,6 +15,7 @@
Flat Rate
Fixed
payflowpro
+ payflowpro_cc_vault
credit_card
visa_default
Yes
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php
index a90bd37f33047..17db35df1b44e 100644
--- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php
@@ -92,7 +92,7 @@ public function test(
}
$this->fillShippingMethod($shipping);
if ($key >= 2) { // if this order will be placed via stored credit card
- $this->useSavedCreditCard($payment);
+ $this->useSavedCreditCard($payment['vault']);
} else {
$this->selectPaymentMethod($payment, $payment['creditCardClass'], $payment['creditCard']);
$this->saveCreditCard($payment, $creditCardSave);
@@ -291,7 +291,7 @@ protected function useSavedCreditCard($payment)
{
$useSavedCreditCardStep = ObjectManager::getInstance()->create(
\Magento\Vault\Test\TestStep\UseSavedPaymentMethodStep::class,
- ['payment' => $payment]
+ ['vault' => $payment]
);
$useSavedCreditCardStep->run();
}
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml
index 5a2e2903e2c49..ae303b695277c 100644
--- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml
@@ -35,6 +35,9 @@
-
- visa_braintree
+ -
+
- braintree_cc_vault
+
-
- payflowpro
@@ -42,6 +45,9 @@
-
- amex_default
+ -
+
- payflowpro_cc_vault
+
Yes
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestStep/UseSavedPaymentMethodStep.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestStep/UseSavedPaymentMethodStep.php
index b4b21670d2e0c..1470bde4f77e5 100644
--- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestStep/UseSavedPaymentMethodStep.php
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestStep/UseSavedPaymentMethodStep.php
@@ -22,21 +22,21 @@ class UseSavedPaymentMethodStep implements TestStepInterface
protected $checkoutOnepage;
/**
- * Payment information.
+ * Vault provider.
*
* @var array
*/
- protected $payment;
+ protected $vault;
/**
* @constructor
* @param CheckoutOnepage $checkoutOnepage
- * @param array $payment
+ * @param array $vault
*/
- public function __construct (CheckoutOnepage $checkoutOnepage, array $payment)
+ public function __construct (CheckoutOnepage $checkoutOnepage, array $vault)
{
$this->checkoutOnepage = $checkoutOnepage;
- $this->payment = $payment;
+ $this->vault = $vault;
}
/**
@@ -46,7 +46,6 @@ public function __construct (CheckoutOnepage $checkoutOnepage, array $payment)
*/
public function run()
{
- $this->payment['method'] .= '_item_';
- $this->checkoutOnepage->getPaymentBlock()->selectPaymentMethod($this->payment);
+ $this->checkoutOnepage->getPaymentBlock()->selectPaymentMethod($this->vault);
}
}
diff --git a/dev/tests/integration/testsuite/Magento/Braintree/Model/Ui/TokensConfigProviderTest.php b/dev/tests/integration/testsuite/Magento/Braintree/Model/Ui/TokensConfigProviderTest.php
index b8550ae205429..440f7674f1227 100644
--- a/dev/tests/integration/testsuite/Magento/Braintree/Model/Ui/TokensConfigProviderTest.php
+++ b/dev/tests/integration/testsuite/Magento/Braintree/Model/Ui/TokensConfigProviderTest.php
@@ -72,7 +72,7 @@ public function testGetConfig()
/** @var PaymentTokenManagement $tokenManagement */
$tokenManagement = $this->objectManager->get(PaymentTokenManagement::class);
$paymentToken = $tokenManagement->getByGatewayToken($token, PayPalConfigProvider::PAYPAL_CODE, $customerId);
- $item = PayPalConfigProvider::PAYPAL_CODE . '_item_' . $paymentToken->getEntityId();
+ $item = PayPalConfigProvider::PAYPAL_VAULT_CODE . '_' . $paymentToken->getEntityId();
/** @var Session $session */
$session = $this->objectManager->get(Session::class);