custom/plugins/MolliePayments/src/Subscriber/PaypalExpressSubscriber.php line 73

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Kiener\MolliePayments\Subscriber;
  4. use Kiener\MolliePayments\Components\PaypalExpress\PayPalExpress;
  5. use Kiener\MolliePayments\Handler\Method\PayPalExpressPayment;
  6. use Kiener\MolliePayments\Service\Cart\CartBackupService;
  7. use Kiener\MolliePayments\Service\CartServiceInterface;
  8. use Kiener\MolliePayments\Service\SettingsService;
  9. use Kiener\MolliePayments\Traits\StringTrait;
  10. use Mollie\Shopware\Entity\Cart\MollieShopwareCart;
  11. use Mollie\Shopware\Entity\Order\MollieShopwareOrder;
  12. use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
  13. use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity;
  14. use Shopware\Core\Checkout\Payment\PaymentMethodEntity;
  15. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  16. use Shopware\Storefront\Event\StorefrontRenderEvent;
  17. use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
  18. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  19. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  20. class PaypalExpressSubscriber implements EventSubscriberInterface
  21. {
  22.     use StringTrait;
  23.     /**
  24.      * @var SettingsService
  25.      */
  26.     private $settingsService;
  27.     /**
  28.      * @var PayPalExpress
  29.      */
  30.     private $paypal;
  31.     /**
  32.      * @var CartService
  33.      */
  34.     private $cartService;
  35.     /**
  36.      * @var CartServiceInterface
  37.      */
  38.     private $mollieCartService;
  39.     /**
  40.      * @var CartBackupService
  41.      */
  42.     private $cartBackupService;
  43.     public function __construct(SettingsService $settingsServicePayPalExpress $paypalCartBackupService $cartBackupServiceCartService $cartServiceCartServiceInterface $mollieCartService)
  44.     {
  45.         $this->settingsService $settingsService;
  46.         $this->paypal $paypal;
  47.         $this->cartBackupService $cartBackupService;
  48.         $this->cartService $cartService;
  49.         $this->mollieCartService $mollieCartService;
  50.     }
  51.     public static function getSubscribedEvents()
  52.     {
  53.         return [
  54.             StorefrontRenderEvent::class => 'onStorefrontRender',
  55.             CheckoutFinishPageLoadedEvent::class => 'onCheckoutSuccess',
  56.             ResponseEvent::class => 'onResetPaypalExpress',
  57.         ];
  58.     }
  59.     /**
  60.      * @throws \Exception
  61.      */
  62.     public function onStorefrontRender(StorefrontRenderEvent $event): void
  63.     {
  64.         $settings $this->settingsService->getSettings($event->getSalesChannelContext()->getSalesChannel()->getId());
  65.         $paymentEnabled $this->isPPEActive($event->getSalesChannelContext());
  66.         $event->setParameter('mollie_paypalexpress_enabled'$paymentEnabled);
  67.         $style $settings->getPaypalExpressButtonStyle();
  68.         $shape $settings->getPaypalExpressButtonShape();
  69.         $restrictions $settings->getPaypalExpressRestrictions();
  70.         $event->setParameter('mollie_paypalexpress_style'$style);
  71.         $event->setParameter('mollie_paypalexpress_shape'$shape);
  72.         $event->setParameter('mollie_paypalexpress_restrictions'$restrictions);
  73.     }
  74.     /**
  75.      * If our apple pay direct payment is done, we want to restore the original cart
  76.      * just in case if the customer had some items in there.
  77.      */
  78.     public function onCheckoutSuccess(CheckoutFinishPageLoadedEvent $event): void
  79.     {
  80.         $mollieShopwareOrder = new MollieShopwareOrder($event->getPage()->getOrder());
  81.         $latestTransaction $mollieShopwareOrder->getLatestTransaction();
  82.         if (! $latestTransaction instanceof OrderTransactionEntity) {
  83.             return;
  84.         }
  85.         $paymentMethod $latestTransaction->getPaymentMethod();
  86.         if (! $paymentMethod instanceof PaymentMethodEntity) {
  87.             return;
  88.         }
  89.         $paymentIdentifier $paymentMethod->getHandlerIdentifier();
  90.         if ($paymentIdentifier !== PayPalExpressPayment::class) {
  91.             return;
  92.         }
  93.         $context $event->getSalesChannelContext();
  94.         if ($this->cartBackupService->isBackupExisting($context)) {
  95.             $this->cartBackupService->clearBackup($context);
  96.         }
  97.     }
  98.     /**
  99.      * If the user is on the PayPal page during the express checkout
  100.      * but somehow gets back to the shop outside of our success/cancel controller actions
  101.      * we need to check if we need to cancel PPE. otherwise the user would be stuck in that process.
  102.      */
  103.     public function onResetPaypalExpress(ResponseEvent $event): void
  104.     {
  105.         $salesChannelContext $event->getRequest()->attributes->get('sw-sales-channel-context');
  106.         if (! $salesChannelContext instanceof SalesChannelContext) {
  107.             return;
  108.         }
  109.         $pathInfo $event->getRequest()->getPathInfo();
  110.         // we must not clear things in our controlled PayPal express process
  111.         if ($this->stringContains($pathInfo'/mollie/paypal-express')) {
  112.             return;
  113.         }
  114.         $paymentEnabled $this->isPPEActive($salesChannelContext);
  115.         // now we need to figure out if the user came back from PayPal express before finalizing the authentication.
  116.         // If so, we need to reset PayPal express, otherwise the user would be stuck in using it
  117.         if (! $paymentEnabled) {
  118.             return;
  119.         }
  120.         $cart $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext);
  121.         $mollieShopwareCart = new MollieShopwareCart($cart);
  122.         // if paypal is either not started or confirmed, then do nothing
  123.         // incomplete means, we have started it, but authorization was not finished
  124.         if (! $mollieShopwareCart->isPayPalExpressIncomplete()) {
  125.             return;
  126.         }
  127.         if ($mollieShopwareCart->isSingleProductExpressCheckout()) {
  128.             // we want to restore our original cart
  129.             $cart $this->cartBackupService->restoreCart($salesChannelContext);
  130.             $this->cartBackupService->clearBackup($salesChannelContext);
  131.             $mollieShopwareCart = new MollieShopwareCart($cart);
  132.         }
  133.         // always make sure that paypal express data is really cleaned
  134.         $mollieShopwareCart->clearPayPalExpress();
  135.         $cart $mollieShopwareCart->getCart();
  136.         $this->mollieCartService->persistCart($cart$salesChannelContext);
  137.     }
  138.     private function isPPEActive(SalesChannelContext $context): bool
  139.     {
  140.         $settings $this->settingsService->getSettings($context->getSalesChannel()->getId());
  141.         if (! $settings->isPaypalExpressEnabled()) {
  142.             return false;
  143.         }
  144.         return $this->paypal->isPaypalExpressPaymentMethodEnabled($context);
  145.     }
  146. }