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

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