Skip to content

Commit 8b35bd4

Browse files
committed
MAGETWO-83340: [2.3] Provide possibility to customize error messages from payment methods
- GetErrorCodes method is introduced in ResultInterface
1 parent 71be970 commit 8b35bd4

19 files changed

+112
-61
lines changed

app/code/Magento/Braintree/Gateway/Validator/ErrorCodeValidator.php renamed to app/code/Magento/Braintree/Gateway/Validator/ErrorCodeProvider.php

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Braintree\Gateway\Validator;
79

810
use Braintree\Error\ErrorCollection;
@@ -13,32 +15,24 @@
1315
/**
1416
* Processes errors codes from Braintree response.
1517
*/
16-
class ErrorCodeValidator
18+
class ErrorCodeProvider
1719
{
1820
/**
19-
* Invokes validation.
21+
* Retrieves list of error codes from Braintree response.
2022
*
2123
* @param Successful|Error $response
2224
* @return array
2325
*/
24-
public function __invoke($response)
26+
public function getErrorCodes($response): array
2527
{
28+
$result = [];
2629
if (!$response instanceof Error) {
27-
return [true, [__('Transaction is successful.')]];
30+
return $result;
2831
}
2932

30-
return [false, $this->getErrorCodes($response->errors)];
31-
}
33+
/** @var ErrorCollection $collection */
34+
$collection = $response->errors;
3235

33-
/**
34-
* Retrieves list of error codes from Braintree response.
35-
*
36-
* @param ErrorCollection $collection
37-
* @return array
38-
*/
39-
private function getErrorCodes(ErrorCollection $collection)
40-
{
41-
$result = [];
4236
/** @var Validation $error */
4337
foreach ($collection->deepAll() as $error) {
4438
$result[] = $error->code;

app/code/Magento/Braintree/Gateway/Validator/GeneralResponseValidator.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,25 @@ class GeneralResponseValidator extends AbstractValidator
1919
protected $subjectReader;
2020

2121
/**
22-
* @var ErrorCodeValidator
22+
* @var ErrorCodeProvider
2323
*/
24-
private $errorCodeValidator;
24+
private $errorCodeProvider;
2525

2626
/**
2727
* Constructor
2828
*
2929
* @param ResultInterfaceFactory $resultFactory
3030
* @param SubjectReader $subjectReader
31-
* @param ErrorCodeValidator $errorCodeValidator
31+
* @param ErrorCodeProvider $errorCodeProvider
3232
*/
3333
public function __construct(
3434
ResultInterfaceFactory $resultFactory,
3535
SubjectReader $subjectReader,
36-
ErrorCodeValidator $errorCodeValidator
36+
ErrorCodeProvider $errorCodeProvider
3737
) {
3838
parent::__construct($resultFactory);
3939
$this->subjectReader = $subjectReader;
40-
$this->errorCodeValidator = $errorCodeValidator;
40+
$this->errorCodeProvider = $errorCodeProvider;
4141
}
4242

4343
/**
@@ -59,8 +59,9 @@ public function validate(array $validationSubject)
5959
$errorMessages = array_merge($errorMessages, $validationResult[1]);
6060
}
6161
}
62+
$errorCodes = $this->errorCodeProvider->getErrorCodes($response);
6263

63-
return $this->createResult($isValid, $errorMessages);
64+
return $this->createResult($isValid, $errorMessages, $errorCodes);
6465
}
6566

6667
/**
@@ -74,8 +75,7 @@ function ($response) {
7475
property_exists($response, 'success') && $response->success === true,
7576
[$response->message ?? __('Braintree error response.')]
7677
];
77-
},
78-
$this->errorCodeValidator
78+
}
7979
];
8080
}
8181
}

app/code/Magento/Braintree/Test/Unit/Gateway/Command/GetPaymentNonceCommandTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ protected function setUp()
9999
->getMock();
100100

101101
$this->validationResultMock = $this->getMockBuilder(ResultInterface::class)
102-
->setMethods(['isValid', 'getFailsDescription'])
102+
->setMethods(['isValid', 'getFailsDescription', 'getErrorCodes'])
103103
->getMock();
104104

105105
$this->responseValidatorMock = $this->getMockBuilder(PaymentNonceResponseValidator::class)

app/code/Magento/Braintree/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
use Braintree\Result\Error;
99
use Magento\Braintree\Gateway\SubjectReader;
10-
use Magento\Braintree\Gateway\Validator\ErrorCodeValidator;
10+
use Magento\Braintree\Gateway\Validator\ErrorCodeProvider;
1111
use Magento\Braintree\Gateway\Validator\GeneralResponseValidator;
1212
use Magento\Framework\Phrase;
1313
use Magento\Payment\Gateway\Validator\Result;
@@ -41,7 +41,7 @@ protected function setUp()
4141
$this->responseValidator = new GeneralResponseValidator(
4242
$this->resultInterfaceFactory,
4343
new SubjectReader(),
44-
new ErrorCodeValidator()
44+
new ErrorCodeProvider()
4545
);
4646
}
4747

@@ -51,18 +51,20 @@ protected function setUp()
5151
* @param array $validationSubject
5252
* @param bool $isValid
5353
* @param Phrase[] $messages
54+
* @param array $errorCodes
5455
* @return void
5556
*
5657
* @dataProvider dataProviderTestValidate
5758
*/
58-
public function testValidate(array $validationSubject, bool $isValid, $messages)
59+
public function testValidate(array $validationSubject, bool $isValid, $messages, array $errorCodes)
5960
{
6061
$result = new Result($isValid, $messages);
6162

6263
$this->resultInterfaceFactory->method('create')
6364
->with([
6465
'isValid' => $isValid,
65-
'failsDescription' => $messages
66+
'failsDescription' => $messages,
67+
'errorCodes' => $errorCodes
6668
])
6769
->willReturn($result);
6870

@@ -104,7 +106,8 @@ public function dataProviderTestValidate()
104106
],
105107
],
106108
'isValid' => true,
107-
[]
109+
[],
110+
'errorCodes' => []
108111
],
109112
[
110113
'validationSubject' => [
@@ -115,7 +118,8 @@ public function dataProviderTestValidate()
115118
'isValid' => false,
116119
[
117120
__('Transaction was failed.')
118-
]
121+
],
122+
'errorCodes' => []
119123
],
120124
[
121125
'validationSubject' => [
@@ -125,9 +129,9 @@ public function dataProviderTestValidate()
125129
],
126130
'isValid' => false,
127131
[
128-
__('Braintree error response.'),
129-
81804
130-
]
132+
__('Braintree error response.')
133+
],
134+
'errorCodes' => ['81804']
131135
]
132136
];
133137
}

app/code/Magento/Braintree/Test/Unit/Gateway/Validator/PaymentNonceResponseValidatorTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
namespace Magento\Braintree\Test\Unit\Gateway\Validator;
77

88
use Magento\Braintree\Gateway\SubjectReader;
9-
use Magento\Braintree\Gateway\Validator\ErrorCodeValidator;
9+
use Magento\Braintree\Gateway\Validator\ErrorCodeProvider;
1010
use Magento\Braintree\Gateway\Validator\PaymentNonceResponseValidator;
1111
use Magento\Payment\Gateway\Validator\Result;
1212
use Magento\Payment\Gateway\Validator\ResultInterfaceFactory;
@@ -34,7 +34,7 @@ protected function setUp()
3434
$this->validator = new PaymentNonceResponseValidator(
3535
$this->resultInterfaceFactory,
3636
new SubjectReader(),
37-
new ErrorCodeValidator()
37+
new ErrorCodeProvider()
3838
);
3939
}
4040

app/code/Magento/Braintree/Test/Unit/Gateway/Validator/ResponseValidatorTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use Braintree\Result\Successful;
99
use Braintree\Transaction;
1010
use Magento\Braintree\Gateway\SubjectReader;
11-
use Magento\Braintree\Gateway\Validator\ErrorCodeValidator;
11+
use Magento\Braintree\Gateway\Validator\ErrorCodeProvider;
1212
use Magento\Braintree\Gateway\Validator\ResponseValidator;
1313
use Magento\Framework\Phrase;
1414
use Magento\Payment\Gateway\Validator\Result;
@@ -46,7 +46,7 @@ protected function setUp()
4646
$this->responseValidator = new ResponseValidator(
4747
$this->resultInterfaceFactory,
4848
new SubjectReader(),
49-
new ErrorCodeValidator()
49+
new ErrorCodeProvider()
5050
);
5151
}
5252

app/code/Magento/Payment/Gateway/Command/GatewayCommand.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

88
use Magento\Payment\Gateway\CommandInterface;
99
use Magento\Payment\Gateway\ErrorMapper\ErrorMessageMapperInterface;
10+
use Magento\Payment\Gateway\Http\ClientException;
1011
use Magento\Payment\Gateway\Http\ClientInterface;
12+
use Magento\Payment\Gateway\Http\ConverterException;
1113
use Magento\Payment\Gateway\Http\TransferFactoryInterface;
1214
use Magento\Payment\Gateway\Request\BuilderInterface;
1315
use Magento\Payment\Gateway\Response\HandlerInterface;
@@ -91,6 +93,8 @@ public function __construct(
9193
* @param array $commandSubject
9294
* @return void
9395
* @throws CommandException
96+
* @throws ClientException
97+
* @throws ConverterException
9498
*/
9599
public function execute(array $commandSubject)
96100
{
@@ -127,18 +131,19 @@ public function execute(array $commandSubject)
127131
private function processErrors(ResultInterface $result)
128132
{
129133
$messages = [];
130-
foreach ($result->getFailsDescription() as $failPhrase) {
131-
$message = (string) $failPhrase;
134+
$errorsSource = array_merge($result->getErrorCodes(), $result->getFailsDescription());
135+
foreach ($errorsSource as $errorCodeOrMessage) {
136+
$errorCodeOrMessage = (string) $errorCodeOrMessage;
132137

133138
// error messages mapper can be not configured if payment method doesn't have custom error messages.
134139
if ($this->errorMessageMapper !== null) {
135-
$mapped = (string) $this->errorMessageMapper->getMessage($message);
140+
$mapped = (string) $this->errorMessageMapper->getMessage($errorCodeOrMessage);
136141
if (!empty($mapped)) {
137142
$messages[] = $mapped;
138-
$message = $mapped;
143+
$errorCodeOrMessage = $mapped;
139144
}
140145
}
141-
$this->logger->critical('Payment Error: ' . $message);
146+
$this->logger->critical('Payment Error: ' . $errorCodeOrMessage);
142147
}
143148

144149
throw new CommandException(

app/code/Magento/Payment/Gateway/ErrorMapper/ErrorMessageMapper.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Payment\Gateway\ErrorMapper;
79

810
use Magento\Framework\Config\DataInterface;
@@ -13,6 +15,8 @@
1315
* For example, during authorization payment operation the payment integration can validate error messages
1416
* related to credit card details and customer address data.
1517
* In that case, this implementation can be extended via di.xml and configured with appropriate mappers.
18+
*
19+
* @api
1620
*/
1721
class ErrorMessageMapper implements ErrorMessageMapperInterface
1822
{

app/code/Magento/Payment/Gateway/ErrorMapper/ErrorMessageMapperInterface.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Payment\Gateway\ErrorMapper;
79

810
use Magento\Framework\Phrase;
911

1012
/**
1113
* Interface to provide customization for payment validation errors.
14+
*
15+
* @api
1216
*/
1317
interface ErrorMessageMapperInterface
1418
{

app/code/Magento/Payment/Gateway/ErrorMapper/MappingData.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Payment\Gateway\ErrorMapper;
79

810
use Magento\Framework\Config\Data\Scoped;

0 commit comments

Comments
 (0)