Transaction.php 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Sales\Model\Order\Payment;
  7. use Magento\Framework\Api\AttributeValueFactory;
  8. use Magento\Sales\Api\Data\TransactionInterface;
  9. use Magento\Sales\Model\AbstractModel;
  10. /**
  11. * Payment transaction model
  12. * Tracks transaction history, allows to build transactions hierarchy
  13. * By default transactions are saved as closed.
  14. *
  15. * @api
  16. * @author Magento Core Team <core@magentocommerce.com>
  17. * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
  18. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  19. * @since 100.0.2
  20. */
  21. class Transaction extends AbstractModel implements TransactionInterface
  22. {
  23. /**
  24. * Raw details key in additional info
  25. */
  26. const RAW_DETAILS = 'raw_details_info';
  27. /**
  28. * Order instance
  29. *
  30. * @var \Magento\Sales\Model\Order\Payment
  31. */
  32. protected $_order = null;
  33. /**
  34. * Parent transaction instance
  35. * @var \Magento\Sales\Model\Order\Payment\Transaction
  36. */
  37. protected $_parentTransaction = null;
  38. /**
  39. * Child transactions, assoc array of transaction_id => instance
  40. *
  41. * @var array
  42. */
  43. protected $_children = null;
  44. /**
  45. * Child transactions, assoc array of txn_id => instance
  46. * Filled only in case when all child transactions have txn_id
  47. * Used for quicker search of child transactions using isset() as opposite to foreaching $_children
  48. *
  49. * @var array
  50. */
  51. protected $_identifiedChildren = null;
  52. /**
  53. * Whether to perform automatic actions on transactions, such as auto-closing and putting as a parent
  54. *
  55. * @var bool
  56. */
  57. protected $_transactionsAutoLinking = true;
  58. /**
  59. * Whether to throw exceptions on different operations
  60. *
  61. * @var bool
  62. */
  63. protected $_isFailsafe = false;
  64. /**
  65. * Whether transaction has children
  66. *
  67. * @var bool
  68. */
  69. protected $_hasChild = null;
  70. /**
  71. * Event object prefix
  72. *
  73. * @var string
  74. * @see \Magento\Framework\Model\AbstractModel::$_eventPrefix
  75. */
  76. protected $_eventPrefix = 'sales_order_payment_transaction';
  77. /**
  78. * Event object prefix
  79. *
  80. * @var string
  81. * @see \Magento\Framework\Model\AbstractModel::$_eventObject
  82. */
  83. protected $_eventObject = 'order_payment_transaction';
  84. /**
  85. * Order website id
  86. *
  87. * @var int
  88. */
  89. protected $_orderWebsiteId = null;
  90. /**
  91. * @var \Magento\Sales\Model\OrderFactory
  92. */
  93. protected $_orderFactory;
  94. /**
  95. * @var \Magento\Framework\Stdlib\DateTime\DateTimeFactory
  96. */
  97. protected $_dateFactory;
  98. /**
  99. * @var TransactionFactory
  100. */
  101. protected $_transactionFactory;
  102. /**
  103. * @var \Magento\Sales\Api\OrderPaymentRepositoryInterface
  104. */
  105. protected $orderPaymentRepository;
  106. /**
  107. * @var \Magento\Sales\Api\OrderRepositoryInterface
  108. */
  109. protected $orderRepository;
  110. /**
  111. * @param \Magento\Framework\Model\Context $context
  112. * @param \Magento\Framework\Registry $registry
  113. * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
  114. * @param AttributeValueFactory $customAttributeFactory
  115. * @param \Magento\Sales\Model\OrderFactory $orderFactory
  116. * @param \Magento\Sales\Api\OrderPaymentRepositoryInterface $orderPaymentRepository
  117. * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
  118. * @param \Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory
  119. * @param TransactionFactory $transactionFactory
  120. * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
  121. * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
  122. * @param array $data
  123. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  124. */
  125. public function __construct(
  126. \Magento\Framework\Model\Context $context,
  127. \Magento\Framework\Registry $registry,
  128. \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
  129. AttributeValueFactory $customAttributeFactory,
  130. \Magento\Sales\Model\OrderFactory $orderFactory,
  131. \Magento\Sales\Api\OrderPaymentRepositoryInterface $orderPaymentRepository,
  132. \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
  133. \Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory,
  134. TransactionFactory $transactionFactory,
  135. \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
  136. \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
  137. array $data = []
  138. ) {
  139. $this->_orderFactory = $orderFactory;
  140. $this->_dateFactory = $dateFactory;
  141. $this->_transactionFactory = $transactionFactory;
  142. $this->orderPaymentRepository = $orderPaymentRepository;
  143. $this->orderRepository = $orderRepository;
  144. parent::__construct(
  145. $context,
  146. $registry,
  147. $extensionFactory,
  148. $customAttributeFactory,
  149. $resource,
  150. $resourceCollection,
  151. $data
  152. );
  153. }
  154. /**
  155. * Initialize resource model
  156. *
  157. * @return void
  158. */
  159. protected function _construct()
  160. {
  161. $this->_init(\Magento\Sales\Model\ResourceModel\Order\Payment\Transaction::class);
  162. parent::_construct();
  163. }
  164. /**
  165. * Transaction ID setter
  166. *
  167. * @param string $txnId
  168. * @return $this
  169. */
  170. public function setTxnId($txnId)
  171. {
  172. $this->_verifyTxnId($txnId);
  173. return $this->setData('txn_id', $txnId);
  174. }
  175. /**
  176. * Parent transaction ID setter Can set the transaction id as well
  177. *
  178. * @param string $parentTxnId
  179. * @param string $txnId
  180. * @return $this
  181. * @throws \Magento\Framework\Exception\LocalizedException
  182. */
  183. public function setParentTxnId($parentTxnId, $txnId = null)
  184. {
  185. $this->_verifyTxnId($parentTxnId);
  186. if (empty($txnId)) {
  187. if ('' == $this->getTxnId()) {
  188. throw new \Magento\Framework\Exception\LocalizedException(
  189. __('The parent transaction ID must have a transaction ID.')
  190. );
  191. }
  192. } else {
  193. $this->setTxnId($txnId);
  194. }
  195. return $this->setData('parent_txn_id', $parentTxnId);
  196. }
  197. /**
  198. * Transaction type setter
  199. *
  200. * @param string $txnType
  201. * @return $this
  202. */
  203. public function setTxnType($txnType)
  204. {
  205. $this->_verifyTxnType($txnType);
  206. return $this->setData('txn_type', $txnType);
  207. }
  208. /**
  209. * Parent transaction getter. May attempt to load it.
  210. *
  211. * @param bool $shouldLoad
  212. * @return bool|\Magento\Sales\Model\Order\Payment\Transaction
  213. */
  214. public function getParentTransaction($shouldLoad = true)
  215. {
  216. if (null === $this->_parentTransaction) {
  217. $this->_verifyThisTransactionExists();
  218. $this->_parentTransaction = false;
  219. $parentId = $this->getParentId();
  220. if ($parentId) {
  221. $this->_parentTransaction = $this->_transactionFactory->create();
  222. if ($shouldLoad) {
  223. $this->_parentTransaction
  224. ->setOrderId($this->getOrderId())
  225. ->setPaymentId($this->getPaymentId())
  226. ->load($parentId);
  227. if (!$this->_parentTransaction->getId()) {
  228. $this->_parentTransaction = false;
  229. } else {
  230. $this->_parentTransaction->hasChildTransaction(true);
  231. }
  232. }
  233. }
  234. }
  235. return $this->_parentTransaction;
  236. }
  237. /**
  238. * Child transaction(s) getter
  239. *
  240. * Will attempt to load them first
  241. * Can be filtered by types and/or transaction_id
  242. * Returns transaction object if transaction_id is specified, otherwise - array
  243. * TODO: $recursive is not implemented
  244. *
  245. * @param array|string $types
  246. * @param string $txnId
  247. * @param bool $recursive
  248. * @return Transaction[]
  249. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  250. * @SuppressWarnings(PHPMD.NPathComplexity)
  251. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  252. */
  253. public function getChildTransactions($types = null, $txnId = null, $recursive = false)
  254. {
  255. $this->_loadChildren();
  256. // grab all transactions
  257. if (empty($types) && null === $txnId) {
  258. return $this->_children;
  259. } elseif ($types && !is_array($types)) {
  260. $types = [$types];
  261. }
  262. // get a specific transaction
  263. if ($txnId) {
  264. if (empty($this->_children)) {
  265. return null;
  266. }
  267. $transaction = null;
  268. if ($this->_identifiedChildren) {
  269. if (isset($this->_identifiedChildren[$txnId])) {
  270. $transaction = $this->_identifiedChildren[$txnId];
  271. }
  272. } else {
  273. foreach ($this->_children as $child) {
  274. if ($child->getTxnId() === $txnId) {
  275. $transaction = $child;
  276. break;
  277. }
  278. }
  279. }
  280. // return transaction only if type matches
  281. if (!$transaction || $types && !in_array($transaction->getType(), $types, true)) {
  282. return null;
  283. }
  284. return $transaction;
  285. }
  286. // filter transactions by types
  287. $result = [];
  288. foreach ($this->_children as $child) {
  289. if (in_array($child->getType(), $types, true)) {
  290. $result[$child->getId()] = $child;
  291. }
  292. }
  293. return $result;
  294. }
  295. /**
  296. * Close an authorization transaction
  297. *
  298. * This method can be invoked from any child transaction of the transaction to be closed
  299. * Returns the authorization transaction on success. Otherwise false.
  300. * $dryRun = true prevents actual closing, it just allows to check whether this operation is possible
  301. *
  302. * @param bool $shouldSave
  303. * @param bool $dryRun
  304. * @return bool|\Magento\Sales\Model\Order\Payment\Transaction
  305. * @throws \Exception
  306. */
  307. public function closeAuthorization($shouldSave = true, $dryRun = false)
  308. {
  309. try {
  310. $this->_verifyThisTransactionExists();
  311. } catch (\Exception $e) {
  312. if ($dryRun) {
  313. return false;
  314. }
  315. throw $e;
  316. }
  317. $authTransaction = false;
  318. switch ($this->getTxnType()) {
  319. case self::TYPE_VOID:
  320. // break intentionally omitted
  321. case self::TYPE_CAPTURE:
  322. $authTransaction = $this->getParentTransaction();
  323. break;
  324. case self::TYPE_AUTH:
  325. $authTransaction = $this;
  326. break;
  327. // case self::TYPE_PAYMENT?
  328. default:
  329. break;
  330. }
  331. if ($authTransaction) {
  332. if (!$dryRun) {
  333. $authTransaction->close($shouldSave);
  334. }
  335. }
  336. return $authTransaction;
  337. }
  338. /**
  339. * Close a capture transaction. Logic is similar to closeAuthorization(), but for a capture transaction
  340. *
  341. * @param bool $shouldSave
  342. * @return bool|\Magento\Sales\Model\Order\Payment\Transaction
  343. * @see self::closeAuthorization()
  344. */
  345. public function closeCapture($shouldSave = true)
  346. {
  347. $this->_verifyThisTransactionExists();
  348. $captureTransaction = false;
  349. switch ($this->getTxnType()) {
  350. case self::TYPE_CAPTURE:
  351. $captureTransaction = $this;
  352. break;
  353. case self::TYPE_REFUND:
  354. $captureTransaction = $this->getParentTransaction();
  355. break;
  356. default:
  357. break;
  358. }
  359. if ($captureTransaction) {
  360. $captureTransaction->close($shouldSave);
  361. }
  362. return $captureTransaction;
  363. }
  364. /**
  365. * Check whether authorization in current hierarchy can be voided completely
  366. *
  367. * Basically checks whether the authorization exists and it is not affected by a capture or void
  368. *
  369. * @return bool
  370. */
  371. public function canVoidAuthorizationCompletely()
  372. {
  373. try {
  374. $authTransaction = $this->closeAuthorization('', true);
  375. if ($authTransaction->hasChildTransaction() || $this->_children) {
  376. return false;
  377. }
  378. return true;
  379. } catch (\Magento\Framework\Exception\LocalizedException $e) {
  380. // jam all logical exceptions, fallback to false
  381. }
  382. return false;
  383. }
  384. /**
  385. * Getter/Setter of whether current transaction has a child transaction
  386. *
  387. * @param bool $whetherHasChild
  388. * @return $this|bool
  389. */
  390. public function hasChildTransaction($whetherHasChild = null)
  391. {
  392. if (null !== $whetherHasChild) {
  393. $this->_hasChild = (bool)$whetherHasChild;
  394. return $this;
  395. } elseif (null === $this->_hasChild) {
  396. if ($this->getChildTransactions()) {
  397. $this->_hasChild = true;
  398. } else {
  399. $this->_hasChild = false;
  400. }
  401. }
  402. return $this->_hasChild;
  403. }
  404. /**
  405. * Additional information setter
  406. * Updates data inside the 'additional_information' array
  407. * Doesn't allow to set arrays
  408. *
  409. * @param string $key
  410. * @param mixed $value
  411. * @return $this
  412. * @throws \Magento\Framework\Exception\LocalizedException
  413. */
  414. public function setAdditionalInformation($key, $value)
  415. {
  416. if (is_object($value)) {
  417. throw new \Magento\Framework\Exception\LocalizedException(
  418. __('Payment transactions disallow storing objects.')
  419. );
  420. }
  421. $info = $this->_getData('additional_information');
  422. if (!$info) {
  423. $info = [];
  424. }
  425. $info[$key] = $value;
  426. return $this->setData('additional_information', $info);
  427. }
  428. /**
  429. * Getter for entire additional_information value or one of its element by key
  430. *
  431. * @param string $key
  432. * @return array|null|mixed
  433. */
  434. public function getAdditionalInformation($key = null)
  435. {
  436. $info = $this->_getData('additional_information');
  437. if (!$info) {
  438. $info = [];
  439. }
  440. if ($key) {
  441. return $info[$key] ?? null;
  442. }
  443. return $info;
  444. }
  445. /**
  446. * Unsetter for entire additional_information value or one of its element by key
  447. *
  448. * @param string $key
  449. * @return $this
  450. */
  451. public function unsAdditionalInformation($key = null)
  452. {
  453. if ($key) {
  454. $info = $this->_getData('additional_information');
  455. if (is_array($info)) {
  456. unset($info[$key]);
  457. }
  458. } else {
  459. $info = [];
  460. }
  461. return $this->setData('additional_information', $info);
  462. }
  463. /**
  464. * Close this transaction
  465. *
  466. * @param bool $shouldSave
  467. * @return $this
  468. * @throws \Magento\Framework\Exception\LocalizedException
  469. * @throws \Exception
  470. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  471. */
  472. public function close($shouldSave = true)
  473. {
  474. if (!$this->_isFailsafe) {
  475. $this->_verifyThisTransactionExists();
  476. }
  477. if (1 == $this->getIsClosed() && $this->_isFailsafe) {
  478. throw new \Magento\Framework\Exception\LocalizedException(
  479. __('The transaction "%1" (%2) is already closed.', $this->getTxnId(), $this->getTxnType())
  480. );
  481. }
  482. $this->setIsClosed(1);
  483. if ($shouldSave) {
  484. $this->save();
  485. }
  486. if ($this->_transactionsAutoLinking && self::TYPE_AUTH === $this->getTxnType()) {
  487. try {
  488. $paymentTransaction = $this->getParentTransaction();
  489. if ($paymentTransaction) {
  490. $paymentTransaction->close($shouldSave);
  491. }
  492. } catch (\Exception $e) {
  493. if (!$this->_isFailsafe) {
  494. throw $e;
  495. }
  496. }
  497. }
  498. return $this;
  499. }
  500. /**
  501. * Order ID getter
  502. *
  503. * Attempts to get ID from set order payment object, if any, or from data by key 'order_id'
  504. *
  505. * @return int|null
  506. */
  507. public function getOrderId()
  508. {
  509. $orderId = $this->_getData('order_id');
  510. if ($orderId) {
  511. return $orderId;
  512. }
  513. if ($this->getPaymentId()) {
  514. $payment = $this->orderPaymentRepository->get($this->getPaymentId());
  515. if ($payment) {
  516. $orderId = $payment->getParentId();
  517. }
  518. }
  519. return $orderId;
  520. }
  521. /**
  522. * Retrieve order instance
  523. *
  524. * @return \Magento\Sales\Model\Order\Payment
  525. */
  526. public function getOrder()
  527. {
  528. if ($this->_order === null) {
  529. $this->setOrder();
  530. }
  531. return $this->_order;
  532. }
  533. /**
  534. * Set order instance for transaction depends on transaction behavior
  535. *
  536. * If $order equals to true, method isn't loading new order instance.
  537. *
  538. * @param \Magento\Sales\Model\Order|null|boolean $order
  539. * @return $this
  540. * @throws \Magento\Framework\Exception\LocalizedException
  541. */
  542. public function setOrder($order = null)
  543. {
  544. if (null === $order || $order === true) {
  545. if ($this->getOrderId()) {
  546. $this->_order = $this->orderRepository->get($this->getOrderId());
  547. } else {
  548. $this->_order = false;
  549. }
  550. } elseif (!$this->getId() || $this->getOrderId() == $order->getId()) {
  551. $this->_order = $order;
  552. } else {
  553. throw new \Magento\Framework\Exception\LocalizedException(
  554. __('Set order for existing transactions not allowed')
  555. );
  556. }
  557. return $this;
  558. }
  559. /**
  560. * Setter/Getter whether transaction is supposed to prevent exceptions on saving
  561. *
  562. * @param bool|null $setFailsafe
  563. * @return $this|bool
  564. */
  565. public function isFailsafe($setFailsafe = null)
  566. {
  567. if (null === $setFailsafe) {
  568. return $this->_isFailsafe;
  569. }
  570. $this->_isFailsafe = (bool)$setFailsafe;
  571. return $this;
  572. }
  573. /**
  574. * Verify data required for saving
  575. *
  576. * @return $this
  577. */
  578. public function beforeSave()
  579. {
  580. if (!$this->getOrderId() && $this->getOrder()) {
  581. $this->setOrderId($this->getOrder()->getId());
  582. }
  583. if (!$this->getPaymentId() && $this->getOrder() && $this->getOrder()->getPayment()) {
  584. $this->setPaymentId($this->getOrder()->getPayment()->getId());
  585. }
  586. // set parent id
  587. $this->_verifyPaymentObject();
  588. if (!$this->getId()) {
  589. $this->setCreatedAt($this->_dateFactory->create()->gmtDate());
  590. }
  591. return parent::beforeSave();
  592. }
  593. /**
  594. * Load child transactions
  595. *
  596. * @return void
  597. * @throws \Magento\Framework\Exception\LocalizedException
  598. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  599. * @SuppressWarnings(PHPMD.NPathComplexity)
  600. */
  601. protected function _loadChildren()
  602. {
  603. if (null !== $this->_children) {
  604. return;
  605. }
  606. // make sure minimum required data is set
  607. $this->_verifyThisTransactionExists();
  608. if (!$this->getPaymentId()) {
  609. throw new \Magento\Framework\Exception\LocalizedException(__('At minimum, you need to set a payment ID.'));
  610. }
  611. $this->setOrder(true);
  612. $orderFilter = $this->getOrder();
  613. // Try to get order instance for filter
  614. if (!$orderFilter) {
  615. $orderFilter = $this->getOrderId();
  616. }
  617. // prepare children collection
  618. $children = $this->getResourceCollection()->setOrderFilter(
  619. $orderFilter
  620. )->addPaymentIdFilter(
  621. $this->getPaymentId()
  622. )->addParentIdFilter(
  623. $this->getId()
  624. );
  625. // set basic children array and attempt to map them per txn_id, if all of them have txn_id
  626. $this->_children = [];
  627. $this->_identifiedChildren = [];
  628. foreach ($children as $child) {
  629. if ($this->getPaymentId()) {
  630. $child->setOrderId($this->getOrderId())->setPaymentId($this->getPaymentId());
  631. }
  632. $this->_children[$child->getId()] = $child;
  633. if (false !== $this->_identifiedChildren) {
  634. $childTxnId = $child->getTxnId();
  635. if (!$childTxnId || '0' == $childTxnId) {
  636. $this->_identifiedChildren = false;
  637. } else {
  638. $this->_identifiedChildren[$child->getTxnId()] = $child;
  639. }
  640. }
  641. }
  642. if (false === $this->_identifiedChildren) {
  643. $this->_identifiedChildren = [];
  644. }
  645. }
  646. /**
  647. * Check whether this transaction is voided
  648. *
  649. * @return bool
  650. */
  651. protected function _isVoided()
  652. {
  653. $this->_verifyThisTransactionExists();
  654. return self::TYPE_AUTH === $this->getTxnType() && (bool)count($this->getChildTransactions(self::TYPE_VOID));
  655. }
  656. /**
  657. * Check whether this transaction is voided
  658. *
  659. * @return bool
  660. */
  661. public function isVoided()
  662. {
  663. return $this->_isVoided();
  664. }
  665. /**
  666. * Retrieve transaction types
  667. *
  668. * @return array
  669. */
  670. public function getTransactionTypes()
  671. {
  672. return [
  673. \Magento\Sales\Model\Order\Payment\Transaction::TYPE_ORDER => __('Order'),
  674. \Magento\Sales\Model\Order\Payment\Transaction::TYPE_AUTH => __('Authorization'),
  675. \Magento\Sales\Model\Order\Payment\Transaction::TYPE_CAPTURE => __('Capture'),
  676. \Magento\Sales\Model\Order\Payment\Transaction::TYPE_VOID => __('Void'),
  677. \Magento\Sales\Model\Order\Payment\Transaction::TYPE_REFUND => __('Refund')
  678. ];
  679. }
  680. /**
  681. * Retrieve order website id
  682. *
  683. * @return int
  684. */
  685. public function getOrderWebsiteId()
  686. {
  687. if ($this->_orderWebsiteId === null) {
  688. $this->_orderWebsiteId = (int)$this->getResource()->getOrderWebsiteId($this->getOrderId());
  689. }
  690. return $this->_orderWebsiteId;
  691. }
  692. /**
  693. * Check whether specified or set transaction type is supported
  694. *
  695. * @param string $txnType
  696. * @return void
  697. * @throws \Magento\Framework\Exception\LocalizedException
  698. */
  699. protected function _verifyTxnType($txnType = null)
  700. {
  701. if (null === $txnType) {
  702. $txnType = $this->getTxnType();
  703. }
  704. switch ($txnType) {
  705. case self::TYPE_PAYMENT:
  706. case self::TYPE_ORDER:
  707. case self::TYPE_AUTH:
  708. case self::TYPE_CAPTURE:
  709. case self::TYPE_VOID:
  710. case self::TYPE_REFUND:
  711. break;
  712. default:
  713. throw new \Magento\Framework\Exception\LocalizedException(
  714. __('We found an unsupported transaction type "%1".', $txnType)
  715. );
  716. }
  717. }
  718. /**
  719. * Check whether the payment object is set and it has order object or there is an order_id is set
  720. * $dryRun allows to not throw exception
  721. *
  722. * @param bool $dryRun
  723. * @return void
  724. * @throws \Magento\Framework\Exception\LocalizedException
  725. */
  726. protected function _verifyPaymentObject($dryRun = false)
  727. {
  728. if (!$this->getPaymentId() || !$this->getOrderId()) {
  729. if (!$dryRun) {
  730. throw new \Magento\Framework\Exception\LocalizedException(
  731. __('Please set a proper payment and order id.')
  732. );
  733. }
  734. }
  735. }
  736. /**
  737. * Check whether specified transaction ID is valid
  738. *
  739. * @param string $txnId
  740. * @return void
  741. * @throws \Magento\Framework\Exception\LocalizedException
  742. */
  743. protected function _verifyTxnId($txnId)
  744. {
  745. if (null !== $txnId && 0 == strlen($txnId)) {
  746. throw new \Magento\Framework\Exception\LocalizedException(__('Please enter a Transaction ID.'));
  747. }
  748. }
  749. /**
  750. * Make sure this object is a valid transaction
  751. *
  752. * @return void
  753. * @throws \Magento\Framework\Exception\LocalizedException
  754. */
  755. protected function _verifyThisTransactionExists()
  756. {
  757. if (!$this->getId()) {
  758. throw new \Magento\Framework\Exception\LocalizedException(
  759. __('You can\'t do this without a transaction object.')
  760. );
  761. }
  762. $this->_verifyTxnType();
  763. }
  764. //@codeCoverageIgnoreStart
  765. /**
  766. * Returns transaction_id
  767. *
  768. * @return int
  769. */
  770. public function getTransactionId()
  771. {
  772. return $this->getData(TransactionInterface::TRANSACTION_ID);
  773. }
  774. /**
  775. * @inheritdoc
  776. */
  777. public function setTransactionId($id)
  778. {
  779. return $this->setData(TransactionInterface::TRANSACTION_ID, $id);
  780. }
  781. /**
  782. * Returns method
  783. *
  784. * @return string
  785. */
  786. public function getMethod()
  787. {
  788. return $this->getData(TransactionInterface::METHOD);
  789. }
  790. /**
  791. * Returns increment_id
  792. *
  793. * @return string
  794. */
  795. public function getIncrementId()
  796. {
  797. return $this->getData(TransactionInterface::INCREMENT_ID);
  798. }
  799. /**
  800. * Returns parent_id
  801. *
  802. * @return int|null
  803. */
  804. public function getParentId()
  805. {
  806. return $this->getData(TransactionInterface::PARENT_ID);
  807. }
  808. /**
  809. * Returns payment_id
  810. *
  811. * @return int
  812. */
  813. public function getPaymentId()
  814. {
  815. return $this->getData(TransactionInterface::PAYMENT_ID);
  816. }
  817. /**
  818. * Returns txn_id
  819. *
  820. * @return string
  821. */
  822. public function getTxnId()
  823. {
  824. return $this->getData(TransactionInterface::TXN_ID);
  825. }
  826. /**
  827. * Get HTML format for transaction id
  828. *
  829. * @return string
  830. */
  831. public function getHtmlTxnId()
  832. {
  833. $this->_eventManager->dispatch($this->_eventPrefix . '_html_txn_id', $this->_getEventData());
  834. return $this->_data['html_txn_id'] ?? $this->getTxnId();
  835. }
  836. /**
  837. * Returns parent_txn_id
  838. *
  839. * @return string
  840. */
  841. public function getParentTxnId()
  842. {
  843. return $this->getData(TransactionInterface::PARENT_TXN_ID);
  844. }
  845. /**
  846. * Returns txn_type
  847. *
  848. * @return string
  849. */
  850. public function getTxnType()
  851. {
  852. return $this->getData(TransactionInterface::TXN_TYPE);
  853. }
  854. /**
  855. * Returns is_closed
  856. *
  857. * @return int
  858. */
  859. public function getIsClosed()
  860. {
  861. return $this->getData(TransactionInterface::IS_CLOSED);
  862. }
  863. /**
  864. * Gets the created-at timestamp for the transaction.
  865. *
  866. * @return string
  867. */
  868. public function getCreatedAt()
  869. {
  870. return $this->getData(TransactionInterface::CREATED_AT);
  871. }
  872. /**
  873. * @inheritdoc
  874. */
  875. public function setCreatedAt($createdAt)
  876. {
  877. return $this->setData(TransactionInterface::CREATED_AT, $createdAt);
  878. }
  879. /**
  880. * @inheritdoc
  881. */
  882. public function setParentId($id)
  883. {
  884. return $this->setData(TransactionInterface::PARENT_ID, $id);
  885. }
  886. /**
  887. * @inheritdoc
  888. */
  889. public function setOrderId($id)
  890. {
  891. return $this->setData(TransactionInterface::ORDER_ID, $id);
  892. }
  893. /**
  894. * @inheritdoc
  895. */
  896. public function setPaymentId($id)
  897. {
  898. return $this->setData(TransactionInterface::PAYMENT_ID, $id);
  899. }
  900. /**
  901. * @inheritdoc
  902. */
  903. public function setIsClosed($isClosed)
  904. {
  905. return $this->setData(TransactionInterface::IS_CLOSED, $isClosed);
  906. }
  907. /**
  908. * @inheritdoc
  909. *
  910. * @return \Magento\Sales\Api\Data\TransactionExtensionInterface|null
  911. */
  912. public function getExtensionAttributes()
  913. {
  914. return $this->_getExtensionAttributes();
  915. }
  916. /**
  917. * @inheritdoc
  918. */
  919. public function setExtensionAttributes(\Magento\Sales\Api\Data\TransactionExtensionInterface $extensionAttributes)
  920. {
  921. return $this->_setExtensionAttributes($extensionAttributes);
  922. }
  923. //@codeCoverageIgnoreEnd
  924. }