vendor/shopware/storefront/Checkout/Payment/BlockedPaymentMethodSwitcher.php line 36

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Storefront\Checkout\Payment;
  3. use Shopware\Core\Checkout\Cart\Cart;
  4. use Shopware\Core\Checkout\Cart\Error\Error;
  5. use Shopware\Core\Checkout\Cart\Error\ErrorCollection;
  6. use Shopware\Core\Checkout\Payment\Cart\Error\PaymentMethodBlockedError;
  7. use Shopware\Core\Checkout\Payment\PaymentMethodEntity;
  8. use Shopware\Core\Checkout\Payment\SalesChannel\AbstractPaymentMethodRoute;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NandFilter;
  12. use Shopware\Core\Framework\Log\Package;
  13. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  14. use Shopware\Storefront\Checkout\Cart\Error\PaymentMethodChangedError;
  15. use Symfony\Component\HttpFoundation\Request;
  16. /**
  17.  * @internal Only to be used by the Storefront
  18.  */
  19. #[Package('checkout')]
  20. class BlockedPaymentMethodSwitcher
  21. {
  22.     public function __construct(private readonly AbstractPaymentMethodRoute $paymentMethodRoute)
  23.     {
  24.     }
  25.     public function switch(ErrorCollection $errorsSalesChannelContext $salesChannelContext): PaymentMethodEntity
  26.     {
  27.         $originalPaymentMethod $salesChannelContext->getPaymentMethod();
  28.         if (!$this->paymentMethodBlocked($errors)) {
  29.             return $originalPaymentMethod;
  30.         }
  31.         $paymentMethod $this->getPaymentMethodToChangeTo($errors$salesChannelContext);
  32.         if ($paymentMethod === null) {
  33.             return $originalPaymentMethod;
  34.         }
  35.         $this->addNoticeToCart($errors$paymentMethod);
  36.         return $paymentMethod;
  37.     }
  38.     private function paymentMethodBlocked(ErrorCollection $errors): bool
  39.     {
  40.         foreach ($errors as $error) {
  41.             if ($error instanceof PaymentMethodBlockedError) {
  42.                 return true;
  43.             }
  44.         }
  45.         return false;
  46.     }
  47.     private function getPaymentMethodToChangeTo(ErrorCollection $errorsSalesChannelContext $salesChannelContext): ?PaymentMethodEntity
  48.     {
  49.         $blockedPaymentMethodNames $errors->fmap(static fn (Error $error) => $error instanceof PaymentMethodBlockedError $error->getName() : null);
  50.         $request = new Request(['onlyAvailable' => true]);
  51.         $defaultPaymentMethod $this->paymentMethodRoute->load(
  52.             $request,
  53.             $salesChannelContext,
  54.             new Criteria([$salesChannelContext->getSalesChannel()->getPaymentMethodId()])
  55.         )->getPaymentMethods()->first();
  56.         if ($defaultPaymentMethod !== null && !\in_array($defaultPaymentMethod->getName(), $blockedPaymentMethodNamestrue)) {
  57.             return $defaultPaymentMethod;
  58.         }
  59.         $criteria = new Criteria();
  60.         $criteria->addFilter(
  61.             new NandFilter([
  62.                 new EqualsAnyFilter('name'$blockedPaymentMethodNames),
  63.             ])
  64.         );
  65.         return $this->paymentMethodRoute->load(
  66.             $request,
  67.             $salesChannelContext,
  68.             $criteria
  69.         )->getPaymentMethods()->first();
  70.     }
  71.     private function addNoticeToCart(ErrorCollection $cartErrorsPaymentMethodEntity $paymentMethod): void
  72.     {
  73.         $newPaymentMethodName $paymentMethod->getTranslation('name');
  74.         if ($newPaymentMethodName === null) {
  75.             return;
  76.         }
  77.         foreach ($cartErrors as $error) {
  78.             if (!$error instanceof PaymentMethodBlockedError) {
  79.                 continue;
  80.             }
  81.             // Exchange cart blocked warning with notice
  82.             $cartErrors->remove($error->getId());
  83.             $cartErrors->add(new PaymentMethodChangedError(
  84.                 $error->getName(),
  85.                 $newPaymentMethodName
  86.             ));
  87.         }
  88.     }
  89. }