Authorize.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <?php
  2. /**
  3. * This file is part of the Klarna KP module
  4. *
  5. * (c) Klarna Bank AB (publ)
  6. *
  7. * For the full copyright and license information, please view the NOTICE
  8. * and LICENSE files that were distributed with this source code.
  9. */
  10. namespace Klarna\Kp\Gateway\Command;
  11. use Klarna\Core\Api\BuilderInterface;
  12. use Klarna\Core\Api\OrderRepositoryInterface;
  13. use Klarna\Core\Model\Api\Builder;
  14. use Klarna\Core\Model\OrderFactory;
  15. use Klarna\Kp\Api\CreditApiInterface;
  16. use Klarna\Kp\Api\Data\RequestInterface;
  17. use Klarna\Kp\Api\QuoteRepositoryInterface;
  18. use Klarna\Kp\Model\Payment\Kp;
  19. use Magento\Payment\Gateway\Command;
  20. use Magento\Payment\Gateway\Command\CommandException;
  21. use Magento\Payment\Gateway\CommandInterface;
  22. use Magento\Quote\Api\CartRepositoryInterface;
  23. use Magento\Quote\Api\Data\CartInterface;
  24. /**
  25. * Class Authorize
  26. *
  27. * @package Klarna\Kp\Gateway\Command
  28. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  29. */
  30. class Authorize implements CommandInterface
  31. {
  32. /**
  33. * Fraud status types
  34. */
  35. const FRAUD_STATUS_ACCEPTED = 'ACCEPTED';
  36. const FRAUD_STATUS_REJECTED = 'REJECTED';
  37. const FRAUD_STATUS_PENDING = 'PENDING';
  38. /**
  39. * @var BuilderInterface
  40. */
  41. private $builder;
  42. /**
  43. * @var OrderFactory
  44. */
  45. private $klarnaOrderFactory;
  46. /**
  47. * @var OrderRepositoryInterface
  48. */
  49. private $klarnaOrderRepository;
  50. /**
  51. * @var CartRepositoryInterface
  52. */
  53. private $mageQuoteRepository;
  54. /**
  55. * @var QuoteRepositoryInterface
  56. */
  57. private $klarnaQuoteRepository;
  58. /**
  59. * @var CreditApiInterface
  60. */
  61. private $api;
  62. /**
  63. * @var CartRepositoryInterface
  64. */
  65. private $quoteRepository;
  66. /**
  67. * @var \Magento\Sales\Api\OrderRepositoryInterface
  68. */
  69. private $mageOrderRepository;
  70. /**
  71. * Authorize constructor.
  72. *
  73. * @param QuoteRepositoryInterface $klarnaQuoteRepository
  74. * @param CartRepositoryInterface $quoteRepository
  75. * @param CreditApiInterface $api
  76. * @param OrderRepositoryInterface $klarnaOrderRepository
  77. * @param OrderFactory $klarnaOrderFactory
  78. * @param BuilderInterface $builder
  79. * @param \Magento\Sales\Api\OrderRepositoryInterface $mageOrderRepository
  80. * @internal param OrderRepositoryInterface $orderRepository
  81. * @internal param OrderFactory $orderFactory
  82. */
  83. public function __construct(
  84. QuoteRepositoryInterface $klarnaQuoteRepository,
  85. CartRepositoryInterface $quoteRepository,
  86. CreditApiInterface $api,
  87. OrderRepositoryInterface $klarnaOrderRepository,
  88. OrderFactory $klarnaOrderFactory,
  89. BuilderInterface $builder,
  90. \Magento\Sales\Api\OrderRepositoryInterface $mageOrderRepository
  91. ) {
  92. $this->quoteRepository = $quoteRepository;
  93. $this->api = $api;
  94. $this->klarnaQuoteRepository = $klarnaQuoteRepository;
  95. $this->klarnaOrderRepository = $klarnaOrderRepository;
  96. $this->klarnaOrderFactory = $klarnaOrderFactory;
  97. $this->builder = $builder;
  98. $this->mageQuoteRepository = $quoteRepository;
  99. $this->mageOrderRepository = $mageOrderRepository;
  100. }
  101. /**
  102. * Executes command basing on business object
  103. *
  104. * @param array $commandSubject
  105. * @return null|Command\ResultInterface
  106. * @throws \Magento\Framework\Exception\NoSuchEntityException
  107. * @throws \Klarna\Core\Model\Api\Exception
  108. * @throws \Klarna\Core\Exception
  109. * @throws \Magento\Framework\Exception\CouldNotSaveException
  110. * @throws CommandException
  111. */
  112. public function execute(array $commandSubject)
  113. {
  114. /** @var \Magento\Payment\Model\InfoInterface $payment */
  115. $payment = $commandSubject['payment']->getPayment();
  116. /** @var \Magento\Sales\Api\Data\OrderInterface $order */
  117. $order = $payment->getOrder();
  118. $quote = $this->mageQuoteRepository->get($order->getQuoteId());
  119. $klarnaQuote = $this->getKlarnaQuote($quote);
  120. /** @var RequestInterface $data */
  121. $data = $this->builder->setObject($quote)->generateRequest(Builder::GENERATE_TYPE_PLACE)->getRequest();
  122. $authorizationToken = $klarnaQuote->getAuthorizationToken();
  123. $result = $this->getKpApi()->placeOrder($authorizationToken, $data, $klarnaQuote->getSessionId());
  124. if (!$result->isSuccessfull()) {
  125. $response = $this->getKpApi()->cancelOrder($authorizationToken, $klarnaQuote->getSessionId());
  126. if (!$response->isSuccessfull()) {
  127. $message = $response->getMessage()
  128. ?: __('Unable to release authorization for the token %1', $authorizationToken);
  129. throw new \Klarna\Core\Model\Api\Exception($message);
  130. }
  131. throw new \Klarna\Core\Exception(__('Unable to authorize payment for this order.'));
  132. }
  133. switch ($result->getFraudStatus()) {
  134. case self::FRAUD_STATUS_REJECTED:
  135. $payment->setIsFraudDetected(true);
  136. break;
  137. case self::FRAUD_STATUS_PENDING:
  138. $payment->setIsTransactionPending(true);
  139. break;
  140. }
  141. $klarnaOrder = $this->klarnaOrderFactory->create();
  142. $payment->getMethodInstance()->setCode(Kp::METHOD_CODE);
  143. $order->getPayment()->setMethod(Kp::METHOD_CODE);
  144. $this->mageOrderRepository->save($order);
  145. $klarnaOrder->setData([
  146. 'klarna_order_id' => $result->getOrderId(),
  147. 'reservation_id' => $result->getOrderId(),
  148. 'session_id' => $klarnaQuote->getSessionId(),
  149. 'order_id' => $order->getId()
  150. ]);
  151. $this->klarnaOrderRepository->save($klarnaOrder);
  152. if (!$klarnaOrder->getId() || !$klarnaOrder->getReservationId()) {
  153. throw new \Klarna\Core\Exception(__('Unable to authorize payment for this order.'));
  154. }
  155. $payment->setTransactionId($result->getOrderId())->setIsTransactionClosed(0);
  156. return null;
  157. }
  158. /**
  159. * Get Klarna quote for a sales quote
  160. *
  161. * @param CartInterface $quote
  162. *
  163. * @return \Klarna\Kp\Api\QuoteInterface
  164. * @throws \Magento\Framework\Exception\NoSuchEntityException
  165. */
  166. private function getKlarnaQuote(CartInterface $quote)
  167. {
  168. return $this->klarnaQuoteRepository->getActiveByQuote($quote);
  169. }
  170. /**
  171. * Get Klarna payments api class
  172. *
  173. * @return CreditApiInterface
  174. */
  175. private function getKpApi()
  176. {
  177. return $this->api;
  178. }
  179. }