From f873f4fd4b3e80c52f4d2aa570c5c930c3a394c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20M=C3=BCller?= Date: Tue, 30 Jan 2024 20:52:12 +0100 Subject: [PATCH 1/2] Improve payment filter to skip filter services if they not support one of the active payment methods --- .../DefaultPaymentFilterService.php | 28 +++++++++---------- .../KlarnaPaymentMethodFilter.php | 7 ++++- .../PayoneBNPLPaymentMethodFilter.php | 9 ++++-- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/Components/PaymentFilter/DefaultPaymentFilterService.php b/src/Components/PaymentFilter/DefaultPaymentFilterService.php index 3dc876dfe..fafee1c61 100644 --- a/src/Components/PaymentFilter/DefaultPaymentFilterService.php +++ b/src/Components/PaymentFilter/DefaultPaymentFilterService.php @@ -31,6 +31,11 @@ public function filterPaymentMethods( PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext ): PaymentMethodCollection { + $supportedPaymentMethods = $this->getSupportedPaymentMethods($methodCollection); + if ($supportedPaymentMethods->count() === 0) { + return $methodCollection; + } + $currency = $filterContext->getCurrency(); $billingAddress = $filterContext->getBillingAddress(); @@ -50,31 +55,26 @@ public function filterPaymentMethods( $this->validateMaxValue($currentValue); } } catch (PaymentMethodNotAllowedException) { - $methodCollection = $this->removePaymentMethod($methodCollection); + $methodCollection = $this->removePaymentMethods($methodCollection, $supportedPaymentMethods); } 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 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 - { - $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)); + protected function removePaymentMethods( + PaymentMethodCollection $paymentMethodCollection, + PaymentMethodCollection $toBeRemoved + ): PaymentMethodCollection { + return $paymentMethodCollection->filter(static fn (PaymentMethodEntity $entity) => !$toBeRemoved->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..fa7e3a15e 100644 --- a/src/Components/PaymentFilter/KlarnaPaymentMethodFilter.php +++ b/src/Components/PaymentFilter/KlarnaPaymentMethodFilter.php @@ -14,8 +14,13 @@ public function filterPaymentMethods(PaymentMethodCollection $methodCollection, { $methodCollection = parent::filterPaymentMethods($methodCollection, $filterContext); + $supportedPaymentMethods = $this->getSupportedPaymentMethods($methodCollection); + if ($supportedPaymentMethods->count() === 0) { + return $methodCollection; + } + if ($this->hasCustomProducts($filterContext)) { - $methodCollection = $this->removePaymentMethod($methodCollection); + $methodCollection = $this->removePaymentMethods($methodCollection, $supportedPaymentMethods); } return $methodCollection; diff --git a/src/Components/PaymentFilter/PayoneBNPLPaymentMethodFilter.php b/src/Components/PaymentFilter/PayoneBNPLPaymentMethodFilter.php index fdbb85d5c..f9289e86c 100644 --- a/src/Components/PaymentFilter/PayoneBNPLPaymentMethodFilter.php +++ b/src/Components/PaymentFilter/PayoneBNPLPaymentMethodFilter.php @@ -15,6 +15,11 @@ public function filterPaymentMethods(PaymentMethodCollection $methodCollection, { $methodCollection = parent::filterPaymentMethods($methodCollection, $filterContext); + $supportedPaymentMethods = $this->getSupportedPaymentMethods($methodCollection); + if ($supportedPaymentMethods->count() === 0) { + return $methodCollection; + } + $billingAddress = $filterContext->getBillingAddress(); $shippingAddress = $filterContext->getShippingAddress(); @@ -22,11 +27,11 @@ public function filterPaymentMethods(PaymentMethodCollection $methodCollection, if ($billingAddress instanceof OrderAddressEntity && $shippingAddress instanceof OrderAddressEntity && !AddressCompare::areOrderAddressesIdentical($billingAddress, $shippingAddress)) { - $methodCollection = $this->removePaymentMethod($methodCollection); + $methodCollection = $this->removePaymentMethods($methodCollection, $supportedPaymentMethods); } elseif ($billingAddress instanceof CustomerAddressEntity && $shippingAddress instanceof CustomerAddressEntity && !AddressCompare::areCustomerAddressesIdentical($billingAddress, $shippingAddress)) { - $methodCollection = $this->removePaymentMethod($methodCollection); + $methodCollection = $this->removePaymentMethods($methodCollection, $supportedPaymentMethods); } return $methodCollection; From ea282289b4395aa71e8a7808de766334758c67e8 Mon Sep 17 00:00:00 2001 From: Frederik Rommel Date: Mon, 5 Feb 2024 20:49:51 +0100 Subject: [PATCH 2/2] PAYOSWXP-113: Improve payment filter to skip filter services if they not support one of the active payment methods --- .../DefaultPaymentFilterService.php | 26 ++++++++++++------- .../KlarnaPaymentMethodFilter.php | 14 +++------- .../PayoneBNPLPaymentMethodFilter.php | 17 +++--------- 3 files changed, 23 insertions(+), 34 deletions(-) diff --git a/src/Components/PaymentFilter/DefaultPaymentFilterService.php b/src/Components/PaymentFilter/DefaultPaymentFilterService.php index fafee1c61..38af3d68f 100644 --- a/src/Components/PaymentFilter/DefaultPaymentFilterService.php +++ b/src/Components/PaymentFilter/DefaultPaymentFilterService.php @@ -27,12 +27,11 @@ public function __construct( ) { } - public function filterPaymentMethods( + final public function filterPaymentMethods( PaymentMethodCollection $methodCollection, PaymentFilterContext $filterContext ): PaymentMethodCollection { - $supportedPaymentMethods = $this->getSupportedPaymentMethods($methodCollection); - if ($supportedPaymentMethods->count() === 0) { + if ($this->getSupportedPaymentMethods($methodCollection)->getElements() === []) { return $methodCollection; } @@ -54,14 +53,21 @@ public function filterPaymentMethods( $this->validateMinValue($currentValue); $this->validateMaxValue($currentValue); } + $this->additionalChecks($methodCollection, $filterContext); } catch (PaymentMethodNotAllowedException) { - $methodCollection = $this->removePaymentMethods($methodCollection, $supportedPaymentMethods); + $methodCollection = $this->removePaymentMethods($methodCollection); } return $methodCollection; } - protected function getSupportedPaymentMethods(PaymentMethodCollection $paymentMethodCollection): PaymentMethodCollection + protected function additionalChecks( + PaymentMethodCollection $methodCollection, + PaymentFilterContext $filterContext + ): void { + } + + private function getSupportedPaymentMethods(PaymentMethodCollection $paymentMethodCollection): PaymentMethodCollection { $refClass = new \ReflectionClass($this->paymentHandlerClass); @@ -70,11 +76,11 @@ protected function getSupportedPaymentMethods(PaymentMethodCollection $paymentMe : $paymentMethod->getHandlerIdentifier() === $this->paymentHandlerClass); } - protected function removePaymentMethods( - PaymentMethodCollection $paymentMethodCollection, - PaymentMethodCollection $toBeRemoved - ): PaymentMethodCollection { - return $paymentMethodCollection->filter(static fn (PaymentMethodEntity $entity) => !$toBeRemoved->has($entity->getUniqueIdentifier())); + private function removePaymentMethods(PaymentMethodCollection $paymentMethodCollection): PaymentMethodCollection + { + $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 fa7e3a15e..e81dd0bdb 100644 --- a/src/Components/PaymentFilter/KlarnaPaymentMethodFilter.php +++ b/src/Components/PaymentFilter/KlarnaPaymentMethodFilter.php @@ -4,26 +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); - - $supportedPaymentMethods = $this->getSupportedPaymentMethods($methodCollection); - if ($supportedPaymentMethods->count() === 0) { - return $methodCollection; - } - if ($this->hasCustomProducts($filterContext)) { - $methodCollection = $this->removePaymentMethods($methodCollection, $supportedPaymentMethods); + 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 f9289e86c..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,29 +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); - - $supportedPaymentMethods = $this->getSupportedPaymentMethods($methodCollection); - if ($supportedPaymentMethods->count() === 0) { - return $methodCollection; - } - $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->removePaymentMethods($methodCollection, $supportedPaymentMethods); + 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->removePaymentMethods($methodCollection, $supportedPaymentMethods); + throw new PaymentMethodNotAllowedException('Different billing and shipping addresses are not allowed for secured invoice'); } - - return $methodCollection; } }