Shopware 6中如何通过代码按货币隐藏指定自定义支付方式?
Shopware 6:按货币隐藏指定支付方式的问题排查与解决
问题概述
需在结账确认页,当用户选择特定货币(如EUR)时隐藏自定义支付方式MyPaygate。已尝试两种方案均失效:
- 使用
CheckoutConfirmPageLoadedEvent事件订阅器,事件未触发 - 装饰
PaymentMethodRoute实现过滤逻辑,但代码未执行(添加日志无输出)
已实现的代码
路由装饰器代码
文件路径:src/Core/Checkout/Payment/SalesChannel/DecoratedPaymentMethodRoute.php
<?php declare(strict_types=1); namespace Test\Paygate\Core\Checkout\Payment\SalesChannel; use Shopware\Core\Checkout\Payment\SalesChannel\AbstractPaymentMethodRoute; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Checkout\Payment\SalesChannel\PaymentMethodRoute; use Symfony\Component\HttpFoundation\Request; use Shopware\Core\System\SalesChannel\SalesChannelContext; use Shopware\Core\Checkout\Payment\SalesChannel\PaymentMethodRouteResponse; class DecoratedPaymentMethodRoute extends AbstractPaymentMethodRoute { private $originalService; public function __construct(PaymentMethodRoute $originalService) { $this->originalService = $originalService; } public function load(Request $request, SalesChannelContext $context, Criteria $criteria): PaymentMethodRouteResponse { $response = $this->originalService->load($request, $context, $criteria); $paymentMethods = $response->getPaymentMethods()->filter(function ($paymentMethod) use ($context) { if ($context->getCurrency()->getIsoCode() === 'EUR' && $paymentMethod->getHandlerIdentifier() === 'TestPaygate') { return false; } return true; }); $response->setPaymentMethods($paymentMethods); return $response; } public function getDecorated(): PaymentMethodRoute { return $this->originalService; } }
services.xml配置
<service id="Test\Paygate\Core\Checkout\Payment\SalesChannel\DecoratedPaymentMethodRoute" class="Test\Paygate\Core\Checkout\Payment\SalesChannel\DecoratedPaymentMethodRoute"> <argument type="service" id="Shopware\Core\Checkout\Payment\SalesChannel\PaymentMethodRoute" /> <tag name="shopware.sales_channel.route_decorator"/> </service>
问题根源分析
路由装饰器未生效的核心原因是缺少路由标识配置:shopware.sales_channel.route_decorator标签必须指定route属性,对应被装饰路由的官方ID,否则Symfony无法识别要装饰的目标路由。
解决方案
方案1:修复路由装饰器配置
修改services.xml,为装饰器标签添加route属性,值为PaymentMethodRoute对应的路由IDfrontend.checkout.payment.method:
<service id="Test\Paygate\Core\Checkout\Payment\SalesChannel\DecoratedPaymentMethodRoute" class="Test\Paygate\Core\Checkout\Payment\SalesChannel\DecoratedPaymentMethodRoute"> <argument type="service" id="Shopware\Core\Checkout\Payment\SalesChannel\PaymentMethodRoute" /> <tag name="shopware.sales_channel.route_decorator" route="frontend.checkout.payment.method"/> </service>
方案2:使用官方推荐的支付方式验证器
相比路由装饰,Shopware提供了更规范的PaymentMethodValidatorInterface接口,用于过滤支付方式,无需手动装饰路由:
1. 实现验证器类
文件路径:src/Core/Checkout/Payment/CurrencyPaymentMethodValidator.php
<?php declare(strict_types=1); namespace Test\Paygate\Core\Checkout\Payment; use Shopware\Core\Checkout\Payment\PaymentMethodValidatorInterface; use Shopware\Core\Checkout\Payment\PaymentMethodCollection; use Shopware\Core\System\SalesChannel\SalesChannelContext; class CurrencyPaymentMethodValidator implements PaymentMethodValidatorInterface { public function validate(PaymentMethodCollection $paymentMethods, SalesChannelContext $context): PaymentMethodCollection { // 仅当货币为EUR时过滤TestPaygate if ($context->getCurrency()->getIsoCode() !== 'EUR') { return $paymentMethods; } return $paymentMethods->filter(function ($method) { return $method->getHandlerIdentifier() !== 'TestPaygate'; }); } }
2. 注册验证器
在services.xml中添加:
<service id="Test\Paygate\Core\Checkout\Payment\CurrencyPaymentMethodValidator" class="Test\Paygate\Core\Checkout\Payment\CurrencyPaymentMethodValidator"> <tag name="shopware.payment.method.validator"/> </service>
通用修复步骤
无论采用哪种方案,都需要执行以下操作确保生效:
- 清除Shopware缓存:
bin/console cache:clear - 刷新插件列表:
bin/console plugin:refresh - 重新安装并激活插件:
bin/console plugin:install Paygate -a
内容的提问来源于stack exchange,提问作者Juraj.Lorinc
相关产品推荐
相关产品推荐

