custom/plugins/KlarnaPayment/src/Components/EventListener/OrderStatusTransitionEventListener.php line 73

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace KlarnaPayment\Components\EventListener;
  4. use KlarnaPayment\Components\Helper\OrderFetcher;
  5. use KlarnaPayment\Components\Helper\OrderValidator\OrderValidatorInterface;
  6. use KlarnaPayment\Components\Helper\StateHelper\Cancel\CancelStateHelper;
  7. use KlarnaPayment\Components\Helper\StateHelper\Capture\CaptureStateHelperInterface;
  8. use KlarnaPayment\Components\Helper\StateHelper\Refund\RefundStateHelperInterface;
  9. use KlarnaPayment\Components\Helper\StateHelper\StateData\StateDataHelper;
  10. use KlarnaPayment\Components\PaymentHandler\AbstractKlarnaPaymentHandler;
  11. use KlarnaPayment\Components\Validator\OrderTransitionChangeValidator;
  12. use KlarnaPayment\Core\Framework\ContextScope;
  13. use KlarnaPayment\Installer\Modules\CustomFieldInstaller;
  14. use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryDefinition;
  15. use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionDefinition;
  16. use Shopware\Core\Checkout\Order\OrderDefinition;
  17. use Shopware\Core\Checkout\Order\OrderEntity;
  18. use Shopware\Core\Framework\Context;
  19. use Shopware\Core\System\StateMachine\Event\StateMachineTransitionEvent;
  20. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  21. class OrderStatusTransitionEventListener implements EventSubscriberInterface
  22. {
  23.     /** @var OrderTransitionChangeValidator */
  24.     private $orderStatusValidator;
  25.     /** @var CaptureStateHelperInterface */
  26.     private $captureStateHelper;
  27.     /** @var RefundStateHelperInterface */
  28.     private $refundStateHelper;
  29.     /** @var OrderFetcher */
  30.     private $orderFetcher;
  31.     /** @var CancelStateHelper */
  32.     private $cancelStateHelper;
  33.     /** @var StateDataHelper */
  34.     private $stateDataHelper;
  35.     /** @var OrderValidatorInterface */
  36.     private $orderValidator;
  37.     public function __construct(
  38.         OrderTransitionChangeValidator $orderStatusValidator,
  39.         CaptureStateHelperInterface $captureStateHelper,
  40.         RefundStateHelperInterface $refundStateHelper,
  41.         CancelStateHelper $cancelStateHelper,
  42.         OrderFetcher $orderFetcher,
  43.         StateDataHelper $stateDataHelper,
  44.         OrderValidatorInterface $orderValidator
  45.     ) {
  46.         $this->orderStatusValidator $orderStatusValidator;
  47.         $this->captureStateHelper   $captureStateHelper;
  48.         $this->refundStateHelper    $refundStateHelper;
  49.         $this->cancelStateHelper    $cancelStateHelper;
  50.         $this->orderFetcher         $orderFetcher;
  51.         $this->stateDataHelper      $stateDataHelper;
  52.         $this->orderValidator       $orderValidator;
  53.     }
  54.     public static function getSubscribedEvents(): array
  55.     {
  56.         return [
  57.             StateMachineTransitionEvent::class => 'onStateMachineTransition',
  58.         ];
  59.     }
  60.     public function onStateMachineTransition(StateMachineTransitionEvent $transitionEvent): void
  61.     {
  62.         $context $transitionEvent->getContext();
  63.         if ($transitionEvent->getContext()->getScope() === ContextScope::INTERNAL_SCOPE) {
  64.             return;
  65.         }
  66.         $order $this->getOrder($transitionEvent$context);
  67.         if (!$order || !$this->orderValidator->isKlarnaOrder($order)) {
  68.             return;
  69.         }
  70.         if ($this->isFraudStatusAccepted($order)
  71.             && $this->orderStatusValidator->isAutomaticCapture(
  72.                 $transitionEvent->getEntityName(),
  73.                 $transitionEvent->getToPlace()->getTechnicalName(),
  74.                 $order->getSalesChannelId(),
  75.                 $transitionEvent->getContext()
  76.             )
  77.         ) {
  78.             $this->captureStateHelper->processOrderCapture($order$context);
  79.         } elseif ($this->orderStatusValidator->isAutomaticRefund($transitionEvent$order->getSalesChannelId())) {
  80.             $this->refundStateHelper->processOrderRefund($order$context);
  81.         }
  82.         if($transitionEvent->getFromPlace()->getId() !== $transitionEvent->getToPlace()->getId()) {
  83.             if ($this->orderStatusValidator->isAutomaticCancel($transitionEvent)) {
  84.                 if ($transitionEvent->getEntityName() === OrderDefinition::ENTITY_NAME) {
  85.                     $this->cancelStateHelper->processOrderCancellation($order$context);
  86.                 } elseif ($transitionEvent->getEntityName() === OrderTransactionDefinition::ENTITY_NAME) {
  87.                     $this->cancelTransaction($order$transitionEvent->getEntityId(), $context);
  88.                 }
  89.             }
  90.         }
  91.     }
  92.     private function isFraudStatusAccepted(OrderEntity $orderEntity): bool
  93.     {
  94.         foreach ($this->stateDataHelper->getValidTransactions($orderEntity) as $transaction) {
  95.             if (is_array($transaction->getCustomFields())
  96.                 && isset($transaction->getCustomFields()[CustomFieldInstaller::FIELD_KLARNA_FRAUD_STATUS])
  97.                 && strtolower($transaction->getCustomFields()[CustomFieldInstaller::FIELD_KLARNA_FRAUD_STATUS]) === strtolower(AbstractKlarnaPaymentHandler::FRAUD_STATUS_ACCEPTED)) {
  98.                 return true;
  99.             }
  100.         }
  101.         return false;
  102.     }
  103.     private function getOrder(StateMachineTransitionEvent $transitionEventContext $context): ?OrderEntity
  104.     {
  105.         if ($transitionEvent->getEntityName() === OrderDefinition::ENTITY_NAME) {
  106.             return $this->orderFetcher->getOrderFromOrder($transitionEvent->getEntityId(), $context);
  107.         }
  108.         if ($transitionEvent->getEntityName() === OrderDeliveryDefinition::ENTITY_NAME) {
  109.             return $this->orderFetcher->getOrderFromOrderDelivery($transitionEvent->getEntityId(), $context);
  110.         }
  111.         if ($transitionEvent->getEntityName() === OrderTransactionDefinition::ENTITY_NAME) {
  112.             return $this->orderFetcher->getOrderFromOrderTransaction($transitionEvent->getEntityId(), $context);
  113.         }
  114.         return null;
  115.     }
  116.     private function cancelTransaction(OrderEntity $orderstring $transactionIdContext $context): void
  117.     {
  118.         if ($order->getTransactions() === null) {
  119.             return;
  120.         }
  121.         $transaction $order->getTransactions()->get($transactionId);
  122.         if ($transaction === null) {
  123.             return;
  124.         }
  125.         $this->cancelStateHelper->processOrderTransactionCancellation($transaction$order$context);
  126.     }
  127. }