Example #1
0
 /**
  * Process payment refund notification
  * Updates transactions hierarchy, if required
  * Prevents transaction double processing
  * Updates payment totals, updates order status and adds proper comments
  * TODO: potentially a full capture can be refunded. In this case if there was only one invoice for that transaction
  *       then we should create a creditmemo from invoice and also refund it offline
  * TODO: implement logic of chargebacks reimbursements (via negative amount)
  *
  * @param float $amount
  * @return $this
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  */
 public function registerRefundNotification($amount)
 {
     $notificationAmount = $amount;
     $this->setTransactionId($this->transactionManager->generateTransactionId($this, Transaction::TYPE_REFUND, $this->transactionRepository->getByTransactionId($this->getParentTransactionId(), $this->getId(), $this->getOrder()->getId())));
     if ($this->checkIfTransactionExists()) {
         return $this;
     }
     $order = $this->getOrder();
     $invoice = $this->_getInvoiceForTransactionId($this->getParentTransactionId());
     //choose where we get totals
     $salesEntity = $invoice ?: $order;
     $baseGrandTotal = $salesEntity->getBaseGrandTotal();
     $amountRefundLeft = $baseGrandTotal - $salesEntity->getBaseTotalRefunded();
     if ($amountRefundLeft < $amount) {
         $amount = $amountRefundLeft;
     }
     if ($amount != $baseGrandTotal) {
         $order->addStatusHistoryComment(__('IPN "Refunded". Refund issued by merchant. Registered notification about refunded amount of %1. Transaction ID: "%2". Credit Memo has not been created. Please create offline Credit Memo.', $this->formatPrice($notificationAmount), $this->getTransactionId()), false);
         return $this;
     }
     $creditmemo = $this->prepareCreditMemo($amount, $baseGrandTotal, $invoice);
     $creditmemo->setPaymentRefundDisallowed(true)->setAutomaticallyCreated(true)->register()->addComment(__('The credit memo has been created automatically.'));
     $creditmemo->save();
     $this->_updateTotals(['amount_refunded' => $creditmemo->getGrandTotal(), 'base_amount_refunded_online' => $amount]);
     $this->setCreatedCreditmemo($creditmemo);
     // update transactions and order state
     $transaction = $this->addTransaction(Transaction::TYPE_REFUND, $creditmemo);
     $message = $this->prependMessage(__('Registered notification about refunded amount of %1.', $this->formatPrice($amount)));
     $message = $this->_appendTransactionToMessage($transaction, $message);
     $this->setOrderStateProcessing($message);
     return $this;
 }
 /**
  * Check if capture transaction already exists
  *
  * @param OrderPaymentInterface $payment
  * @return bool
  */
 private function isExistsCaptureTransaction(OrderPaymentInterface $payment)
 {
     $filters[] = $this->filterBuilder->setField('payment_id')->setValue($payment->getId())->create();
     $filters[] = $this->filterBuilder->setField('txn_type')->setValue(TransactionInterface::TYPE_CAPTURE)->create();
     $searchCriteria = $this->searchCriteriaBuilder->addFilters($filters)->create();
     $count = $this->transactionRepository->getList($searchCriteria)->getTotalCount();
     return (bool) $count;
 }
Example #3
0
 /**
  * @param string $payuplOrderId
  * @param string $status
  * @param bool $close
  * @throws LocalizedException
  */
 public function updateStatus($payuplOrderId, $status, $close = false)
 {
     /**
      * @var $transaction \Magento\Sales\Model\Order\Payment\Transaction
      */
     $id = $this->transactionResource->getIdByPayuplOrderId($payuplOrderId);
     if (!$id) {
         throw new LocalizedException(new Phrase('Transaction ' . $payuplOrderId . ' not found.'));
     }
     $transaction = $this->transactionRepository->get($id);
     if ($close) {
         $transaction->setIsClosed(1);
     }
     $rawDetailsInfo = $transaction->getAdditionalInformation(\Magento\Sales\Model\Order\Payment\Transaction::RAW_DETAILS);
     $rawDetailsInfo['status'] = $status;
     $transaction->setAdditionalInformation(\Magento\Sales\Model\Order\Payment\Transaction::RAW_DETAILS, $rawDetailsInfo)->save();
 }
 /**
  * Build search criteria
  */
 private function buildSearchCriteria()
 {
     $this->filterBuilder->expects(static::exactly(2))->method('setField')->willReturnSelf();
     $this->filterBuilder->expects(static::exactly(2))->method('setValue')->willReturnSelf();
     $searchCriteria = new SearchCriteria();
     $this->searchCriteriaBuilder->expects(static::once())->method('addFilters')->willReturnSelf();
     $this->searchCriteriaBuilder->expects(static::once())->method('create')->willReturn($searchCriteria);
     $this->transactionRepository->expects(static::once())->method('getList')->with($searchCriteria)->willReturnSelf();
 }
Example #5
0
 /**
  * Links transaction with parent transaction
  *
  * @param TransactionInterface $transaction
  * @return TransactionInterface
  */
 protected function linkWithParentTransaction(TransactionInterface $transaction)
 {
     $parentTransactionId = $this->payment->getParentTransactionId();
     if ($parentTransactionId) {
         $transaction->setParentTxnId($parentTransactionId);
         if ($this->payment->getShouldCloseParentTransaction()) {
             $parentTransaction = $this->transactionRepository->getByTransactionId($parentTransactionId, $this->payment->getid(), $this->order->getId());
             if ($parentTransaction) {
                 if (!$parentTransaction->getIsClosed()) {
                     $parentTransaction->isFailsafe($this->failSafe)->close(false);
                 }
                 $this->order->addRelatedObject($parentTransaction);
             }
         }
     }
     return $transaction;
 }
 /**
  * @param int $size
  * @param string $command
  * @covers       \Magento\BraintreeTwo\Gateway\Command\CaptureStrategyCommand::execute
  * @dataProvider captureDataProvider
  */
 public function testCaptureExecute($size, $command)
 {
     $paymentData = $this->getPaymentDataObjectMock();
     $subject['payment'] = $paymentData;
     $this->subjectReaderMock->expects(self::once())->method('readPayment')->with($subject)->willReturn($paymentData);
     $this->payment->expects(static::once())->method('getAuthorizationTransaction')->willReturn(true);
     $this->payment->expects(static::once())->method('getId')->willReturn(1);
     $this->filterBuilder->expects(static::exactly(2))->method('setField')->willReturnSelf();
     $this->filterBuilder->expects(static::exactly(2))->method('setValue')->willReturnSelf();
     $searchCriteria = new SearchCriteria();
     $this->searchCriteriaBuilder->expects(static::once())->method('addFilters')->willReturnSelf();
     $this->searchCriteriaBuilder->expects(static::once())->method('create')->willReturn($searchCriteria);
     $this->transactionRepository->expects(static::once())->method('getList')->with($searchCriteria)->willReturnSelf();
     $this->transactionRepository->expects(static::once())->method('getTotalCount')->willReturn($size);
     $this->commandPool->expects(static::once())->method('get')->with($command)->willReturn($this->command);
     $this->strategyCommand->execute($subject);
 }
Example #7
0
 /**
  * Get transaction with type order
  *
  * @param OrderPaymentInterface $payment
  *
  * @return false|\Magento\Sales\Api\Data\TransactionInterface
  */
 protected function getOrderTransaction($payment)
 {
     return $this->transactionRepository->getByTransactionType(Transaction::TYPE_ORDER, $payment->getId(), $payment->getOrder()->getId());
 }
Example #8
0
 /**
  * Return option array
  *
  * @return array
  */
 public function toOptionArray()
 {
     return $this->transactionRepository->create()->getTransactionTypes();
 }
Example #9
0
 /**
  * Checks if transaction exists by txt id
  *
  * @param string $transactionId
  * @param int $paymentId
  * @param int $orderId
  * @return bool
  */
 public function isTransactionExists($transactionId, $paymentId, $orderId)
 {
     return $transactionId && $this->transactionRepository->getByTransactionId($transactionId, $paymentId, $orderId);
 }
 /**
  * Fetch transaction details info
  *
  * Update transaction info if there is one placing transaction only
  *
  * @param \Magento\Payment\Model\InfoInterface $payment
  * @param string $transactionId
  * @return array
  */
 public function fetchTransactionInfo(\Magento\Payment\Model\InfoInterface $payment, $transactionId)
 {
     $transaction = $this->transactionRepository->getByTransactionId($transactionId, $payment->getId(), $payment->getOrder()->getId());
     $response = $this->getTransactionResponse($transactionId);
     if ($response->getXResponseCode() == self::RESPONSE_CODE_APPROVED) {
         if ($response->getTransactionStatus() == 'voided') {
             $payment->setIsTransactionDenied(true);
             $payment->setIsTransactionClosed(true);
             $transaction->close();
         } else {
             $transaction->setAdditionalInformation(self::TRANSACTION_FRAUD_STATE_KEY, false);
             $payment->setIsTransactionApproved(true);
         }
     } elseif ($response->getXResponseReasonCode() == self::RESPONSE_REASON_CODE_PENDING_REVIEW_DECLINED) {
         $payment->setIsTransactionDenied(true);
     }
     $this->addStatusCommentOnUpdate($payment, $response, $transactionId);
     return [];
 }