<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\AuthorizenetAcceptjs\Gateway\Command; use Magento\AuthorizenetAcceptjs\Gateway\SubjectReader; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Payment\Gateway\Command\CommandPoolInterface; use Magento\Payment\Gateway\CommandInterface; use Magento\Payment\Gateway\Helper\ContextHelper; use Magento\Sales\Api\Data\OrderPaymentInterface; use Magento\Sales\Api\Data\TransactionInterface; use Magento\Sales\Api\TransactionRepositoryInterface; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; /** * Chooses the best method of capture based on the context of the payment */ class CaptureStrategyCommand implements CommandInterface { private const SALE = 'sale'; private const CAPTURE = 'settle'; /** * @var CommandPoolInterface */ private $commandPool; /** * @var TransactionRepositoryInterface */ private $transactionRepository; /** * @var FilterBuilder */ private $filterBuilder; /** * @var SearchCriteriaBuilder */ private $searchCriteriaBuilder; /** * @var SubjectReader */ private $subjectReader; /** * @param CommandPoolInterface $commandPool * @param TransactionRepositoryInterface $repository * @param FilterBuilder $filterBuilder * @param SearchCriteriaBuilder $searchCriteriaBuilder * @param SubjectReader $subjectReader */ public function __construct( CommandPoolInterface $commandPool, TransactionRepositoryInterface $repository, FilterBuilder $filterBuilder, SearchCriteriaBuilder $searchCriteriaBuilder, SubjectReader $subjectReader ) { $this->commandPool = $commandPool; $this->transactionRepository = $repository; $this->filterBuilder = $filterBuilder; $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->subjectReader = $subjectReader; } /** * @inheritdoc */ public function execute(array $commandSubject): void { /** @var PaymentDataObjectInterface $paymentDO */ $paymentDO = $this->subjectReader->readPayment($commandSubject); $command = $this->getCommand($paymentDO); $this->commandPool->get($command) ->execute($commandSubject); } /** * Get execution command name. * * @param PaymentDataObjectInterface $paymentDO * @return string */ private function getCommand(PaymentDataObjectInterface $paymentDO): string { $payment = $paymentDO->getPayment(); ContextHelper::assertOrderPayment($payment); // If auth transaction does not exist then execute authorize&capture command $captureExists = $this->captureTransactionExists($payment); if (!$payment->getAuthorizationTransaction() && !$captureExists) { return self::SALE; } return self::CAPTURE; } /** * Check if capture transaction already exists * * @param OrderPaymentInterface $payment * @return bool */ private function captureTransactionExists(OrderPaymentInterface $payment): bool { $this->searchCriteriaBuilder->addFilters( [ $this->filterBuilder ->setField('payment_id') ->setValue($payment->getId()) ->create(), ] ); $this->searchCriteriaBuilder->addFilters( [ $this->filterBuilder ->setField('txn_type') ->setValue(TransactionInterface::TYPE_CAPTURE) ->create(), ] ); $searchCriteria = $this->searchCriteriaBuilder->create(); $count = $this->transactionRepository->getList($searchCriteria) ->getTotalCount(); return $count > 0; } }