GetAmazonCaptureUpdates.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. /**
  3. * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License").
  6. * You may not use this file except in compliance with the License.
  7. * A copy of the License is located at
  8. *
  9. * http://aws.amazon.com/apache2.0
  10. *
  11. * or in the "license" file accompanying this file. This file is distributed
  12. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  13. * express or implied. See the License for the specific language governing
  14. * permissions and limitations under the License.
  15. */
  16. namespace Amazon\Payment\Cron;
  17. use Amazon\Core\Helper\Data;
  18. use Amazon\Core\Model\Config\Source\UpdateMechanism;
  19. use Amazon\Payment\Api\Data\PendingCaptureInterface;
  20. use Amazon\Payment\Model\PaymentManagement\Capture;
  21. use Amazon\Payment\Model\ResourceModel\PendingCapture\CollectionFactory;
  22. use Magento\Framework\Data\Collection;
  23. use Magento\Sales\Api\TransactionRepositoryInterface;
  24. use Magento\Framework\Api\SearchCriteriaBuilder;
  25. use Magento\Framework\Api\FilterBuilder;
  26. use Magento\Framework\Api\Search\FilterGroup;
  27. use Psr\Log\LoggerInterface;
  28. class GetAmazonCaptureUpdates
  29. {
  30. /**
  31. * @var int
  32. */
  33. private $limit;
  34. /**
  35. * @var CollectionFactory
  36. */
  37. private $collectionFactory;
  38. /**
  39. * @var Capture
  40. */
  41. private $capture;
  42. /**
  43. * @var Data
  44. */
  45. private $coreHelper;
  46. /**
  47. * @var TransactionRepositoryInterface
  48. */
  49. private $transactionRepository;
  50. /**
  51. * @var FilterBuilder
  52. */
  53. private $filterBuilder;
  54. /**
  55. * @var SearchCriteriaBuilder
  56. */
  57. private $searchBuilder;
  58. /**
  59. * @var FilterGroup
  60. */
  61. private $filterGroup;
  62. /**
  63. * @var LoggerInterface
  64. */
  65. private $logger;
  66. /**
  67. * GetAmazonCaptureUpdates constructor.
  68. * @param CollectionFactory $collectionFactory
  69. * @param Capture $capture
  70. * @param Data $coreHelper
  71. * @param TransactionRepositoryInterface $transactionRepository
  72. * @param SearchCriteriaBuilder $searchBuilder
  73. * @param FilterBuilder $filterBuilder
  74. * @param FilterGroup $filterGroup
  75. * @param LoggerInterface $logger
  76. * @param int $limit
  77. */
  78. public function __construct(
  79. CollectionFactory $collectionFactory,
  80. Capture $capture,
  81. Data $coreHelper,
  82. TransactionRepositoryInterface $transactionRepository,
  83. SearchCriteriaBuilder $searchBuilder,
  84. FilterBuilder $filterBuilder,
  85. FilterGroup $filterGroup,
  86. LoggerInterface $logger,
  87. $limit = 100
  88. ) {
  89. $this->collectionFactory = $collectionFactory;
  90. $this->capture = $capture;
  91. $this->coreHelper = $coreHelper;
  92. $this->transactionRepository = $transactionRepository;
  93. $this->searchBuilder = $searchBuilder;
  94. $this->filterBuilder = $filterBuilder;
  95. $this->filterGroup = $filterGroup;
  96. $this->logger = $logger;
  97. $limit = (int)$limit;
  98. if ($limit < 1) {
  99. throw new \InvalidArgumentException('Limit must be greater than 1.');
  100. }
  101. $this->limit = $limit;
  102. }
  103. /**
  104. * Since we might not get order or payment ID during gateway transaction, we make sure items in the
  105. * amazon_pending_capture table have these IDs if they are not set by matching them to a transaction that
  106. * has matching transaction or parent transaction IDs.
  107. */
  108. private function updateIds()
  109. {
  110. // only get items that have no order ID set since we don't want to have to keep repeating this
  111. $collection = $this->collectionFactory
  112. ->create()
  113. ->addFieldToFilter('order_id', ['eq' => 0])
  114. ->addOrder(PendingCaptureInterface::CREATED_AT, Collection::SORT_ORDER_ASC)
  115. ->setPageSize($this->limit)
  116. ->setCurPage(1);
  117. foreach ($collection->getItems() as $item) {
  118. if ($item) {
  119. $hasTransaction = false;
  120. $parent = $this->filterBuilder
  121. ->setField('parent_txn_id')
  122. ->setValue($item->getCaptureId())
  123. ->setConditionType('eq')
  124. ->create();
  125. $child = $this->filterBuilder
  126. ->setField('txn_id')
  127. ->setValue($item->getCaptureId())
  128. ->setConditionType('eq')
  129. ->create();
  130. $filterOr = $this->filterGroup->setFilters([$parent, $child]);
  131. $searchCriteria = $this->searchBuilder->setFilterGroups([$filterOr])->create();
  132. $transactionList = $this->transactionRepository->getList($searchCriteria);
  133. foreach ($transactionList->getItems() as $transaction) {
  134. if ($transaction) {
  135. $item->setPaymentId($transaction->getPaymentId());
  136. $item->setOrderId($transaction->getOrderId());
  137. $item->save();
  138. $hasTransaction = true;
  139. }
  140. }
  141. // If there's no match, get rid of this item in the table so the cron job will not error out.
  142. if (!$hasTransaction) {
  143. $item->delete();
  144. }
  145. }
  146. }
  147. }
  148. /**
  149. * During cron, process payments if possible.
  150. */
  151. public function execute()
  152. {
  153. if (UpdateMechanism::IPN === $this->coreHelper->getUpdateMechanism()) {
  154. return;
  155. }
  156. $this->updateIds();
  157. $collection = $this->collectionFactory
  158. ->create()
  159. ->addOrder(PendingCaptureInterface::CREATED_AT, Collection::SORT_ORDER_ASC)
  160. ->setPageSize($this->limit)
  161. ->setCurPage(1);
  162. $pendingCaptureIds = $collection->getIdGenerator();
  163. foreach ($pendingCaptureIds as $pendingCaptureId) {
  164. try {
  165. $this->capture->updateCapture($pendingCaptureId);
  166. } catch (\Exception $e) {
  167. $this->logger->error($e);
  168. }
  169. }
  170. }
  171. }