Skip to content

Commit e2a69d9

Browse files
committed
Merge remote-tracking branch 'magento-mpi/MAGETWO-99867' into PR23-20190718
2 parents 3256578 + eb51835 commit e2a69d9

File tree

3 files changed

+73
-59
lines changed

3 files changed

+73
-59
lines changed

app/code/Magento/Braintree/view/frontend/requirejs-config.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
var config = {
77
map: {
88
'*': {
9-
braintreeClient: 'https://js.braintreegateway.com/web/3.44.1/js/client.min.js',
10-
braintreeHostedFields: 'https://js.braintreegateway.com/web/3.44.1/js/hosted-fields.min.js',
11-
braintreePayPal: 'https://js.braintreegateway.com/web/3.44.1/js/paypal-checkout.min.js',
12-
braintree3DSecure: 'https://js.braintreegateway.com/web/3.44.1/js/three-d-secure.min.js',
13-
braintreeDataCollector: 'https://js.braintreegateway.com/web/3.44.1/js/data-collector.min.js'
9+
braintreeClient: 'https://js.braintreegateway.com/web/3.46.0-beta-3ds.8/js/client.min.js',
10+
braintreeHostedFields: 'https://js.braintreegateway.com/web/3.46.0-beta-3ds.8/js/hosted-fields.min.js',
11+
braintreePayPal: 'https://js.braintreegateway.com/web/3.46.0-beta-3ds.8/js/paypal-checkout.min.js',
12+
braintree3DSecure: 'https://js.braintreegateway.com/web/3.46.0-beta-3ds.8/js/three-d-secure.min.js',
13+
braintreeDataCollector: 'https://js.braintreegateway.com/web/3.46.0-beta-3ds.8/js/data-collector.min.js'
1414
}
1515
},
1616
paths: {

app/code/Magento/Braintree/view/frontend/web/js/view/payment/3d-secure.js

Lines changed: 42 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ define([
4141
braintreeAdapter.getApiClient()
4242
.then(function (clientInstance) {
4343
return braintree3DSecure.create({
44+
version: 2, // Will use 3DS 2 whenever possible
4445
client: clientInstance
4546
});
4647
})
@@ -49,6 +50,7 @@ define([
4950
promise.resolve(self.threeDSecureInstance);
5051
})
5152
.catch(function (err) {
53+
fullScreenLoader.stopLoader();
5254
promise.reject(err);
5355
});
5456

@@ -84,30 +86,55 @@ define([
8486
var self = this,
8587
totalAmount = quote.totals()['base_grand_total'],
8688
billingAddress = quote.billingAddress(),
89+
shippingAddress = quote.shippingAddress(),
8790
options = {
8891
amount: totalAmount,
8992
nonce: context.paymentPayload.nonce,
90-
91-
/**
92-
* Adds iframe to page
93-
* @param {Object} err
94-
* @param {Object} iframe
95-
*/
96-
addFrame: function (err, iframe) {
97-
self.createModal($(iframe));
98-
fullScreenLoader.stopLoader();
99-
self.modal.openModal();
93+
billingAddress: {
94+
givenName: billingAddress.firstname,
95+
surname: billingAddress.lastname,
96+
phoneNumber: billingAddress.telephone,
97+
streetAddress: billingAddress.street[0],
98+
extendedAddress: billingAddress.street[1],
99+
locality: billingAddress.city,
100+
region: billingAddress.regionCode,
101+
postalCode: billingAddress.postcode,
102+
countryCodeAlpha2: billingAddress.countryId
100103
},
101104

102105
/**
103-
* Removes iframe from page
106+
* Will be called after receiving ThreeDSecure response, before completing the flow.
107+
*
108+
* @param {Object} data - ThreeDSecure data to consume before continuing
109+
* @param {Function} next - callback to continue flow
104110
*/
105-
removeFrame: function () {
106-
self.modal.closeModal();
111+
onLookupComplete: function (data, next) {
112+
next();
113+
}
114+
};
115+
116+
if (context.paymentPayload.details) {
117+
options.bin = context.paymentPayload.details.bin;
118+
}
119+
120+
if (shippingAddress) {
121+
options.additionalInformation = {
122+
shippingGivenName: shippingAddress.firstname,
123+
shippingSurname: shippingAddress.lastname,
124+
shippingPhone: shippingAddress.telephone,
125+
shippingAddress: {
126+
streetAddress: shippingAddress.street[0],
127+
extendedAddress: shippingAddress.street[1],
128+
locality: shippingAddress.city,
129+
region: shippingAddress.regionCode,
130+
postalCode: shippingAddress.postcode,
131+
countryCodeAlpha2: shippingAddress.countryId
107132
}
108133
};
134+
}
109135

110136
if (!this.isAmountAvailable(totalAmount) || !this.isCountryAvailable(billingAddress.countryId)) {
137+
self.state = $.Deferred();
111138
self.state.resolve();
112139

113140
return self.state.promise();
@@ -118,6 +145,7 @@ define([
118145
.then(function () {
119146
self.threeDSecureInstance.verifyCard(options, function (err, payload) {
120147
if (err) {
148+
fullScreenLoader.stopLoader();
121149
self.state.reject(err.message);
122150

123151
return;
@@ -129,6 +157,7 @@ define([
129157
context.paymentPayload.nonce = payload.nonce;
130158
self.state.resolve();
131159
} else {
160+
fullScreenLoader.stopLoader();
132161
self.state.reject($t('Please try again with another form of payment.'));
133162
}
134163
});
@@ -141,42 +170,6 @@ define([
141170
return self.state.promise();
142171
},
143172

144-
/**
145-
* Creates modal window
146-
*
147-
* @param {Object} $context
148-
* @private
149-
*/
150-
createModal: function ($context) {
151-
var self = this,
152-
options = {
153-
clickableOverlay: false,
154-
buttons: [],
155-
modalCloseBtnHandler: self.cancelFlow.bind(self),
156-
keyEventHandlers: {
157-
escapeKey: self.cancelFlow.bind(self)
158-
}
159-
};
160-
161-
// adjust iframe styles
162-
$context.attr('width', '100%');
163-
self.modal = Modal(options, $context);
164-
},
165-
166-
/**
167-
* Cancels 3D Secure flow
168-
*
169-
* @private
170-
*/
171-
cancelFlow: function () {
172-
var self = this;
173-
174-
self.threeDSecureInstance.cancelVerifyCard(function () {
175-
self.modal.closeModal();
176-
self.state.reject();
177-
});
178-
},
179-
180173
/**
181174
* Checks minimal amount for 3D Secure activation
182175
*

dev/tests/functional/tests/app/Magento/Braintree/Test/Block/Form/Secure3d.php

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,23 @@ class Secure3d extends Form
1919
/**
2020
* 3D Secure iFrame locator.
2121
*
22-
* @var array
22+
* @var string
23+
*/
24+
protected $braintree3dSecure = "//iframe[contains(@id, 'braintreethreedsecurelanding')]";
25+
26+
/**
27+
* AuthWindow locator.
28+
*
29+
* @var string
2330
*/
24-
protected $braintree3dSecure = "//iframe[contains(@src, 'braintreegateway.com/3ds')]";
31+
private $authWindow3dSecure = "//iframe[contains(@id, 'authWindow')]";
32+
33+
/**
34+
* Password field locator.
35+
*
36+
* @var string
37+
*/
38+
private $passwordField = "//*[@name='external.field.password']";
2539

2640
/**
2741
* Submit button button css selector.
@@ -33,12 +47,12 @@ class Secure3d extends Form
3347
/**
3448
* Switch to 3D Secure iFrame.
3549
*
36-
* @param array $locator
50+
* @param string $locator
3751
*/
3852
public function switchToFrame($locator)
3953
{
40-
$this->browser->switchToFrame(new Locator($locator, Locator::SELECTOR_XPATH));
41-
$this->browser->switchToFrame(new Locator($locator, Locator::SELECTOR_XPATH));
54+
$this->browser->switchToFrame(new Locator($locator, Locator::SELECTOR_XPATH));
55+
$this->browser->switchToFrame(new Locator($this->authWindow3dSecure, Locator::SELECTOR_XPATH));
4256
}
4357

4458
/**
@@ -56,13 +70,20 @@ public function submit()
5670
*
5771
* @param FixtureInterface $fixture
5872
* @param SimpleElement|null $element
73+
*
5974
* @return $this|void
6075
*/
6176
public function fill(FixtureInterface $fixture, SimpleElement $element = null)
6277
{
6378
$mapping = $this->dataMapping($fixture->getData());
6479
$this->switchToFrame($this->braintree3dSecure);
6580
$element = $this->browser->find('body');
81+
$this->browser->waitUntil(
82+
function () use ($element) {
83+
$fieldElement = $element->find($this->passwordField, Locator::SELECTOR_XPATH);
84+
return $fieldElement->isVisible() ? true : null;
85+
}
86+
);
6687
$this->_fill([$mapping['secure3d_password']], $element);
6788
$this->submit();
6889
$this->browser->switchToFrame();

0 commit comments

Comments
 (0)