diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a78abc..009ca1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ -# 6.2.2 -- Fixed issue with payment method availability rules being ignored +# 6.2.3 +- Fix issue with cart clearing on payment method change +- Fixed issue with missing payment methods # 6.2.1 - Fixed issue with multiple discount codes diff --git a/CHANGELOG_de-DE.md b/CHANGELOG_de-DE.md index d0048d7..8322f5d 100644 --- a/CHANGELOG_de-DE.md +++ b/CHANGELOG_de-DE.md @@ -1,5 +1,6 @@ -# 6.2.2 -- Problem behoben, bei dem die Verfügbarkeitsregeln für Zahlungsmethoden ignoriert wurden +# 6.2.3 +- Problem mit dem Leeren des Warenkorbs bei Änderung der Zahlungsmethode behoben +- Problem mit fehlenden Zahlungsmethoden behoben # 6.2.1 - Problem mit mehreren Rabattcodes behoben diff --git a/README.md b/README.md index 018b201..ea90e37 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,10 @@ The VR Payment Payment Plugin integrates modern payment processing into Shopware - **VR Payment Account:** Obtain `Space ID`, `User ID`, and `API Key` from the [VR Payment Dashboard](https://gateway.vr-payment.de/). ## Documentation -- For English documentation click [here](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.2/docs/en/documentation.html) -- Für die deutsche Dokumentation klicken Sie [hier](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.2/docs/de/documentation.html) -- Pour la documentation Française, cliquez [ici](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.2/docs/fr/documentation.html) -- Per la documentazione in tedesco, clicca [qui](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.2/docs/it/documentation.html) +- For English documentation click [here](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.3/docs/en/documentation.html) +- Für die deutsche Dokumentation klicken Sie [hier](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.3/docs/de/documentation.html) +- Pour la documentation Française, cliquez [ici](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.3/docs/fr/documentation.html) +- Per la documentazione in tedesco, clicca [qui](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.3/docs/it/documentation.html) ## Installation @@ -82,7 +82,7 @@ Configure supported methods (e.g., credit cards, Apple Pay) via the [VR Payment ___________________________________________________________________________________ | Shopware 6 version | Plugin major version | Supported until | |-------------------------------|------------------------|------------------------| -| Shopware 6.6.x | 6.x | December 2026 | +| Shopware 6.6.x | 6.x | Further notice | | Shopware 6.5.x | 5.x | October 2024 | ----------------------------------------------------------------------------------- diff --git a/composer.json b/composer.json index e8fb8e3..f2d3c09 100644 --- a/composer.json +++ b/composer.json @@ -59,5 +59,5 @@ "vrpayment/sdk": "^4.0.0" }, "type": "shopware-platform-plugin", - "version": "6.2.2" + "version": "6.2.3" } diff --git a/src/Core/Api/PaymentMethodConfiguration/Service/PaymentMethodConfigurationService.php b/src/Core/Api/PaymentMethodConfiguration/Service/PaymentMethodConfigurationService.php index 11df089..09dc7c2 100644 --- a/src/Core/Api/PaymentMethodConfiguration/Service/PaymentMethodConfigurationService.php +++ b/src/Core/Api/PaymentMethodConfiguration/Service/PaymentMethodConfigurationService.php @@ -684,6 +684,13 @@ class PaymentMethodConfigurationService { ], $context); // Media insert/update + + // detect if collision, return existing id + $existingId = $this->checkMediaAlreadyExists($paymentMethodConfiguration->getResolvedImageUrl(), $context); + if ($existingId) { + return $existingId; + } + $mediaDefinition = $this->container->get(MediaDefinition::class); $this->mediaSerializer->setRegistry($this->serializerRegistry); @@ -704,6 +711,32 @@ class PaymentMethodConfigurationService { } } + /** + * Check if the payment method icon is already uploaded. + * + * @param string $paymentMethodUrl + * @param \Shopware\Core\Framework\Context $context + * + * @return string|bool + */ + private function checkMediaAlreadyExists($paymentMethodUrl, $context) { + // detect if collision, return existing id + if (!preg_match('#/([^/]+)\.[^/.]+$#', $paymentMethodUrl, $matches)) { + return false; + } + $filename = $matches[1]; + + $criteria = new Criteria(); + $criteria->addFilter(new EqualsFilter('fileName', $filename)); + + $existing = $this->mediaRepository->search($criteria, $context)->first(); + + if ($existing) { + return $existing->getId(); + } + return false; + } + /** * Retrieves media default folder for a given payment method configuration. * diff --git a/src/Core/Api/Transaction/Service/TransactionService.php b/src/Core/Api/Transaction/Service/TransactionService.php index dff1ff1..6963e62 100644 --- a/src/Core/Api/Transaction/Service/TransactionService.php +++ b/src/Core/Api/Transaction/Service/TransactionService.php @@ -609,13 +609,10 @@ class TransactionService $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://'; $homeUrl = $protocol . $_SERVER['HTTP_HOST']; $currency = $salesChannelContext->getCurrency()->getIsoCode(); - $language = $this->localeCodeProvider->getLocaleCodeFromContext($salesChannelContext->getContext()); - $transactionPayload = (new TransactionCreate()) ->setBillingAddress($billingAddress) ->setLineItems($lineItems) ->setCurrency($currency) - ->setLanguage($language) ->setSpaceViewId($settings->getSpaceViewId()) ->setAutoConfirmationEnabled(false) ->setChargeRetryEnabled(false) @@ -664,10 +661,7 @@ class TransactionService $billingAddress->setOrganizationName($customerBillingAddress->getCompany()); $currency = $salesChannelContext->getCurrency()->getIsoCode(); - $language = $this->localeCodeProvider->getLocaleCodeFromContext($salesChannelContext->getContext()); - $pendingTransaction->setCurrency($currency); - $pendingTransaction->setLanguage($language); $pendingTransaction->setBillingAddress($billingAddress); $settings->getApiClient()->getTransactionService() diff --git a/src/Core/Api/WebHooks/Controller/WebHookController.php b/src/Core/Api/WebHooks/Controller/WebHookController.php index dc2c0a2..5c92ad6 100644 --- a/src/Core/Api/WebHooks/Controller/WebHookController.php +++ b/src/Core/Api/WebHooks/Controller/WebHookController.php @@ -698,16 +698,6 @@ class WebHookController extends AbstractController { private function unholdAndCancelDelivery(string $orderId, Context $context): void { $order = $this->getOrderEntity($orderId, $context); - try { - $this->orderService->orderStateTransition( - $order->getId(), - StateMachineTransitionActions::ACTION_CANCEL, - new ParameterBag(), - $context - ); - } catch (\Exception $exception) { - $this->logger->info($exception->getMessage(), $exception->getTrace()); - } try { /** diff --git a/src/Core/Api/WebHooks/Strategy/WebHookStrategyBase.php b/src/Core/Api/WebHooks/Strategy/WebHookStrategyBase.php index e77e898..3c29cd2 100644 --- a/src/Core/Api/WebHooks/Strategy/WebHookStrategyBase.php +++ b/src/Core/Api/WebHooks/Strategy/WebHookStrategyBase.php @@ -378,16 +378,6 @@ abstract class WebHookStrategyBase implements WebHookStrategyInterface { protected function unholdAndCancelDelivery(string $orderId, Context $context): void { $order = $this->getOrderEntity($orderId, $context); - try { - $this->orderService->orderStateTransition( - $order->getId(), - StateMachineTransitionActions::ACTION_CANCEL, - new ParameterBag(), - $context - ); - } catch (\Exception $exception) { - $this->logger->info($exception->getMessage(), $exception->getTrace()); - } try { diff --git a/src/Core/Storefront/Checkout/Controller/CheckoutController.php b/src/Core/Storefront/Checkout/Controller/CheckoutController.php index c4d0d1e..d142f16 100644 --- a/src/Core/Storefront/Checkout/Controller/CheckoutController.php +++ b/src/Core/Storefront/Checkout/Controller/CheckoutController.php @@ -55,7 +55,6 @@ use VRPaymentPayment\Core\{ Settings\Options\Integration, Settings\Service\SettingsService, Storefront\Checkout\Struct\CheckoutPageData, - Util\LocaleCodeProvider, Util\Payload\CustomProducts\CustomProductsLineItemTypes, Util\Payload\TransactionPayload }; @@ -127,11 +126,6 @@ class CheckoutController extends StorefrontController { */ private CacheItemPoolInterface $cache; - /** - * @var LocaleCodeProvider - */ - private LocaleCodeProvider $localeCodeProvider; - /** * PaymentController constructor. * @@ -154,8 +148,7 @@ class CheckoutController extends StorefrontController { AbstractOrderRoute $orderRoute, OrderTransactionStateHandler $orderTransactionStateHandler, StateMachineRegistry $stateMachineRegistry, - ParameterBagInterface $params, - LocaleCodeProvider $localeCodeProvider + ParameterBagInterface $params ) { $this->cartService = $cartService; @@ -167,7 +160,6 @@ class CheckoutController extends StorefrontController { $this->orderTransactionStateHandler = $orderTransactionStateHandler; $this->stateMachineRegistry = $stateMachineRegistry; $this->cache = new FilesystemAdapter('vrpayment', 0, rtrim($params->get('kernel.cache_dir'), '/') . '/vrpayment-cache'); - $this->localeCodeProvider = $localeCodeProvider; } /** @@ -251,9 +243,7 @@ class CheckoutController extends StorefrontController { return $this->redirect($recreateCartUrl, Response::HTTP_MOVED_PERMANENTLY); } - $localeCode = $this->localeCodeProvider->getLocaleCodeFromContext($salesChannelContext->getContext()); - $paymentPageLocale = $this->localeCodeProvider->mapToPaymentPageLocale($localeCode); - $javascriptUrl = $this->getTransactionJavaScriptUrl($transaction->getId(), $paymentPageLocale); + $javascriptUrl = $this->getTransactionJavaScriptUrl($transaction->getId()); // Set Checkout Page Data $checkoutPageData = (new CheckoutPageData()) @@ -280,14 +270,13 @@ class CheckoutController extends StorefrontController { * Get transaction Javascript URL * * @param int $transactionId - * @param string $paymentPageLocale The payment page locale. * * @return string * @throws \VRPayment\Sdk\ApiException * @throws \VRPayment\Sdk\Http\ConnectionException * @throws \VRPayment\Sdk\VersioningException */ - private function getTransactionJavaScriptUrl(int $transactionId, string $paymentPageLocale = ''): string + private function getTransactionJavaScriptUrl(int $transactionId): string { $javascriptUrl = ''; switch ($this->settings->getIntegration()) { @@ -303,12 +292,6 @@ class CheckoutController extends StorefrontController { $this->logger->critical(strtr('invalid integration : :integration', [':integration' => $this->settings->getIntegration()])); } - - if ($javascriptUrl && $paymentPageLocale) { - $separator = str_contains($javascriptUrl, '?') ? '&' : '?'; - $javascriptUrl .= $separator . 'language=' . $paymentPageLocale; - } - return $javascriptUrl; } diff --git a/src/Core/Storefront/Checkout/Subscriber/CheckoutSubscriber.php b/src/Core/Storefront/Checkout/Subscriber/CheckoutSubscriber.php index 37ed8f1..2a0a5ea 100644 --- a/src/Core/Storefront/Checkout/Subscriber/CheckoutSubscriber.php +++ b/src/Core/Storefront/Checkout/Subscriber/CheckoutSubscriber.php @@ -8,6 +8,10 @@ use Shopware\Core\{Checkout\Order\Aggregate\OrderTransaction\OrderTransactionCol Checkout\Order\OrderEntity, Content\MailTemplate\Service\Event\MailBeforeValidateEvent}; use Shopware\Core\Checkout\Payment\PaymentMethodCollection; +use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; +use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; +use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; +use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter; use Shopware\Core\System\SalesChannel\SalesChannelContext; use Shopware\Storefront\Page\Account\Order\AccountEditOrderPageLoadedEvent; use Shopware\Storefront\Page\Account\PaymentMethod\AccountPaymentMethodPageLoadedEvent; @@ -35,6 +39,7 @@ use VRPaymentPayment\Sdk\{Model\AddressCreate, Model\TransactionCreate, Model\TransactionPending}; use Shopware\Core\Framework\Struct\ArrayEntity; +use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting; /** * Class CheckoutSubscriber @@ -69,6 +74,9 @@ class CheckoutSubscriber implements EventSubscriberInterface */ private $paymentMethodUtil; + /** @var EntityRepository */ + private EntityRepository $paymentMethodRepository; + /** * CheckoutSubscriber constructor. * @@ -77,12 +85,13 @@ class CheckoutSubscriber implements EventSubscriberInterface * @param \VRPaymentPayment\Core\Settings\Service\SettingsService $settingsService * @param \VRPaymentPayment\Core\Util\PaymentMethodUtil $paymentMethodUtil */ - public function __construct(PaymentMethodConfigurationService $paymentMethodConfigurationService, TransactionService $transactionService, SettingsService $settingsService, PaymentMethodUtil $paymentMethodUtil) + public function __construct(PaymentMethodConfigurationService $paymentMethodConfigurationService, TransactionService $transactionService, SettingsService $settingsService, PaymentMethodUtil $paymentMethodUtil, EntityRepository $paymentMethodRepository) { $this->paymentMethodConfigurationService = $paymentMethodConfigurationService; $this->transactionService = $transactionService; $this->settingsService = $settingsService; $this->paymentMethodUtil = $paymentMethodUtil; + $this->paymentMethodRepository = $paymentMethodRepository; } /** @@ -284,25 +293,26 @@ class CheckoutSubscriber implements EventSubscriberInterface } /** - * Filters the original payment method collection (which already has Shopware's availability rules applied) - * to only include WhitelabelMachineName methods that are also allowed by the API. - * Non-WhitelabelMachineName methods are kept as-is. - * * @param int $spaceId - * @param $event + * @param CheckoutConfirmPageLoadedEvent $event * @return void */ private function setPossiblePaymentMethods(int $spaceId, $event): void { + $paymentIds = []; $paymentMethodCollection = $event->getPage()->getPaymentMethods(); + foreach ($paymentMethodCollection as $paymentMethodCollectionItem) { + $isVRPaymentPM = VRPaymentPaymentHandler::class === $paymentMethodCollectionItem->getHandlerIdentifier(); + if (!$isVRPaymentPM) { + $paymentIds[] = $paymentMethodCollectionItem->getId(); + } + } + + $allowedWLMethods = []; $paymentMethodConfigurations = $this->paymentMethodConfigurationService ->getAllPaymentMethodConfigurations($spaceId, $event->getSalesChannelContext()->getContext()); - $allowedIds = $this->getAllowedPaymentMethodIds($event->getSalesChannelContext()); - - // Build a map of Shopware payment method ID => configuration for methods allowed by the API. - $allowedWLConfigByPmId = []; foreach ($paymentMethodConfigurations as $paymentMethodConfiguration) { if ($paymentMethodConfiguration->getPaymentMethod() === null) { continue; @@ -310,34 +320,33 @@ class CheckoutSubscriber implements EventSubscriberInterface $pmId = $paymentMethodConfiguration->getPaymentMethod()->getId(); $pmConfigId = $paymentMethodConfiguration->getPaymentMethodConfigurationId(); + $allowedIds = $this->getAllowedPaymentMethodIds($event->getSalesChannelContext()); if ($paymentMethodConfiguration->getSpaceId() === $spaceId && \in_array($pmConfigId, $allowedIds, true)) { - $allowedWLConfigByPmId[$pmId] = $paymentMethodConfiguration; + $allowedWLMethods[] = $pmId; } } - // Filter the original collection to preserve Shopware's availability rule filtering. - // Non-WLM methods pass through unchanged; WLM methods are kept only if allowed by the API. + $allPaymentIds = array_unique(array_merge($paymentIds, $allowedWLMethods)); $collection = new PaymentMethodCollection(); - foreach ($paymentMethodCollection as $method) { - $isVRPaymentPM = VRPaymentPaymentHandler::class === $method->getHandlerIdentifier(); + if (!empty($allPaymentIds)) { + $criteria = new Criteria($allPaymentIds); + $criteria->addFilter(new EqualsFilter('active', true)); + $criteria->addFilter( + new EqualsFilter('salesChannels.id', $event->getSalesChannelContext()->getSalesChannelId()) + ); + $criteria->addSorting(new FieldSorting('position', FieldSorting::ASCENDING)); + $criteria->addAssociation('media'); - if (!$isVRPaymentPM) { - $collection->add($method); - continue; - } - - if (isset($allowedWLConfigByPmId[$method->getId()])) { - $method->addExtension('vrpayment_config', $allowedWLConfigByPmId[$method->getId()]); - $collection->add($method); + $result = $this->paymentMethodRepository->search($criteria, $event->getContext()); + foreach ($result->getEntities() as $method) { + if (!$collection->has($method->getId())) { + $collection->add($method); + } } } - $collection->sort(function ($a, $b) { - return ($a->getPosition() ?? 0) <=> ($b->getPosition() ?? 0); - }); - $event->getPage()->setPaymentMethods($collection); } diff --git a/src/Core/Util/Analytics/Analytics.php b/src/Core/Util/Analytics/Analytics.php index 2f004eb..3107788 100644 --- a/src/Core/Util/Analytics/Analytics.php +++ b/src/Core/Util/Analytics/Analytics.php @@ -28,7 +28,7 @@ class Analytics { self::SHOP_SYSTEM => 'shopware', self::SHOP_SYSTEM_VERSION => $shopwareVersion, self::SHOP_SYSTEM_AND_VERSION => 'shopware-' . $shopwareVersion, - self::PLUGIN_SYSTEM_VERSION => '6.2.2', + self::PLUGIN_SYSTEM_VERSION => '6.2.3', ]; } diff --git a/src/Core/Util/LocaleCodeProvider.php b/src/Core/Util/LocaleCodeProvider.php index 4b8af8b..041c6d5 100644 --- a/src/Core/Util/LocaleCodeProvider.php +++ b/src/Core/Util/LocaleCodeProvider.php @@ -91,26 +91,6 @@ class LocaleCodeProvider { return $language->getLocale() ? $language->getLocale()->getCode() : $defaultLocale; } - /** - * Maps a locale code to a VRPayment-supported payment page locale by matching the language prefix. - * E.g. de-CH -> de-DE, fr-CH -> fr-FR, en-US -> en-GB, it-CH -> it-IT. - * - * @param string $localeCode - * @return string - */ - public function mapToPaymentPageLocale(string $localeCode): string - { - $supportedLocales = [ - 'de' => self::LOCALE_GERMANY_GERMAN, - 'fr' => self::LOCALE_FRANCE_FRENCH, - 'it' => self::LOCALE_ITALY_ITALIAN, - 'en' => self::LOCALE_GREAT_BRITAIN_ENGLISH, - ]; - - $languagePrefix = substr($localeCode, 0, 2); - - return $supportedLocales[$languagePrefix] ?? self::LOCALE_GREAT_BRITAIN_ENGLISH; - } /** * @param \Shopware\Core\Framework\Context $context diff --git a/src/Resources/config/services/core/storefront/checkout.xml b/src/Resources/config/services/core/storefront/checkout.xml index c7146a3..58f2a5e 100644 --- a/src/Resources/config/services/core/storefront/checkout.xml +++ b/src/Resources/config/services/core/storefront/checkout.xml @@ -16,7 +16,6 @@ - @@ -34,6 +33,7 @@ +