diff --git a/CHANGELOG.md b/CHANGELOG.md index 552f253..3a78abc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 6.2.2 +- Fixed issue with payment method availability rules being ignored + # 6.2.1 - Fixed issue with multiple discount codes diff --git a/CHANGELOG_de-DE.md b/CHANGELOG_de-DE.md index 3fa5228..d0048d7 100644 --- a/CHANGELOG_de-DE.md +++ b/CHANGELOG_de-DE.md @@ -1,3 +1,6 @@ +# 6.2.2 +- Problem behoben, bei dem die Verfügbarkeitsregeln für Zahlungsmethoden ignoriert wurden + # 6.2.1 - Problem mit mehreren Rabattcodes behoben diff --git a/README.md b/README.md index 7a70955..018b201 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.1/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.1/docs/de/documentation.html) -- Pour la documentation Française, cliquez [ici](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.1/docs/fr/documentation.html) -- Per la documentazione in tedesco, clicca [qui](https://docs.plugin-documentation.vr-payment.de/vr-payment/shopware-6/6.2.1/docs/it/documentation.html) +- 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) ## 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 | Further notice | +| Shopware 6.6.x | 6.x | December 2026 | | Shopware 6.5.x | 5.x | October 2024 | ----------------------------------------------------------------------------------- diff --git a/composer.json b/composer.json index 05728b9..e8fb8e3 100644 --- a/composer.json +++ b/composer.json @@ -59,5 +59,5 @@ "vrpayment/sdk": "^4.0.0" }, "type": "shopware-platform-plugin", - "version": "6.2.1" + "version": "6.2.2" } diff --git a/src/Core/Api/Transaction/Service/TransactionService.php b/src/Core/Api/Transaction/Service/TransactionService.php index 6963e62..dff1ff1 100644 --- a/src/Core/Api/Transaction/Service/TransactionService.php +++ b/src/Core/Api/Transaction/Service/TransactionService.php @@ -609,10 +609,13 @@ 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) @@ -661,7 +664,10 @@ 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/Storefront/Checkout/Controller/CheckoutController.php b/src/Core/Storefront/Checkout/Controller/CheckoutController.php index d142f16..c4d0d1e 100644 --- a/src/Core/Storefront/Checkout/Controller/CheckoutController.php +++ b/src/Core/Storefront/Checkout/Controller/CheckoutController.php @@ -55,6 +55,7 @@ use VRPaymentPayment\Core\{ Settings\Options\Integration, Settings\Service\SettingsService, Storefront\Checkout\Struct\CheckoutPageData, + Util\LocaleCodeProvider, Util\Payload\CustomProducts\CustomProductsLineItemTypes, Util\Payload\TransactionPayload }; @@ -126,6 +127,11 @@ class CheckoutController extends StorefrontController { */ private CacheItemPoolInterface $cache; + /** + * @var LocaleCodeProvider + */ + private LocaleCodeProvider $localeCodeProvider; + /** * PaymentController constructor. * @@ -148,7 +154,8 @@ class CheckoutController extends StorefrontController { AbstractOrderRoute $orderRoute, OrderTransactionStateHandler $orderTransactionStateHandler, StateMachineRegistry $stateMachineRegistry, - ParameterBagInterface $params + ParameterBagInterface $params, + LocaleCodeProvider $localeCodeProvider ) { $this->cartService = $cartService; @@ -160,6 +167,7 @@ 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; } /** @@ -243,7 +251,9 @@ class CheckoutController extends StorefrontController { return $this->redirect($recreateCartUrl, Response::HTTP_MOVED_PERMANENTLY); } - $javascriptUrl = $this->getTransactionJavaScriptUrl($transaction->getId()); + $localeCode = $this->localeCodeProvider->getLocaleCodeFromContext($salesChannelContext->getContext()); + $paymentPageLocale = $this->localeCodeProvider->mapToPaymentPageLocale($localeCode); + $javascriptUrl = $this->getTransactionJavaScriptUrl($transaction->getId(), $paymentPageLocale); // Set Checkout Page Data $checkoutPageData = (new CheckoutPageData()) @@ -270,13 +280,14 @@ 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 + private function getTransactionJavaScriptUrl(int $transactionId, string $paymentPageLocale = ''): string { $javascriptUrl = ''; switch ($this->settings->getIntegration()) { @@ -292,6 +303,12 @@ 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 2a0a5ea..37ed8f1 100644 --- a/src/Core/Storefront/Checkout/Subscriber/CheckoutSubscriber.php +++ b/src/Core/Storefront/Checkout/Subscriber/CheckoutSubscriber.php @@ -8,10 +8,6 @@ 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; @@ -39,7 +35,6 @@ 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 @@ -74,9 +69,6 @@ class CheckoutSubscriber implements EventSubscriberInterface */ private $paymentMethodUtil; - /** @var EntityRepository */ - private EntityRepository $paymentMethodRepository; - /** * CheckoutSubscriber constructor. * @@ -85,13 +77,12 @@ 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, EntityRepository $paymentMethodRepository) + public function __construct(PaymentMethodConfigurationService $paymentMethodConfigurationService, TransactionService $transactionService, SettingsService $settingsService, PaymentMethodUtil $paymentMethodUtil) { $this->paymentMethodConfigurationService = $paymentMethodConfigurationService; $this->transactionService = $transactionService; $this->settingsService = $settingsService; $this->paymentMethodUtil = $paymentMethodUtil; - $this->paymentMethodRepository = $paymentMethodRepository; } /** @@ -293,26 +284,25 @@ 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 CheckoutConfirmPageLoadedEvent $event + * @param $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; @@ -320,33 +310,34 @@ 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)) { - $allowedWLMethods[] = $pmId; + $allowedWLConfigByPmId[$pmId] = $paymentMethodConfiguration; } } - $allPaymentIds = array_unique(array_merge($paymentIds, $allowedWLMethods)); + // 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. $collection = new PaymentMethodCollection(); - 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'); + foreach ($paymentMethodCollection as $method) { + $isVRPaymentPM = VRPaymentPaymentHandler::class === $method->getHandlerIdentifier(); - $result = $this->paymentMethodRepository->search($criteria, $event->getContext()); - foreach ($result->getEntities() as $method) { - if (!$collection->has($method->getId())) { - $collection->add($method); - } + if (!$isVRPaymentPM) { + $collection->add($method); + continue; + } + + if (isset($allowedWLConfigByPmId[$method->getId()])) { + $method->addExtension('vrpayment_config', $allowedWLConfigByPmId[$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 72a26c0..2f004eb 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.1', + self::PLUGIN_SYSTEM_VERSION => '6.2.2', ]; } diff --git a/src/Core/Util/LocaleCodeProvider.php b/src/Core/Util/LocaleCodeProvider.php index 041c6d5..4b8af8b 100644 --- a/src/Core/Util/LocaleCodeProvider.php +++ b/src/Core/Util/LocaleCodeProvider.php @@ -91,6 +91,26 @@ 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 58f2a5e..c7146a3 100644 --- a/src/Resources/config/services/core/storefront/checkout.xml +++ b/src/Resources/config/services/core/storefront/checkout.xml @@ -16,6 +16,7 @@ + @@ -33,7 +34,6 @@ -