CaptureOperation.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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\Operations;
  7. use Magento\Sales\Api\Data\InvoiceInterface;
  8. use Magento\Sales\Api\Data\OrderPaymentInterface;
  9. use Magento\Sales\Model\Order;
  10. use Magento\Sales\Model\Order\Payment;
  11. use Magento\Sales\Model\Order\Payment\Transaction;
  12. class CaptureOperation extends AbstractOperation
  13. {
  14. /**
  15. * Captures payment.
  16. *
  17. * @param OrderPaymentInterface $payment
  18. * @param InvoiceInterface|null $invoice
  19. * @return OrderPaymentInterface
  20. * @throws \Magento\Framework\Exception\LocalizedException
  21. */
  22. public function capture(OrderPaymentInterface $payment, $invoice)
  23. {
  24. /**
  25. * @var $payment Payment
  26. */
  27. if (null === $invoice) {
  28. $invoice = $this->invoice($payment);
  29. $payment->setCreatedInvoice($invoice);
  30. if ($payment->getIsFraudDetected()) {
  31. $payment->getOrder()->setStatus(Order::STATUS_FRAUD);
  32. }
  33. return $payment;
  34. }
  35. $amountToCapture = $payment->formatAmount($invoice->getBaseGrandTotal());
  36. $order = $payment->getOrder();
  37. $payment->setTransactionId(
  38. $this->transactionManager->generateTransactionId(
  39. $payment,
  40. Transaction::TYPE_CAPTURE,
  41. $payment->getAuthorizationTransaction()
  42. )
  43. );
  44. $this->eventManager->dispatch(
  45. 'sales_order_payment_capture',
  46. ['payment' => $payment, 'invoice' => $invoice]
  47. );
  48. /**
  49. * Fetch an update about existing transaction. It can determine whether the transaction can be paid
  50. * Capture attempt will happen only when invoice is not yet paid and the transaction can be paid
  51. */
  52. if ($invoice->getTransactionId()) {
  53. $method = $payment->getMethodInstance();
  54. $method->setStore(
  55. $order->getStoreId()
  56. );
  57. if ($method->canFetchTransactionInfo()) {
  58. $method->fetchTransactionInfo(
  59. $payment,
  60. $invoice->getTransactionId()
  61. );
  62. }
  63. }
  64. if ($invoice->getIsPaid()) {
  65. throw new \Magento\Framework\Exception\LocalizedException(
  66. __('The transaction "%1" cannot be captured yet.', $invoice->getTransactionId())
  67. );
  68. }
  69. // attempt to capture: this can trigger "is_transaction_pending"
  70. $method = $payment->getMethodInstance();
  71. $method->setStore(
  72. $order->getStoreId()
  73. );
  74. //TODO replace for sale usage
  75. $method->capture($payment, $amountToCapture);
  76. // prepare parent transaction and its amount
  77. $paidWorkaround = 0;
  78. if (!$invoice->wasPayCalled()) {
  79. $paidWorkaround = (double)$amountToCapture;
  80. }
  81. if ($payment->isCaptureFinal($paidWorkaround)) {
  82. $payment->setShouldCloseParentTransaction(true);
  83. }
  84. $transactionBuilder = $this->transactionBuilder->setPayment($payment);
  85. $transactionBuilder->setOrder($order);
  86. $transactionBuilder->setFailSafe(true);
  87. $transactionBuilder->setTransactionId($payment->getTransactionId());
  88. $transactionBuilder->setAdditionalInformation($payment->getTransactionAdditionalInfo());
  89. $transactionBuilder->setSalesDocument($invoice);
  90. $transaction = $transactionBuilder->build(Transaction::TYPE_CAPTURE);
  91. $message = $this->stateCommand->execute($payment, $amountToCapture, $order);
  92. if ($payment->getIsTransactionPending()) {
  93. $invoice->setIsPaid(false);
  94. } else {
  95. $invoice->setIsPaid(true);
  96. $this->updateTotals($payment, ['base_amount_paid_online' => $amountToCapture]);
  97. }
  98. $message = $payment->prependMessage($message);
  99. $payment->addTransactionCommentsToOrder($transaction, $message);
  100. $invoice->setTransactionId($payment->getLastTransId());
  101. return $payment;
  102. }
  103. }