diff --git a/src/Components/PaymentFilter/DefaultPaymentFilterService.php b/src/Components/PaymentFilter/DefaultPaymentFilterService.php index 3dc876dfe..38af3d68f 100644 --- a/src/Components/PaymentFilter/DefaultPaymentFilterService.php +++ b/src/Components/PaymentFilter/DefaultPaymentFilterService.php @@ -27,10 +27,14 @@ public function __construct( ) { } - public function filterPaymentMethods( + final public function filterPaymentMethods( PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext ): PaymentMethodCollection { + if ($this->getSupportedPaymentMethods($methodCollection)->getElements() === []) { + return $methodCollection; + } + $currency = $filterContext->getCurrency(); $billingAddress = $filterContext->getBillingAddress(); @@ -49,32 +53,34 @@ public function filterPaymentMethods( $this->validateMinValue($currentValue); $this->validateMaxValue($currentValue); } + $this->additionalChecks($methodCollection, $filterContext); } catch (PaymentMethodNotAllowedException) { - $methodCollection = $this->removePaymentMethod($methodCollection); + $methodCollection = $this->removePaymentMethods($methodCollection); } return $methodCollection; } - /** - * returns true, if the method should be filtered out. - * - * @internal method needs to be public, so it can be called by `removePaymentMethod` - */ - public function canMethodRemoved(PaymentMethodEntity $paymentMethod): bool + protected function additionalChecks( + PaymentMethodCollection $methodCollection, + PaymentFilterContext $filterContext + ): void { + } + + private function getSupportedPaymentMethods(PaymentMethodCollection $paymentMethodCollection): PaymentMethodCollection { $refClass = new \ReflectionClass($this->paymentHandlerClass); - return $refClass->isAbstract() + return $paymentMethodCollection->filter(fn (PaymentMethodEntity $paymentMethod) => $refClass->isAbstract() ? is_subclass_of($paymentMethod->getHandlerIdentifier(), $this->paymentHandlerClass) - : $paymentMethod->getHandlerIdentifier() === $this->paymentHandlerClass; + : $paymentMethod->getHandlerIdentifier() === $this->paymentHandlerClass); } - protected function removePaymentMethod(PaymentMethodCollection $paymentMethodCollection): PaymentMethodCollection + private function removePaymentMethods(PaymentMethodCollection $paymentMethodCollection): PaymentMethodCollection { - $that = $this; - // filter-method needs a closure (forced anonymous function) so we can not use [$this, 'filterMethod'] - return $paymentMethodCollection->filter(static fn (PaymentMethodEntity $entity) => !$that->canMethodRemoved($entity)); + $itemsToRemove = $this->getSupportedPaymentMethods($paymentMethodCollection); + + return $paymentMethodCollection->filter(static fn (PaymentMethodEntity $entity) => !$itemsToRemove->has($entity->getUniqueIdentifier())); } private function validateAddress(CustomerAddressEntity|OrderAddressEntity|null $address): void diff --git a/src/Components/PaymentFilter/KlarnaPaymentMethodFilter.php b/src/Components/PaymentFilter/KlarnaPaymentMethodFilter.php index 534149d8a..e81dd0bdb 100644 --- a/src/Components/PaymentFilter/KlarnaPaymentMethodFilter.php +++ b/src/Components/PaymentFilter/KlarnaPaymentMethodFilter.php @@ -4,21 +4,18 @@ namespace PayonePayment\Components\PaymentFilter; +use PayonePayment\Components\PaymentFilter\Exception\PaymentMethodNotAllowedException; use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection; use Shopware\Core\Checkout\Payment\PaymentMethodCollection; use Swag\CustomizedProducts\Core\Checkout\CustomizedProductsCartDataCollector; class KlarnaPaymentMethodFilter extends DefaultPaymentFilterService { - public function filterPaymentMethods(PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext): PaymentMethodCollection + protected function additionalChecks(PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext): void { - $methodCollection = parent::filterPaymentMethods($methodCollection, $filterContext); - if ($this->hasCustomProducts($filterContext)) { - $methodCollection = $this->removePaymentMethod($methodCollection); + throw new PaymentMethodNotAllowedException('PAYONE does not support custom products within Klarna payments'); } - - return $methodCollection; } private function hasCustomProducts(PaymentFilterContext $filterContext): bool diff --git a/src/Components/PaymentFilter/PayoneBNPLPaymentMethodFilter.php b/src/Components/PaymentFilter/PayoneBNPLPaymentMethodFilter.php index fdbb85d5c..21f9a60ca 100644 --- a/src/Components/PaymentFilter/PayoneBNPLPaymentMethodFilter.php +++ b/src/Components/PaymentFilter/PayoneBNPLPaymentMethodFilter.php @@ -4,6 +4,7 @@ namespace PayonePayment\Components\PaymentFilter; +use PayonePayment\Components\PaymentFilter\Exception\PaymentMethodNotAllowedException; use PayonePayment\Core\Utils\AddressCompare; use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressEntity; use Shopware\Core\Checkout\Order\Aggregate\OrderAddress\OrderAddressEntity; @@ -11,24 +12,19 @@ class PayoneBNPLPaymentMethodFilter extends DefaultPaymentFilterService { - public function filterPaymentMethods(PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext): PaymentMethodCollection + protected function additionalChecks(PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext): void { - $methodCollection = parent::filterPaymentMethods($methodCollection, $filterContext); - $billingAddress = $filterContext->getBillingAddress(); $shippingAddress = $filterContext->getShippingAddress(); - // Different billing and shipping addresses are not allowed for secured invoice if ($billingAddress instanceof OrderAddressEntity && $shippingAddress instanceof OrderAddressEntity && !AddressCompare::areOrderAddressesIdentical($billingAddress, $shippingAddress)) { - $methodCollection = $this->removePaymentMethod($methodCollection); + throw new PaymentMethodNotAllowedException('Different billing and shipping addresses are not allowed for secured invoice'); } elseif ($billingAddress instanceof CustomerAddressEntity && $shippingAddress instanceof CustomerAddressEntity && !AddressCompare::areCustomerAddressesIdentical($billingAddress, $shippingAddress)) { - $methodCollection = $this->removePaymentMethod($methodCollection); + throw new PaymentMethodNotAllowedException('Different billing and shipping addresses are not allowed for secured invoice'); } - - return $methodCollection; } }