requestBuilder = $requestBuilder; $this->transferFactory = $transferFactory; $this->client = $client; $this->handler = $handler; $this->validator = $validator; $this->logger = $logger; $this->errorMessageMapper = $errorMessageMapper; $this->config = $config; } /** * Executes command basing on business object * * @param array $commandSubject * @return \Magento\Payment\Gateway\Command\ResultInterface|null|void * @throws AmazonWebapiException * @throws \Magento\Payment\Gateway\Http\ClientException * @throws \Magento\Payment\Gateway\Http\ConverterException */ public function execute(array $commandSubject) { $isTimeout = 0; $transferO = $this->transferFactory->create( $this->requestBuilder->build($commandSubject) ); $response = $this->client->placeRequest($transferO); if ($this->validator !== null) { $result = $this->validator->validate( array_merge($commandSubject, ['response' => $response]) ); if (!$result->isValid()) { // when Amazon Pay is set to receive asynchronous calls, we need to allow timeouts to pass validation and // flag the handler to save the order for later processing. $auth_mode = ''; if (isset($response['auth_mode'])) { $auth_mode = $response['auth_mode']; } $isTimeout = $this->processErrors($result, $auth_mode); } } $response['timeout'] = $isTimeout; if ($isTimeout) { $response['status'] = true; } if ($this->handler) { $this->handler->handle( $commandSubject, $response ); } } /** * Tries to map error messages from validation result and logs processed message. * Throws an exception with mapped message or default error. * * @throws AmazonWebapiException */ private function processErrors(ResultInterface $result, $mode = '') { $isDecline = false; $isTimeout = false; $code = false; $messages = []; foreach ($result->getFailsDescription() as $failPhrase) { $message = (string)$failPhrase; if ($this->errorMessageMapper !== null) { $mapped = (string)$this->errorMessageMapper->getMessage($message); if (!empty($mapped) && !in_array($mapped, $messages)) { $messages[] = $mapped; } } $this->logger->critical('Payment Error: ' . $message . ': ' . $mapped); if ($message == 'AmazonRejected' || $message == 'TransactionTimedOut') { $code = (int)$this->config->getValue('hard_decline_code'); $isDecline = true; } elseif ($message == 'InvalidPaymentMethod' || $message == 'Declined') { $code = (int)$this->config->getValue('soft_decline_code'); } if ($mode == 'synchronous_possible' && $message == 'TransactionTimedOut') { $isTimeout = true; $isDecline = false; } } if ($isDecline) { $messages[] = __("You will be redirected to the cart shortly."); } if ($isTimeout) { return true; } throw new AmazonWebapiException( !empty($messages) ? __(implode(PHP_EOL, $messages)) : __('Transaction has been declined. Please try again later.'), $code ); return $false; } }