Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Transaction.php
Go to the documentation of this file.
1 <?php
8 
12 
25 {
29  const RAW_DETAILS = 'raw_details_info';
30 
36  protected $_order = null;
37 
42  protected $_parentTransaction = null;
43 
49  protected $_children = null;
50 
58  protected $_identifiedChildren = null;
59 
65  protected $_transactionsAutoLinking = true;
66 
72  protected $_isFailsafe = false;
73 
79  protected $_hasChild = null;
80 
87  protected $_eventPrefix = 'sales_order_payment_transaction';
88 
95  protected $_eventObject = 'order_payment_transaction';
96 
102  protected $_orderWebsiteId = null;
103 
107  protected $_orderFactory;
108 
112  protected $_dateFactory;
113 
118 
123 
127  protected $orderRepository;
128 
142  public function __construct(
143  \Magento\Framework\Model\Context $context,
144  \Magento\Framework\Registry $registry,
145  \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
147  \Magento\Sales\Model\OrderFactory $orderFactory,
150  \Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory,
151  TransactionFactory $transactionFactory,
152  \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
153  \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
154  array $data = []
155  ) {
156  $this->_orderFactory = $orderFactory;
157  $this->_dateFactory = $dateFactory;
158  $this->_transactionFactory = $transactionFactory;
159  $this->orderPaymentRepository = $orderPaymentRepository;
160  $this->orderRepository = $orderRepository;
161  parent::__construct(
162  $context,
163  $registry,
164  $extensionFactory,
166  $resource,
167  $resourceCollection,
168  $data
169  );
170  }
171 
177  protected function _construct()
178  {
179  $this->_init(\Magento\Sales\Model\ResourceModel\Order\Payment\Transaction::class);
180  parent::_construct();
181  }
182 
189  public function setTxnId($txnId)
190  {
191  $this->_verifyTxnId($txnId);
192  return $this->setData('txn_id', $txnId);
193  }
194 
204  public function setParentTxnId($parentTxnId, $txnId = null)
205  {
206  $this->_verifyTxnId($parentTxnId);
207  if (empty($txnId)) {
208  if ('' == $this->getTxnId()) {
209  throw new \Magento\Framework\Exception\LocalizedException(
210  __('The parent transaction ID must have a transaction ID.')
211  );
212  }
213  } else {
214  $this->setTxnId($txnId);
215  }
216  return $this->setData('parent_txn_id', $parentTxnId);
217  }
218 
225  public function setTxnType($txnType)
226  {
227  $this->_verifyTxnType($txnType);
228  return $this->setData('txn_type', $txnType);
229  }
230 
238  public function getParentTransaction($shouldLoad = true)
239  {
240  if (null === $this->_parentTransaction) {
242  $this->_parentTransaction = false;
243  $parentId = $this->getParentId();
244  if ($parentId) {
245  $this->_parentTransaction = $this->_transactionFactory->create();
246  if ($shouldLoad) {
247  $this->_parentTransaction
248  ->setOrderId($this->getOrderId())
249  ->setPaymentId($this->getPaymentId())
250  ->load($parentId);
251  if (!$this->_parentTransaction->getId()) {
252  $this->_parentTransaction = false;
253  } else {
254  $this->_parentTransaction->hasChildTransaction(true);
255  }
256  }
257  }
258  }
260  }
261 
278  public function getChildTransactions($types = null, $txnId = null, $recursive = false)
279  {
280  $this->_loadChildren();
281 
282  // grab all transactions
283  if (empty($types) && null === $txnId) {
284  return $this->_children;
285  } elseif ($types && !is_array($types)) {
286  $types = [$types];
287  }
288 
289  // get a specific transaction
290  if ($txnId) {
291  if (empty($this->_children)) {
292  return null;
293  }
294  $transaction = null;
295  if ($this->_identifiedChildren) {
296  if (isset($this->_identifiedChildren[$txnId])) {
297  $transaction = $this->_identifiedChildren[$txnId];
298  }
299  } else {
300  foreach ($this->_children as $child) {
301  if ($child->getTxnId() === $txnId) {
302  $transaction = $child;
303  break;
304  }
305  }
306  }
307  // return transaction only if type matches
308  if (!$transaction || $types && !in_array($transaction->getType(), $types, true)) {
309  return null;
310  }
311  return $transaction;
312  }
313 
314  // filter transactions by types
315  $result = [];
316  foreach ($this->_children as $child) {
317  if (in_array($child->getType(), $types, true)) {
318  $result[$child->getId()] = $child;
319  }
320  }
321  return $result;
322  }
323 
336  public function closeAuthorization($shouldSave = true, $dryRun = false)
337  {
338  try {
340  } catch (\Exception $e) {
341  if ($dryRun) {
342  return false;
343  }
344  throw $e;
345  }
346  $authTransaction = false;
347  switch ($this->getTxnType()) {
348  case self::TYPE_VOID:
349  // break intentionally omitted
350  case self::TYPE_CAPTURE:
351  $authTransaction = $this->getParentTransaction();
352  break;
353  case self::TYPE_AUTH:
354  $authTransaction = $this;
355  break;
356  // case self::TYPE_PAYMENT?
357  default:
358  break;
359  }
360  if ($authTransaction) {
361  if (!$dryRun) {
362  $authTransaction->close($shouldSave);
363  }
364  }
365  return $authTransaction;
366  }
367 
376  public function closeCapture($shouldSave = true)
377  {
379  $captureTransaction = false;
380  switch ($this->getTxnType()) {
381  case self::TYPE_CAPTURE:
382  $captureTransaction = $this;
383  break;
384  case self::TYPE_REFUND:
385  $captureTransaction = $this->getParentTransaction();
386  break;
387  default:
388  break;
389  }
390  if ($captureTransaction) {
391  $captureTransaction->close($shouldSave);
392  }
393  return $captureTransaction;
394  }
395 
403  {
404  try {
405  $authTransaction = $this->closeAuthorization('', true);
406  if ($authTransaction->hasChildTransaction() || $this->_children) {
407  return false;
408  }
409  return true;
410  } catch (\Magento\Framework\Exception\LocalizedException $e) {
411  // jam all logical exceptions, fallback to false
412  }
413  return false;
414  }
415 
422  public function hasChildTransaction($whetherHasChild = null)
423  {
424  if (null !== $whetherHasChild) {
425  $this->_hasChild = (bool)$whetherHasChild;
426  return $this;
427  } elseif (null === $this->_hasChild) {
428  if ($this->getChildTransactions()) {
429  $this->_hasChild = true;
430  } else {
431  $this->_hasChild = false;
432  }
433  }
434  return $this->_hasChild;
435  }
436 
447  public function setAdditionalInformation($key, $value)
448  {
449  if (is_object($value)) {
450  throw new \Magento\Framework\Exception\LocalizedException(
451  __('Payment transactions disallow storing objects.')
452  );
453  }
454  $info = $this->_getData('additional_information');
455  if (!$info) {
456  $info = [];
457  }
458  $info[$key] = $value;
459  return $this->setData('additional_information', $info);
460  }
461 
468  public function getAdditionalInformation($key = null)
469  {
470  $info = $this->_getData('additional_information');
471  if (!$info) {
472  $info = [];
473  }
474  if ($key) {
475  return isset($info[$key]) ? $info[$key] : null;
476  }
477  return $info;
478  }
479 
486  public function unsAdditionalInformation($key = null)
487  {
488  if ($key) {
489  $info = $this->_getData('additional_information');
490  if (is_array($info)) {
491  unset($info[$key]);
492  }
493  } else {
494  $info = [];
495  }
496  return $this->setData('additional_information', $info);
497  }
498 
508  public function close($shouldSave = true)
509  {
510  if (!$this->_isFailsafe) {
512  }
513  if (1 == $this->getIsClosed() && $this->_isFailsafe) {
514  throw new \Magento\Framework\Exception\LocalizedException(
515  __('The transaction "%1" (%2) is already closed.', $this->getTxnId(), $this->getTxnType())
516  );
517  }
518  $this->setIsClosed(1);
519  if ($shouldSave) {
520  $this->save();
521  }
522  if ($this->_transactionsAutoLinking && self::TYPE_AUTH === $this->getTxnType()) {
523  try {
524  $paymentTransaction = $this->getParentTransaction();
525  if ($paymentTransaction) {
526  $paymentTransaction->close($shouldSave);
527  }
528  } catch (\Exception $e) {
529  if (!$this->_isFailsafe) {
530  throw $e;
531  }
532  }
533  }
534  return $this;
535  }
536 
543  public function getOrderId()
544  {
545  $orderId = $this->_getData('order_id');
546  if ($orderId) {
547  return $orderId;
548  }
549  if ($this->getPaymentId()) {
550  $payment = $this->orderPaymentRepository->get($this->getPaymentId());
551  if ($payment) {
552  $orderId = $payment->getParentId();
553  }
554  }
555 
556  return $orderId;
557  }
558 
564  public function getOrder()
565  {
566  if ($this->_order === null) {
567  $this->setOrder();
568  }
569 
570  return $this->_order;
571  }
572 
581  public function setOrder($order = null)
582  {
583  if (null === $order || $order === true) {
584  if ($this->getOrderId()) {
585  $this->_order = $this->orderRepository->get($this->getOrderId());
586  } else {
587  $this->_order = false;
588  }
589  } elseif (!$this->getId() || $this->getOrderId() == $order->getId()) {
590  $this->_order = $order;
591  } else {
592  throw new \Magento\Framework\Exception\LocalizedException(
593  __('Set order for existing transactions not allowed')
594  );
595  }
596 
597  return $this;
598  }
599 
606  public function isFailsafe($setFailsafe = null)
607  {
608  if (null === $setFailsafe) {
609  return $this->_isFailsafe;
610  }
611  $this->_isFailsafe = (bool)$setFailsafe;
612  return $this;
613  }
614 
620  public function beforeSave()
621  {
622  if (!$this->getOrderId() && $this->getOrder()) {
623  $this->setOrderId($this->getOrder()->getId());
624  }
625  if (!$this->getPaymentId() && $this->getOrder() && $this->getOrder()->getPayment()) {
626  $this->setPaymentId($this->getOrder()->getPayment()->getId());
627  }
628  // set parent id
629  $this->_verifyPaymentObject();
630  if (!$this->getId()) {
631  $this->setCreatedAt($this->_dateFactory->create()->gmtDate());
632  }
633  return parent::beforeSave();
634  }
635 
644  protected function _loadChildren()
645  {
646  if (null !== $this->_children) {
647  return;
648  }
649 
650  // make sure minimum required data is set
652  if (!$this->getPaymentId()) {
653  throw new \Magento\Framework\Exception\LocalizedException(__('At minimum, you need to set a payment ID.'));
654  }
655 
656  $this->setOrder(true);
657 
658  $orderFilter = $this->getOrder();
659  // Try to get order instance for filter
660  if (!$orderFilter) {
661  $orderFilter = $this->getOrderId();
662  }
663 
664  // prepare children collection
665  $children = $this->getResourceCollection()->setOrderFilter(
666  $orderFilter
667  )->addPaymentIdFilter(
668  $this->getPaymentId()
669  )->addParentIdFilter(
670  $this->getId()
671  );
672 
673  // set basic children array and attempt to map them per txn_id, if all of them have txn_id
674  $this->_children = [];
675  $this->_identifiedChildren = [];
676  foreach ($children as $child) {
677  if ($this->getPaymentId()) {
678  $child->setOrderId($this->getOrderId())->setPaymentId($this->getPaymentId());
679  }
680  $this->_children[$child->getId()] = $child;
681  if (false !== $this->_identifiedChildren) {
682  $childTxnId = $child->getTxnId();
683  if (!$childTxnId || '0' == $childTxnId) {
684  $this->_identifiedChildren = false;
685  } else {
686  $this->_identifiedChildren[$child->getTxnId()] = $child;
687  }
688  }
689  }
690  if (false === $this->_identifiedChildren) {
691  $this->_identifiedChildren = [];
692  }
693  }
694 
701  protected function _isVoided()
702  {
704  return self::TYPE_AUTH === $this->getTxnType() && (bool)count($this->getChildTransactions(self::TYPE_VOID));
705  }
706 
712  public function isVoided()
713  {
714  return $this->_isVoided();
715  }
716 
722  public function getTransactionTypes()
723  {
724  return [
725  \Magento\Sales\Model\Order\Payment\Transaction::TYPE_ORDER => __('Order'),
726  \Magento\Sales\Model\Order\Payment\Transaction::TYPE_AUTH => __('Authorization'),
727  \Magento\Sales\Model\Order\Payment\Transaction::TYPE_CAPTURE => __('Capture'),
728  \Magento\Sales\Model\Order\Payment\Transaction::TYPE_VOID => __('Void'),
729  \Magento\Sales\Model\Order\Payment\Transaction::TYPE_REFUND => __('Refund')
730  ];
731  }
732 
738  public function getOrderWebsiteId()
739  {
740  if ($this->_orderWebsiteId === null) {
741  $this->_orderWebsiteId = (int)$this->getResource()->getOrderWebsiteId($this->getOrderId());
742  }
743  return $this->_orderWebsiteId;
744  }
745 
753  protected function _verifyTxnType($txnType = null)
754  {
755  if (null === $txnType) {
756  $txnType = $this->getTxnType();
757  }
758  switch ($txnType) {
759  case self::TYPE_PAYMENT:
760  case self::TYPE_ORDER:
761  case self::TYPE_AUTH:
762  case self::TYPE_CAPTURE:
763  case self::TYPE_VOID:
764  case self::TYPE_REFUND:
765  break;
766  default:
767  throw new \Magento\Framework\Exception\LocalizedException(
768  __('We found an unsupported transaction type "%1".', $txnType)
769  );
770  }
771  }
772 
781  protected function _verifyPaymentObject($dryRun = false)
782  {
783  if (!$this->getPaymentId() || !$this->getOrderId()) {
784  if (!$dryRun) {
785  throw new \Magento\Framework\Exception\LocalizedException(
786  __('Please set a proper payment and order id.')
787  );
788  }
789  }
790  }
791 
799  protected function _verifyTxnId($txnId)
800  {
801  if (null !== $txnId && 0 == strlen($txnId)) {
802  throw new \Magento\Framework\Exception\LocalizedException(__('Please enter a Transaction ID.'));
803  }
804  }
805 
813  protected function _verifyThisTransactionExists()
814  {
815  if (!$this->getId()) {
816  throw new \Magento\Framework\Exception\LocalizedException(
817  __('You can\'t do this without a transaction object.')
818  );
819  }
820  $this->_verifyTxnType();
821  }
822 
823  //@codeCoverageIgnoreStart
824 
830  public function getTransactionId()
831  {
833  }
834 
838  public function setTransactionId($id)
839  {
841  }
842 
848  public function getMethod()
849  {
850  return $this->getData(TransactionInterface::METHOD);
851  }
852 
858  public function getIncrementId()
859  {
861  }
862 
868  public function getParentId()
869  {
871  }
872 
878  public function getPaymentId()
879  {
881  }
882 
888  public function getTxnId()
889  {
890  return $this->getData(TransactionInterface::TXN_ID);
891  }
892 
898  public function getHtmlTxnId()
899  {
900  $this->_eventManager->dispatch($this->_eventPrefix . '_html_txn_id', $this->_getEventData());
901  return isset($this->_data['html_txn_id']) ? $this->_data['html_txn_id'] : $this->getTxnId();
902  }
903 
909  public function getParentTxnId()
910  {
912  }
913 
919  public function getTxnType()
920  {
922  }
923 
929  public function getIsClosed()
930  {
932  }
933 
939  public function getCreatedAt()
940  {
942  }
943 
947  public function setCreatedAt($createdAt)
948  {
949  return $this->setData(TransactionInterface::CREATED_AT, $createdAt);
950  }
951 
955  public function setParentId($id)
956  {
958  }
959 
963  public function setOrderId($id)
964  {
966  }
967 
971  public function setPaymentId($id)
972  {
974  }
975 
979  public function setIsClosed($isClosed)
980  {
981  return $this->setData(TransactionInterface::IS_CLOSED, $isClosed);
982  }
983 
989  public function getExtensionAttributes()
990  {
991  return $this->_getExtensionAttributes();
992  }
993 
1000  public function setExtensionAttributes(\Magento\Sales\Api\Data\TransactionExtensionInterface $extensionAttributes)
1001  {
1002  return $this->_setExtensionAttributes($extensionAttributes);
1003  }
1004 
1005  //@codeCoverageIgnoreEnd
1006 }
$transaction
setParentTxnId($parentTxnId, $txnId=null)
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$id
Definition: fieldset.phtml:14
_setExtensionAttributes(\Magento\Framework\Api\ExtensionAttributesInterface $extensionAttributes)
$order
Definition: order.php:55
__()
Definition: __.php:13
$resource
Definition: bulk.php:12
getChildTransactions($types=null, $txnId=null, $recursive=false)
$payment
Definition: order.php:17
$value
Definition: gender.phtml:16
closeAuthorization($shouldSave=true, $dryRun=false)
__construct(\Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, \Magento\Sales\Model\OrderFactory $orderFactory, \Magento\Sales\Api\OrderPaymentRepositoryInterface $orderPaymentRepository, \Magento\Sales\Api\OrderRepositoryInterface $orderRepository, \Magento\Framework\Stdlib\DateTime\DateTimeFactory $dateFactory, TransactionFactory $transactionFactory, \Magento\Framework\Model\ResourceModel\AbstractResource $resource=null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection=null, array $data=[])
setExtensionAttributes(\Magento\Sales\Api\Data\TransactionExtensionInterface $extensionAttributes)
$children
Definition: actions.phtml:11
foreach( $_productCollection as $_product)() ?>" class $info
Definition: listing.phtml:52