custom/plugins/MolliePayments/src/Subscriber/CancelOrderSubscriber.php line 88

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Kiener\MolliePayments\Subscriber;
  3. use Kiener\MolliePayments\Factory\MollieApiFactory;
  4. use Kiener\MolliePayments\Service\OrderService;
  5. use Kiener\MolliePayments\Service\SettingsService;
  6. use Kiener\MolliePayments\Struct\Order\OrderAttributes;
  7. use Mollie\Api\Exceptions\ApiException;
  8. use Mollie\Api\MollieApiClient;
  9. use Mollie\Api\Types\OrderStatus;
  10. use Psr\Log\LoggerInterface;
  11. use Shopware\Core\System\StateMachine\Aggregation\StateMachineTransition\StateMachineTransitionActions;
  12. use Shopware\Core\System\StateMachine\Event\StateMachineStateChangeEvent;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. class CancelOrderSubscriber implements EventSubscriberInterface
  15. {
  16.     /**
  17.      * These Shopware actions will automatically trigger
  18.      * our cancellation (if enabled in the config).
  19.      */
  20.     public const AUTOMATIC_TRIGGER_ACTIONS = [
  21.         StateMachineTransitionActions::ACTION_CANCEL
  22.     ];
  23.     /**
  24.      * Cancellations are only done for these Mollie states.
  25.      */
  26.     public const ALLOWED_CANCELLABLE_MOLLIE_STATES = [
  27.         OrderStatus::STATUS_CREATED,
  28.         OrderStatus::STATUS_AUTHORIZED,
  29.         OrderStatus::STATUS_SHIPPING
  30.     ];
  31.     /**
  32.      * @var OrderService
  33.      */
  34.     private $orderService;
  35.     /**
  36.      * @var MollieApiFactory
  37.      */
  38.     private $apiFactory;
  39.     /**
  40.      * @var SettingsService
  41.      */
  42.     private $settingsService;
  43.     /**
  44.      * @var LoggerInterface
  45.      */
  46.     private $logger;
  47.     /**
  48.      * @param MollieApiFactory $apiFactory
  49.      * @param OrderService $orderService
  50.      * @param SettingsService $settingsService
  51.      * @param LoggerInterface $loggerService
  52.      */
  53.     public function __construct(MollieApiFactory $apiFactoryOrderService $orderServiceSettingsService $settingsServiceLoggerInterface $loggerService)
  54.     {
  55.         $this->orderService $orderService;
  56.         $this->apiFactory $apiFactory;
  57.         $this->settingsService $settingsService;
  58.         $this->logger $loggerService;
  59.     }
  60.     /**
  61.      * @return array<mixed>
  62.      */
  63.     public static function getSubscribedEvents(): array
  64.     {
  65.         return [
  66.             'state_machine.order.state_changed' => ['onOrderStateChanges']
  67.         ];
  68.     }
  69.     /**
  70.      * @param StateMachineStateChangeEvent $event
  71.      * @return void
  72.      */
  73.     public function onOrderStateChanges(StateMachineStateChangeEvent $event): void
  74.     {
  75.         if ($event->getTransitionSide() !== StateMachineStateChangeEvent::STATE_MACHINE_TRANSITION_SIDE_ENTER) {
  76.             return;
  77.         }
  78.         $transitionName $event->getTransition()->getTransitionName();
  79.         try {
  80.             # if we don't have at least one of our
  81.             # actions that automatically trigger this feature, continue
  82.             if (!in_array($transitionNameself::AUTOMATIC_TRIGGER_ACTIONStrue)) {
  83.                 return;
  84.             }
  85.             # get order and extract our Mollie Order ID
  86.             $order $this->orderService->getOrder($event->getTransition()->getEntityId(), $event->getContext());
  87.             # -----------------------------------------------------------------------------------------------------------------------
  88.             # check if we have activated this feature in our plugin configuration
  89.             $settings $this->settingsService->getSettings($order->getSalesChannelId());
  90.             if (!$settings->isAutomaticCancellation()) {
  91.                 return;
  92.             }
  93.             # -----------------------------------------------------------------------------------------------------------------------
  94.             $orderAttributes = new OrderAttributes($order);
  95.             $mollieOrderId $orderAttributes->getMollieOrderId();
  96.             # if we don't have a Mollie Order ID continue
  97.             # this can also happen for subscriptions where we only have a tr_xxx Transaction ID.
  98.             # but cancellation only works on orders anyway
  99.             if (empty($mollieOrderId)) {
  100.                 return;
  101.             }
  102.             # -----------------------------------------------------------------------------------------------------------------------
  103.             $apiClient $this->apiFactory->getClient($order->getSalesChannelId());
  104.             $mollieOrder $apiClient->orders->get($mollieOrderId);
  105.             # check if the status of the Mollie order allows
  106.             # a cancellation based on our whitelist.
  107.             if (in_array($mollieOrder->statusself::ALLOWED_CANCELLABLE_MOLLIE_STATEStrue)) {
  108.                 $this->logger->debug('Starting auto-cancellation of order: ' $order->getOrderNumber() . ', ' $mollieOrderId);
  109.                 $apiClient->orders->cancel($mollieOrderId);
  110.                 $this->logger->info('Auto-cancellation of order: ' $order->getOrderNumber() . ', ' $mollieOrderId ' successfully executed after transition: ' $transitionName);
  111.             }
  112.         } catch (ApiException $e) {
  113.             $this->logger->error(
  114.                 'Error when executing auto-cancellation of an order after transition: ' $transitionName,
  115.                 [
  116.                     'error' => $e,
  117.                 ]
  118.             );
  119.         }
  120.     }
  121. }