Skip to content

Commit 93e1abc

Browse files
[Magento Community Engineering] Community Contributions - 2.3-develop
- merged latest code from mainline branch
2 parents 0ea4bc1 + 777b0b0 commit 93e1abc

File tree

55 files changed

+1509
-379
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1509
-379
lines changed

app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/di.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,9 @@
3131
</argument>
3232
</arguments>
3333
</virtualType>
34+
<virtualType name="AuthorizenetAcceptjsAuthorizeCommand" type="Magento\Payment\Gateway\Command\GatewayCommand">
35+
<arguments>
36+
<argument name="validator" xsi:type="object">AuthorizenetAcceptjsTransactionValidator</argument>
37+
</arguments>
38+
</virtualType>
3439
</config>

app/code/Magento/AuthorizenetAcceptjs/etc/di.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
<arguments>
135135
<argument name="requestBuilder" xsi:type="object">AuthorizenetAcceptjsRefundRequest</argument>
136136
<argument name="handler" xsi:type="object">AuthorizenetAcceptjsRefundSettledHandler</argument>
137+
<argument name="validator" xsi:type="object">AuthorizenetAcceptjsTransactionValidator</argument>
137138
</arguments>
138139
</virtualType>
139140
<virtualType name="AuthorizenetAcceptjsCaptureCommand" type="Magento\AuthorizenetAcceptjs\Gateway\Command\CaptureStrategyCommand">
@@ -145,6 +146,7 @@
145146
<arguments>
146147
<argument name="requestBuilder" xsi:type="object">AuthorizenetAcceptjsCaptureRequest</argument>
147148
<argument name="handler" xsi:type="object">AuthorizenetAcceptjsCaptureTransactionHandler</argument>
149+
<argument name="validator" xsi:type="object">AuthorizenetAcceptjsTransactionValidator</argument>
148150
</arguments>
149151
</virtualType>
150152
<virtualType name="AuthorizenetAcceptjsVoidCommand" type="Magento\Payment\Gateway\Command\GatewayCommand">

app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/template/payment/authorizenet-acceptjs.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<button class="action primary checkout"
3636
type="submit"
3737
click="beforePlaceOrder"
38+
css="disabled: !isPlaceOrderActionAllowed()"
3839
attr="title: $t('Place Order')"
3940
>
4041
<span translate="'Place Order'"></span>

app/code/Magento/AuthorizenetCardinal/Gateway/Request/Authorize3DSecureBuilder.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use Magento\AuthorizenetAcceptjs\Gateway\SubjectReader;
1212
use Magento\AuthorizenetCardinal\Model\Config;
13-
use Magento\CardinalCommerce\Model\Response\JwtParser;
13+
use Magento\CardinalCommerce\Model\Response\JwtParserInterface;
1414
use Magento\Payment\Gateway\Request\BuilderInterface;
1515
use Magento\Sales\Model\Order\Payment;
1616

@@ -30,19 +30,19 @@ class Authorize3DSecureBuilder implements BuilderInterface
3030
private $config;
3131

3232
/**
33-
* @var JwtParser
33+
* @var JwtParserInterface
3434
*/
3535
private $jwtParser;
3636

3737
/**
3838
* @param SubjectReader $subjectReader
3939
* @param Config $config
40-
* @param JwtParser $jwtParser
40+
* @param JwtParserInterface $jwtParser
4141
*/
4242
public function __construct(
4343
SubjectReader $subjectReader,
4444
Config $config,
45-
JwtParser $jwtParser
45+
JwtParserInterface $jwtParser
4646
) {
4747
$this->subjectReader = $subjectReader;
4848
$this->config = $config;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\AuthorizenetCardinal\Gateway\Validator;
10+
11+
use Magento\AuthorizenetAcceptjs\Gateway\SubjectReader;
12+
use Magento\AuthorizenetCardinal\Model\Config;
13+
use Magento\Payment\Gateway\Validator\AbstractValidator;
14+
use Magento\Payment\Gateway\Validator\ResultInterface;
15+
use Magento\Payment\Gateway\Validator\ResultInterfaceFactory;
16+
17+
/**
18+
* Validates cardholder authentication verification response code.
19+
*/
20+
class CavvResponseValidator extends AbstractValidator
21+
{
22+
/**
23+
* The result code that authorize.net returns if CAVV passed validation.
24+
*/
25+
private const RESULT_CODE_SUCCESS = '2';
26+
27+
/**
28+
* @var SubjectReader
29+
*/
30+
private $subjectReader;
31+
32+
/**
33+
* @var ResultInterfaceFactory
34+
*/
35+
private $resultFactory;
36+
37+
/**
38+
* @var Config
39+
*/
40+
private $config;
41+
42+
/**
43+
* @param ResultInterfaceFactory $resultFactory
44+
* @param SubjectReader $subjectReader
45+
* @param Config $config
46+
*/
47+
public function __construct(
48+
ResultInterfaceFactory $resultFactory,
49+
SubjectReader $subjectReader,
50+
Config $config
51+
) {
52+
parent::__construct($resultFactory);
53+
54+
$this->resultFactory = $resultFactory;
55+
$this->subjectReader = $subjectReader;
56+
$this->config = $config;
57+
}
58+
59+
/**
60+
* @inheritdoc
61+
*/
62+
public function validate(array $validationSubject): ResultInterface
63+
{
64+
if ($this->config->isActive() === false) {
65+
return $this->createResult(true);
66+
}
67+
68+
$response = $this->subjectReader->readResponse($validationSubject);
69+
$transactionResponse = $response['transactionResponse'];
70+
71+
$cavvResultCode = $transactionResponse['cavvResultCode'] ?? '';
72+
$isValid = $cavvResultCode === self::RESULT_CODE_SUCCESS;
73+
$errorCodes = [];
74+
$errorMessages = [];
75+
76+
if (!$isValid) {
77+
$errorCodes[] = $transactionResponse['cavvResultCode'];
78+
$errorMessages[] = 'CAVV failed validation';
79+
}
80+
81+
return $this->createResult($isValid, $errorMessages, $errorCodes);
82+
}
83+
}

app/code/Magento/AuthorizenetCardinal/etc/di.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,20 @@
1313
</argument>
1414
</arguments>
1515
</virtualType>
16+
<virtualType name="Magento\AuthorizenetCardinal\Gateway\Validator\VirtualTransactionValidator" type="Magento\Payment\Gateway\Validator\ValidatorComposite">
17+
<arguments>
18+
<argument name="chainBreakingValidators" xsi:type="array">
19+
<item name="general" xsi:type="boolean">true</item>
20+
</argument>
21+
<argument name="validators" xsi:type="array">
22+
<item name="general" xsi:type="string">AuthorizenetAcceptjsTransactionValidator</item>
23+
<item name="cavv_response" xsi:type="string">Magento\AuthorizenetCardinal\Gateway\Validator\CavvResponseValidator</item>
24+
</argument>
25+
</arguments>
26+
</virtualType>
27+
<virtualType name="AuthorizenetAcceptjsAuthorizeCommand">
28+
<arguments>
29+
<argument name="validator" xsi:type="object">Magento\AuthorizenetCardinal\Gateway\Validator\VirtualTransactionValidator</argument>
30+
</arguments>
31+
</virtualType>
1632
</config>

app/code/Magento/AuthorizenetCardinal/view/frontend/web/js/authorizenet-accept-mixin.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ define([
5656
},
5757

5858
/**
59+
* Adds cardinal response JWT to payment additional data.
60+
*
5961
* @returns {Object}
6062
*/
6163
getData: function () {

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
*

app/code/Magento/CardinalCommerce/Model/Response/JwtParser.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
use Magento\Payment\Model\Method\Logger as PaymentLogger;
1515

1616
/**
17-
* Parse content of CardinalCommerce response JWT.
17+
* Parses content of CardinalCommerce response JWT.
1818
*/
19-
class JwtParser
19+
class JwtParser implements JwtParserInterface
2020
{
2121
/**
2222
* @var JwtManagement

0 commit comments

Comments
 (0)