diff --git a/src/Components/PaymentFilter/DefaultPaymentFilterService.php b/src/Components/PaymentFilter/DefaultPaymentFilterService.php index bd2bcea66..646cb690d 100644 --- a/src/Components/PaymentFilter/DefaultPaymentFilterService.php +++ b/src/Components/PaymentFilter/DefaultPaymentFilterService.php @@ -54,7 +54,7 @@ final public function filterPaymentMethods( // Validate and remove all supported payment methods if necessary try { - if ($filterContext->getFlag(PaymentFilterContext::FLAG_SKIP_EC_REQUIRED_DATA_VALIDATION) !== true) { + if ($filterContext->hasFlag(PaymentFilterContext::FLAG_SKIP_EC_REQUIRED_DATA_VALIDATION) !== true) { $this->validateGenericExpressCheckout($filterContext); } $this->validateCurrency($currency); diff --git a/src/Components/PaymentFilter/GenericExpressCheckoutFilterOther.php b/src/Components/PaymentFilter/GenericExpressCheckoutFilterOther.php new file mode 100644 index 000000000..7e4114b5b --- /dev/null +++ b/src/Components/PaymentFilter/GenericExpressCheckoutFilterOther.php @@ -0,0 +1,27 @@ +getSalesChannelContext()->getPaymentMethod(); + + if ($methodCollection->has($actualPaymentMethod->getId()) + && \in_array($actualPaymentMethod->getHandlerIdentifier(), PaymentHandlerGroups::GENERIC_EXPRESS, true) + ) { + return new PaymentMethodCollection([$actualPaymentMethod]); + } + + return $methodCollection; + } +} diff --git a/src/Components/PaymentFilter/PaymentFilterContext.php b/src/Components/PaymentFilter/PaymentFilterContext.php index df2303eba..0a8ac8429 100644 --- a/src/Components/PaymentFilter/PaymentFilterContext.php +++ b/src/Components/PaymentFilter/PaymentFilterContext.php @@ -19,6 +19,9 @@ class PaymentFilterContext extends Struct private bool $_areAddressesIdentical; + /** + * @param string[] $flags + */ public function __construct( private readonly SalesChannelContext $salesChannelContext, private readonly CustomerAddressEntity|OrderAddressEntity|null $billingAddress = null, @@ -87,8 +90,8 @@ public function areAddressesIdentical(): bool return $this->_areAddressesIdentical = true; } - public function getFlag(string $key): bool + public function hasFlag(string $key): bool { - return $this->flags[$key] ?? false; + return \in_array($key, $this->flags, true); } } diff --git a/src/DependencyInjection/controllers.xml b/src/DependencyInjection/controllers.xml index 8408c548b..b646b8ffb 100644 --- a/src/DependencyInjection/controllers.xml +++ b/src/DependencyInjection/controllers.xml @@ -154,5 +154,10 @@ + + + + + diff --git a/src/DependencyInjection/listeners.xml b/src/DependencyInjection/listeners.xml index d3f17d4c6..f5de9d596 100644 --- a/src/DependencyInjection/listeners.xml +++ b/src/DependencyInjection/listeners.xml @@ -124,5 +124,9 @@ + + + + diff --git a/src/DependencyInjection/payment_method_filter.xml b/src/DependencyInjection/payment_method_filter.xml index d576813b7..cb86dc8d0 100644 --- a/src/DependencyInjection/payment_method_filter.xml +++ b/src/DependencyInjection/payment_method_filter.xml @@ -223,5 +223,9 @@ + + + + diff --git a/src/EventListener/CheckoutCartAmazonPayExpressEventListener.php b/src/EventListener/CheckoutCartAmazonPayExpressEventListener.php index b74087021..541ca54bb 100644 --- a/src/EventListener/CheckoutCartAmazonPayExpressEventListener.php +++ b/src/EventListener/CheckoutCartAmazonPayExpressEventListener.php @@ -27,6 +27,7 @@ use Shopware\Core\System\SalesChannel\Aggregate\SalesChannelPaymentMethod\SalesChannelPaymentMethodDefinition; use Shopware\Core\System\SalesChannel\SalesChannelContext; use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent; +use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent; use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -81,7 +82,7 @@ public function onCartLoaded(CheckoutCartPageLoadedEvent|OffcanvasCartPageLoaded currency: $event->getSalesChannelContext()->getCurrency(), cart: $event->getPage()->getCart(), flags: [ - PaymentFilterContext::FLAG_SKIP_EC_REQUIRED_DATA_VALIDATION => true, + PaymentFilterContext::FLAG_SKIP_EC_REQUIRED_DATA_VALIDATION, ] ) ); diff --git a/src/EventListener/CheckoutConfirmGenericExpressCheckoutEventListener.php b/src/EventListener/CheckoutConfirmGenericExpressCheckoutEventListener.php new file mode 100644 index 000000000..fa986be9b --- /dev/null +++ b/src/EventListener/CheckoutConfirmGenericExpressCheckoutEventListener.php @@ -0,0 +1,36 @@ + 'onCheckoutConfirmLoaded', + ]; + } + + public function onCheckoutConfirmLoaded(CheckoutConfirmPageLoadedEvent $event): void + { + $paymentMethod = $event->getSalesChannelContext()->getPaymentMethod(); + if (\in_array($paymentMethod->getHandlerIdentifier(), PaymentHandlerGroups::GENERIC_EXPRESS, true) === false) { + // payment handler is not a generic express-checkout + return; + } + + $extension = $event->getPage()->getExtension(CheckoutConfirmPaymentData::EXTENSION_NAME) ?? new CheckoutConfirmPaymentData(); + $extension->assign([ + 'showExitExpressCheckoutLink' => true, + 'preventAddressEdit' => true, + ]); + $event->getPage()->addExtension(CheckoutConfirmPaymentData::EXTENSION_NAME, $extension); + } +} diff --git a/src/Resources/config/routes.xml b/src/Resources/config/routes.xml index 747a5b090..cee3d197f 100644 --- a/src/Resources/config/routes.xml +++ b/src/Resources/config/routes.xml @@ -20,6 +20,7 @@ + diff --git a/src/Resources/snippet/de_DE/messages.de-DE.json b/src/Resources/snippet/de_DE/messages.de-DE.json index 29eb6ccc8..b8371ac51 100644 --- a/src/Resources/snippet/de_DE/messages.de-DE.json +++ b/src/Resources/snippet/de_DE/messages.de-DE.json @@ -48,7 +48,9 @@ "checkoutConfirmPage": { "defaultCardTitle": "Zahlungsinformationen", "save": "Daten für zukünftige Nutzung speichern", - "saveMandate": "Lastschrift-Mandat für zukünftige Nutzung speichern" + "saveMandate": "Lastschrift-Mandat für zukünftige Nutzung speichern", + "back-to-standard-checkout": "Zahlungsart ändern", + "express-checkout-canceled": "Der Express-Checkout wurde abgebrochen." }, "checkoutFinishPage": { "mandateIdentification": "SEPA-Lastschriftmandat" diff --git a/src/Resources/snippet/en_GB/messages.en-GB.json b/src/Resources/snippet/en_GB/messages.en-GB.json index da635777e..bcb330aa8 100644 --- a/src/Resources/snippet/en_GB/messages.en-GB.json +++ b/src/Resources/snippet/en_GB/messages.en-GB.json @@ -48,7 +48,9 @@ "checkoutConfirmPage": { "defaultCardTitle": "Payment Information", "save": "Save data for future use", - "saveMandate": "Save direct debit mandate for future use" + "saveMandate": "Save direct debit mandate for future use", + "back-to-standard-checkout": "Change payment method", + "express-checkout-canceled": "The express checkout has been cancelled." }, "checkoutFinishPage": { "mandateIdentification": "Direct Debit Mandate" diff --git a/src/Resources/views/storefront/page/checkout/confirm/confirm-address.html.twig b/src/Resources/views/storefront/page/checkout/confirm/confirm-address.html.twig new file mode 100644 index 000000000..c1f6a1034 --- /dev/null +++ b/src/Resources/views/storefront/page/checkout/confirm/confirm-address.html.twig @@ -0,0 +1,13 @@ +{% sw_extends '@Storefront/storefront/page/checkout/confirm/confirm-address.html.twig' %} + +{% block page_checkout_confirm_address_shipping_actions %} + {% if not page.extensions.payone or not page.extensions.payone.preventAddressEdit %} + {{ parent() }} + {% endif %} +{% endblock %} + +{% block page_checkout_confirm_address_billing_actions %} + {% if not page.extensions.payone or not page.extensions.payone.preventAddressEdit %} + {{ parent() }} + {% endif %} +{% endblock %} diff --git a/src/Resources/views/storefront/page/checkout/confirm/confirm-payment.html.twig b/src/Resources/views/storefront/page/checkout/confirm/confirm-payment.html.twig new file mode 100644 index 000000000..b4c99457c --- /dev/null +++ b/src/Resources/views/storefront/page/checkout/confirm/confirm-payment.html.twig @@ -0,0 +1,14 @@ +{% sw_extends '@Storefront/storefront/page/checkout/confirm/confirm-payment.html.twig' %} + +{% block page_checkout_change_payment_form %} + {{ parent() }} + + {% block page_checkout_change_payment_form_payone_back_to_standard_checkout %} + {% if page.extensions.payone and page.extensions.payone.showExitExpressCheckoutLink|default(false) %} + + {% endif %} + {% endblock %} + +{% endblock %} diff --git a/src/Storefront/Controller/CheckoutController.php b/src/Storefront/Controller/CheckoutController.php new file mode 100644 index 000000000..cf90810e7 --- /dev/null +++ b/src/Storefront/Controller/CheckoutController.php @@ -0,0 +1,47 @@ + ['storefront']])] +class CheckoutController +{ + public function __construct( + private readonly CartService $cartService, + private readonly RouterInterface $router, + private readonly TranslatorInterface $translator + ) { + } + + #[Route(path: '/payone/delete-checkout-data', name: 'frontend.payone.delete-checkout-data')] + public function deleteCheckoutData( + Request $request, + SalesChannelContext $salesChannelContext + ): Response { + $cart = $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext); + $cart->removeExtension(CheckoutCartPaymentData::EXTENSION_NAME); + $this->cartService->recalculate($cart, $salesChannelContext); + + $session = $request->getSession(); + if (method_exists($session, 'getFlashBag')) { + $session->getFlashBag()->add( + StorefrontController::SUCCESS, + $this->translator->trans('PayonePayment.checkoutConfirmPage.express-checkout-canceled') + ); + } + + return new RedirectResponse($this->router->generate('frontend.checkout.confirm.page')); + } +} diff --git a/src/Storefront/Struct/CheckoutConfirmPaymentData.php b/src/Storefront/Struct/CheckoutConfirmPaymentData.php index a57de67bb..b06fb94b5 100644 --- a/src/Storefront/Struct/CheckoutConfirmPaymentData.php +++ b/src/Storefront/Struct/CheckoutConfirmPaymentData.php @@ -25,6 +25,10 @@ class CheckoutConfirmPaymentData extends Struct protected ?EntitySearchResult $savedMandates = null; + protected bool $showExitExpressCheckoutLink = false; + + protected bool $preventAddressEdit = false; + public function getCardRequest(): array { return $this->cardRequest; @@ -59,4 +63,14 @@ public function getSavedMandates(): ?EntitySearchResult { return $this->savedMandates; } + + public function isshowExitExpressCheckoutLink(): bool + { + return $this->showExitExpressCheckoutLink; + } + + public function isPreventAddressEdit(): bool + { + return $this->preventAddressEdit; + } }