Skip to content

Commit b61fa20

Browse files
John ZolperJohn Zolper
authored andcommitted
Merge branch 'MC-4239' of github.com:magento-borg/magento2ce into MC-4239
2 parents 20b3c6a + 47f9843 commit b61fa20

File tree

16 files changed

+260
-164
lines changed

16 files changed

+260
-164
lines changed

app/code/Magento/Authorizenet/etc/adminhtml/system.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<system>
1010
<section id="payment">
1111
<group id="authorizenet_directpost" translate="label" type="text" sortOrder="34" showInDefault="1" showInWebsite="1" showInStore="1">
12-
<label>Authorize.net Direct Post (Deprecated)</label>
12+
<label>Authorize.Net Direct Post (Deprecated)</label>
1313
<field id="active" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
1414
<label>Enabled</label>
1515
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>

app/code/Magento/Authorizenet/etc/config.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<order_status>processing</order_status>
2020
<payment_action>authorize</payment_action>
2121
<test>1</test>
22-
<title>Credit Card Direct Post (Authorize.net)</title>
22+
<title>Credit Card Direct Post (Authorize.Net)</title>
2323
<trans_key backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
2424
<trans_md5 backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
2525
<allowspecific>0</allowspecific>

app/code/Magento/Authorizenet/etc/payment.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Payment:etc/payment.xsd">
1010
<groups>
1111
<group id="authorizenet">
12-
<label>Authorize.net</label>
12+
<label>Authorize.Net</label>
1313
</group>
1414
</groups>
1515
</payment>

app/code/Magento/Authorizenet/i18n/en_US.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ void,void
4545
"Fraud Filters","Fraud Filters"
4646
"Place Order","Place Order"
4747
"Sorry, but something went wrong. Please contact the seller.","Sorry, but something went wrong. Please contact the seller."
48-
"Authorize.net Direct Post (Deprecated)","Authorize.net Direct Post (Deprecated)"
48+
"Authorize.Net Direct Post (Deprecated)","Authorize.Net Direct Post (Deprecated)"
4949
Enabled,Enabled
5050
"Payment Action","Payment Action"
5151
Title,Title

app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/FetchTransactionInfoCommand.php

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,13 @@
1313
use Magento\Payment\Gateway\Command\CommandPool;
1414
use Magento\Payment\Gateway\Command\CommandPoolInterface;
1515
use Magento\Payment\Gateway\CommandInterface;
16-
use Magento\Sales\Model\Order\Payment;
16+
use Magento\Payment\Gateway\Response\HandlerInterface;
1717

1818
/**
1919
* Syncs the transaction status with authorize.net
2020
*/
2121
class FetchTransactionInfoCommand implements CommandInterface
2222
{
23-
private const REVIEW_PENDING_STATUSES = [
24-
'FDSPendingReview',
25-
'FDSAuthorizedPendingReview'
26-
];
27-
private const REVIEW_DECLINED_STATUSES = [
28-
'void',
29-
'declined'
30-
];
31-
3223
/**
3324
* @var CommandPool
3425
*/
@@ -44,19 +35,27 @@ class FetchTransactionInfoCommand implements CommandInterface
4435
*/
4536
private $config;
4637

38+
/**
39+
* @var HandlerInterface|null
40+
*/
41+
private $handler;
42+
4743
/**
4844
* @param CommandPoolInterface $commandPool
4945
* @param SubjectReader $subjectReader
5046
* @param Config $config
47+
* @param HandlerInterface|null $handler
5148
*/
5249
public function __construct(
5350
CommandPoolInterface $commandPool,
5451
SubjectReader $subjectReader,
55-
Config $config
52+
Config $config,
53+
HandlerInterface $handler = null
5654
) {
5755
$this->commandPool = $commandPool;
5856
$this->subjectReader = $subjectReader;
5957
$this->config = $config;
58+
$this->handler = $handler;
6059
}
6160

6261
/**
@@ -66,22 +65,13 @@ public function execute(array $commandSubject): array
6665
{
6766
$paymentDO = $this->subjectReader->readPayment($commandSubject);
6867
$order = $paymentDO->getOrder();
69-
$payment = $paymentDO->getPayment();
70-
71-
if (!$payment instanceof Payment) {
72-
return [];
73-
}
7468

7569
$command = $this->commandPool->get('get_transaction_details');
7670
$result = $command->execute($commandSubject);
7771
$response = $result->get();
78-
$status = $response['transaction']['transactionStatus'];
7972

80-
// This data is only used when updating the payment on the order
81-
if (!in_array($status, self::REVIEW_PENDING_STATUSES)) {
82-
$denied = in_array($status, self::REVIEW_DECLINED_STATUSES);
83-
$payment->setData('is_transaction_denied', $denied);
84-
$payment->setData('is_transaction_approved', !$denied);
73+
if ($this->handler) {
74+
$this->handler->handle($commandSubject, $response);
8575
}
8676

8777
$additionalInformationKeys = $this->config->getTransactionInfoSyncKeys($order->getStoreId());
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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\AuthorizenetAcceptjs\Gateway\Response;
10+
11+
use Magento\AuthorizenetAcceptjs\Gateway\SubjectReader;
12+
use Magento\Payment\Gateway\Response\HandlerInterface;
13+
use Magento\Sales\Model\Order\Payment;
14+
15+
/**
16+
* Processes payment information from a void transaction response
17+
*/
18+
class PaymentReviewStatusHandler implements HandlerInterface
19+
{
20+
private const REVIEW_PENDING_STATUSES = [
21+
'FDSPendingReview',
22+
'FDSAuthorizedPendingReview'
23+
];
24+
private const REVIEW_DECLINED_STATUSES = [
25+
'void',
26+
'declined'
27+
];
28+
29+
/**
30+
* @var SubjectReader
31+
*/
32+
private $subjectReader;
33+
34+
/**
35+
* @param SubjectReader $subjectReader
36+
*/
37+
public function __construct(SubjectReader $subjectReader)
38+
{
39+
$this->subjectReader = $subjectReader;
40+
}
41+
42+
/**
43+
* @inheritdoc
44+
*/
45+
public function handle(array $handlingSubject, array $response): void
46+
{
47+
$paymentDO = $this->subjectReader->readPayment($handlingSubject);
48+
$payment = $paymentDO->getPayment();
49+
50+
if ($payment instanceof Payment) {
51+
$paymentDO = $this->subjectReader->readPayment($handlingSubject);
52+
$payment = $paymentDO->getPayment();
53+
54+
$status = $response['transaction']['transactionStatus'];
55+
// This data is only used when updating the order payment via Get Payment Update
56+
if (!in_array($status, self::REVIEW_PENDING_STATUSES)) {
57+
$denied = in_array($status, self::REVIEW_DECLINED_STATUSES);
58+
$payment->setData('is_transaction_denied', $denied);
59+
$payment->setData('is_transaction_approved', !$denied);
60+
}
61+
}
62+
}
63+
}

app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/TransactionResponseValidator.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ public function validate(array $validationSubject): ResultInterface
5959
$errorCodes[] = $message['code'];
6060
$errorMessages[] = $message['description'];
6161
}
62+
} elseif (isset($transactionResponse['errors'])) {
63+
foreach ($transactionResponse['errors'] as $message) {
64+
$errorCodes[] = $message['errorCode'];
65+
$errorMessages[] = $message['errorCode'];
66+
}
6267
}
6368

6469
return $this->createResult(false, $errorMessages, $errorCodes);
@@ -77,6 +82,7 @@ private function isResponseCodeAnError(array $transactionResponse): bool
7782
{
7883
$code = $transactionResponse['messages']['message']['code']
7984
?? $transactionResponse['messages']['message'][0]['code']
85+
?? $transactionResponse['errors'][0]['errorCode']
8086
?? null;
8187

8288
return in_array($transactionResponse['responseCode'], [self::RESPONSE_CODE_APPROVED, self::RESPONSE_CODE_HELD])

app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/FetchTransactionInfoCommandTest.php

Lines changed: 20 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Magento\Payment\Gateway\Command\ResultInterface;
1616
use Magento\Payment\Gateway\CommandInterface;
1717
use Magento\Payment\Gateway\Data\PaymentDataObject;
18+
use Magento\Payment\Gateway\Response\HandlerInterface;
1819
use Magento\Sales\Model\Order;
1920
use Magento\Sales\Model\Order\Payment;
2021
use PHPUnit\Framework\MockObject\MockObject;
@@ -57,6 +58,11 @@ class FetchTransactionInfoCommandTest extends TestCase
5758
*/
5859
private $configMock;
5960

61+
/**
62+
* @var HandlerInterface
63+
*/
64+
private $handlerMock;
65+
6066
protected function setUp()
6167
{
6268
$this->paymentDOMock = $this->createMock(PaymentDataObject::class);
@@ -72,85 +78,33 @@ protected function setUp()
7278
$this->transactionDetailsCommandMock = $this->createMock(CommandInterface::class);
7379
$this->transactionResultMock = $this->createMock(ResultInterface::class);
7480
$this->commandPoolMock = $this->createMock(CommandPoolInterface::class);
81+
$this->handlerMock = $this->createMock(HandlerInterface::class);
7582
$this->command = new FetchTransactionInfoCommand(
7683
$this->commandPoolMock,
7784
new SubjectReader(),
78-
$this->configMock
85+
$this->configMock,
86+
$this->handlerMock
7987
);
8088
}
8189

8290
public function testCommandWillMarkTransactionAsApprovedWhenNotVoid()
8391
{
84-
$this->commandPoolMock->method('get')
85-
->willReturnMap([
86-
['get_transaction_details', $this->transactionDetailsCommandMock],
87-
]);
88-
89-
$this->transactionResultMock->method('get')
90-
->willReturn([
91-
'transaction' => [
92-
'transactionStatus' => 'authorizedPendingCapture',
93-
'foo' => 'abc',
94-
'bar' => 'cba',
95-
'dontreturnme' => 'justdont'
96-
]
97-
]);
98-
99-
// Assert payment is handled correctly
100-
$this->paymentMock->expects($this->exactly(2))
101-
->method('setData')
102-
->withConsecutive(
103-
['is_transaction_denied', false],
104-
['is_transaction_approved', true]
105-
);
106-
107-
$buildSubject = [
108-
'payment' => $this->paymentDOMock
109-
];
110-
111-
$this->transactionDetailsCommandMock->expects($this->once())
112-
->method('execute')
113-
->with($buildSubject)
114-
->willReturn($this->transactionResultMock);
115-
116-
$result = $this->command->execute($buildSubject);
117-
118-
$expected = [
119-
'foo' => 'abc',
120-
'bar' => 'cba'
92+
$response = [
93+
'transaction' => [
94+
'transactionStatus' => 'authorizedPendingCapture',
95+
'foo' => 'abc',
96+
'bar' => 'cba',
97+
'dontreturnme' => 'justdont'
98+
]
12199
];
122100

123-
$this->assertSame($expected, $result);
124-
}
125-
126-
/**
127-
* @dataProvider declinedTransactionStatusesProvider
128-
* @param string $status
129-
*/
130-
public function testCommandWillMarkTransactionAsDeniedWhenDeclined(string $status)
131-
{
132101
$this->commandPoolMock->method('get')
133102
->willReturnMap([
134103
['get_transaction_details', $this->transactionDetailsCommandMock],
135104
]);
136105

137106
$this->transactionResultMock->method('get')
138-
->willReturn([
139-
'transaction' => [
140-
'transactionStatus' => $status,
141-
'foo' => 'abc',
142-
'bar' => 'cba',
143-
'dontreturnme' => 'justdont'
144-
]
145-
]);
146-
147-
// Assert payment is handled correctly
148-
$this->paymentMock->expects($this->exactly(2))
149-
->method('setData')
150-
->withConsecutive(
151-
['is_transaction_denied', true],
152-
['is_transaction_approved', false]
153-
);
107+
->willReturn($response);
154108

155109
$buildSubject = [
156110
'payment' => $this->paymentDOMock
@@ -161,48 +115,9 @@ public function testCommandWillMarkTransactionAsDeniedWhenDeclined(string $statu
161115
->with($buildSubject)
162116
->willReturn($this->transactionResultMock);
163117

164-
$result = $this->command->execute($buildSubject);
165-
166-
$expected = [
167-
'foo' => 'abc',
168-
'bar' => 'cba'
169-
];
170-
171-
$this->assertSame($expected, $result);
172-
}
173-
174-
/**
175-
* @dataProvider pendingTransactionStatusesProvider
176-
* @param string $status
177-
*/
178-
public function testCommandWillDoNothingWhenTransactionIsStillPending(string $status)
179-
{
180-
$this->commandPoolMock->method('get')
181-
->willReturnMap([
182-
['get_transaction_details', $this->transactionDetailsCommandMock],
183-
]);
184-
185-
$this->transactionResultMock->method('get')
186-
->willReturn([
187-
'transaction' => [
188-
'transactionStatus' => $status,
189-
'foo' => 'abc',
190-
'bar' => 'cba',
191-
'dontreturnme' => 'justdont'
192-
]
193-
]);
194-
195-
// Assert payment is handled correctly
196-
$this->paymentMock->expects($this->never())
197-
->method('setData');
198-
199-
$buildSubject = [
200-
'payment' => $this->paymentDOMock
201-
];
202-
203-
$this->transactionDetailsCommandMock->expects($this->once())
204-
->method('execute')
205-
->with($buildSubject)
118+
$this->handlerMock->expects($this->once())
119+
->method('handle')
120+
->with($buildSubject, $response)
206121
->willReturn($this->transactionResultMock);
207122

208123
$result = $this->command->execute($buildSubject);
@@ -214,20 +129,4 @@ public function testCommandWillDoNothingWhenTransactionIsStillPending(string $st
214129

215130
$this->assertSame($expected, $result);
216131
}
217-
218-
public function pendingTransactionStatusesProvider()
219-
{
220-
return [
221-
['FDSPendingReview'],
222-
['FDSAuthorizedPendingReview']
223-
];
224-
}
225-
226-
public function declinedTransactionStatusesProvider()
227-
{
228-
return [
229-
['void'],
230-
['declined']
231-
];
232-
}
233132
}

0 commit comments

Comments
 (0)