GatewayCommand.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Payment\Gateway\Command;
  7. use Magento\Payment\Gateway\CommandInterface;
  8. use Magento\Payment\Gateway\ErrorMapper\ErrorMessageMapperInterface;
  9. use Magento\Payment\Gateway\Http\ClientException;
  10. use Magento\Payment\Gateway\Http\ClientInterface;
  11. use Magento\Payment\Gateway\Http\ConverterException;
  12. use Magento\Payment\Gateway\Http\TransferFactoryInterface;
  13. use Magento\Payment\Gateway\Request\BuilderInterface;
  14. use Magento\Payment\Gateway\Response\HandlerInterface;
  15. use Magento\Payment\Gateway\Validator\ResultInterface;
  16. use Magento\Payment\Gateway\Validator\ValidatorInterface;
  17. use Psr\Log\LoggerInterface;
  18. /**
  19. * Class GatewayCommand
  20. * @api
  21. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  22. * @since 100.0.2
  23. */
  24. class GatewayCommand implements CommandInterface
  25. {
  26. /**
  27. * @var BuilderInterface
  28. */
  29. private $requestBuilder;
  30. /**
  31. * @var TransferFactoryInterface
  32. */
  33. private $transferFactory;
  34. /**
  35. * @var ClientInterface
  36. */
  37. private $client;
  38. /**
  39. * @var HandlerInterface
  40. */
  41. private $handler;
  42. /**
  43. * @var ValidatorInterface
  44. */
  45. private $validator;
  46. /**
  47. * @var LoggerInterface
  48. */
  49. private $logger;
  50. /**
  51. * @var ErrorMessageMapperInterface
  52. */
  53. private $errorMessageMapper;
  54. /**
  55. * @param BuilderInterface $requestBuilder
  56. * @param TransferFactoryInterface $transferFactory
  57. * @param ClientInterface $client
  58. * @param LoggerInterface $logger
  59. * @param HandlerInterface $handler
  60. * @param ValidatorInterface $validator
  61. * @param ErrorMessageMapperInterface|null $errorMessageMapper
  62. */
  63. public function __construct(
  64. BuilderInterface $requestBuilder,
  65. TransferFactoryInterface $transferFactory,
  66. ClientInterface $client,
  67. LoggerInterface $logger,
  68. HandlerInterface $handler = null,
  69. ValidatorInterface $validator = null,
  70. ErrorMessageMapperInterface $errorMessageMapper = null
  71. ) {
  72. $this->requestBuilder = $requestBuilder;
  73. $this->transferFactory = $transferFactory;
  74. $this->client = $client;
  75. $this->handler = $handler;
  76. $this->validator = $validator;
  77. $this->logger = $logger;
  78. $this->errorMessageMapper = $errorMessageMapper;
  79. }
  80. /**
  81. * Executes command basing on business object
  82. *
  83. * @param array $commandSubject
  84. * @return void
  85. * @throws CommandException
  86. * @throws ClientException
  87. * @throws ConverterException
  88. */
  89. public function execute(array $commandSubject)
  90. {
  91. // @TODO implement exceptions catching
  92. $transferO = $this->transferFactory->create(
  93. $this->requestBuilder->build($commandSubject)
  94. );
  95. $response = $this->client->placeRequest($transferO);
  96. if ($this->validator !== null) {
  97. $result = $this->validator->validate(
  98. array_merge($commandSubject, ['response' => $response])
  99. );
  100. if (!$result->isValid()) {
  101. $this->processErrors($result);
  102. }
  103. }
  104. if ($this->handler) {
  105. $this->handler->handle(
  106. $commandSubject,
  107. $response
  108. );
  109. }
  110. }
  111. /**
  112. * Tries to map error messages from validation result and logs processed message.
  113. * Throws an exception with mapped message or default error.
  114. *
  115. * @param ResultInterface $result
  116. * @throws CommandException
  117. */
  118. private function processErrors(ResultInterface $result)
  119. {
  120. $messages = [];
  121. $errorsSource = array_merge($result->getErrorCodes(), $result->getFailsDescription());
  122. foreach ($errorsSource as $errorCodeOrMessage) {
  123. $errorCodeOrMessage = (string) $errorCodeOrMessage;
  124. // error messages mapper can be not configured if payment method doesn't have custom error messages.
  125. if ($this->errorMessageMapper !== null) {
  126. $mapped = (string) $this->errorMessageMapper->getMessage($errorCodeOrMessage);
  127. if (!empty($mapped)) {
  128. $messages[] = $mapped;
  129. $errorCodeOrMessage = $mapped;
  130. }
  131. }
  132. $this->logger->critical('Payment Error: ' . $errorCodeOrMessage);
  133. }
  134. throw new CommandException(
  135. !empty($messages)
  136. ? __(implode(PHP_EOL, $messages))
  137. : __('Transaction has been declined. Please try again later.')
  138. );
  139. }
  140. }