/** * Capture payment * * @param \Magento\Framework\DataObject|\Magento\Payment\Model\InfoInterface|Payment $payment * @param float $amount * @return $this * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount) { $authorizationTransaction = $payment->getAuthorizationTransaction(); $authorizationPeriod = abs(intval($this->getConfigData('authorization_honor_period'))); $maxAuthorizationNumber = abs(intval($this->getConfigData('child_authorization_number'))); $order = $payment->getOrder(); $isAuthorizationCreated = false; if ($payment->getAdditionalInformation($this->_isOrderPaymentActionKey)) { $voided = false; if (!$authorizationTransaction->getIsClosed() && $this->_isTransactionExpired($authorizationTransaction, $authorizationPeriod)) { //Save payment state and configure payment object for voiding $isCaptureFinal = $payment->getShouldCloseParentTransaction(); $payment->setShouldCloseParentTransaction(false); $payment->setParentTransactionId($authorizationTransaction->getTxnId()); $payment->unsTransactionId(); $payment->setVoidOnlyAuthorization(true); $payment->void(new \Magento\Framework\DataObject()); //Revert payment state after voiding $payment->unsAuthorizationTransaction(); $payment->unsTransactionId(); $payment->setShouldCloseParentTransaction($isCaptureFinal); $voided = true; } if ($authorizationTransaction->getIsClosed() || $voided) { if ($payment->getAdditionalInformation($this->_authorizationCountKey) > $maxAuthorizationNumber - 1) { $this->_exception->create(['phrase' => __('The maximum number of child authorizations is reached.')]); } $api = $this->_callDoAuthorize($amount, $payment, $authorizationTransaction->getParentTxnId()); //Adding authorization transaction $this->_pro->importPaymentInfo($api, $payment); $payment->setTransactionId($api->getTransactionId()); $payment->setParentTransactionId($authorizationTransaction->getParentTxnId()); $payment->setIsTransactionClosed(false); $formatedPrice = $order->getBaseCurrency()->formatTxt($amount); if ($payment->getIsTransactionPending()) { $message = __('We\'ll authorize the amount of %1 as soon as the payment gateway approves it.', $formatedPrice); } else { $message = __('The authorized amount is %1.', $formatedPrice); } $transaction = $this->transactionBuilder->setPayment($payment)->setOrder($order)->setTransactionId($payment->getTransactionId())->setFailSafe(true)->build(Transaction::TYPE_AUTH); $payment->addTransactionCommentsToOrder($transaction, $message); $payment->setParentTransactionId($api->getTransactionId()); $isAuthorizationCreated = true; } //close order transaction if needed if ($payment->getShouldCloseParentTransaction()) { $orderTransaction = $this->getOrderTransaction($payment); if ($orderTransaction) { $orderTransaction->setIsClosed(true); $order->addRelatedObject($orderTransaction); } } } if (false === $this->_pro->capture($payment, $amount)) { $this->_placeOrder($payment, $amount); } if ($isAuthorizationCreated && isset($transaction)) { $transaction->setIsClosed(true); } return $this; }
/** * Handle logical errors * * @param array $response * @return void * @throws \Magento\Paypal\Model\Api\ProcessableException|\Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function _handleCallErrors($response) { $errors = $this->_extractErrorsFromResponse($response); if (empty($errors)) { return; } $errorMessages = []; foreach ($errors as $error) { $errorMessages[] = $error['message']; $this->_callErrors[] = $error['code']; } $errorMessages = implode(' ', $errorMessages); $exceptionLogMessage = sprintf('PayPal NVP gateway errors: %s Correlation ID: %s. Version: %s.', $errorMessages, isset($response['CORRELATIONID']) ? $response['CORRELATIONID'] : '', isset($response['VERSION']) ? $response['VERSION'] : ''); $this->_logger->critical($exceptionLogMessage); $exceptionPhrase = __('PayPal gateway has rejected request. %1', $errorMessages); /** @var \Magento\Framework\Exception\LocalizedException $exception */ $exception = count($errors) == 1 && $this->_isProcessableError($errors[0]['code']) ? $this->_processableExceptionFactory->create(['phrase' => $exceptionPhrase, 'code' => $errors[0]['code']]) : $this->_frameworkExceptionFactory->create(['phrase' => $exceptionPhrase]); throw $exception; }