Shopware6后台订阅事件中如何抛出异常并展示错误提示?
解决Shopware6后台支付操作失败时的自定义错误通知问题
问题背景
开发Shopware6支付提供商插件时,通过以下事件订阅处理退款与金额捕获逻辑:
OrderEvents::ORDER_LINE_ITEM_WRITTEN_EVENT => 'lineItemWritten', StateMachineTransitionEvent::class => 'onStateTransition'
API调用流程正常,但当API返回失败时,无法在后台右上角展示自定义错误通知。尝试抛出自定义异常无响应,修改请求头仅返回通用状态码错误,即使已实现支付状态回滚,仍无对应错误提示。
解决方案
Shopware后台的错误通知需要结合状态机事件的异常处理逻辑,以下是具体调整步骤:
1. 调整事件订阅逻辑
放弃在PreWriteValidationEvent中处理API调用,转而使用StateMachineTransitionEvent——该事件更适合处理支付状态变更的业务逻辑,且能将异常正确反馈到后台UI。
修改订阅者的事件配置:
public static function getSubscribedEvents() { return [ StateMachineTransitionEvent::class => 'onStateTransition' ]; }
2. 实现状态转换事件处理方法
在onStateTransition方法中,判断支付状态转换操作,调用API后直接抛出自定义异常(而非添加到异常集合):
public function onStateTransition(StateMachineTransitionEvent $event) { // 仅处理订单交易的状态转换 if ($event->getStateMachineName() !== 'order_transaction') { return; } // 仅处理从"open"到"paid"的金额捕获操作 if ($event->getFromPlace() !== 'open' || $event->getToPlace() !== 'paid') { return; } // 获取交易及关联数据 $transaction = $this->transactionRepository->search( (new Criteria())->addFilter(new EqualsFilter('id', $event->getEntityId())) ->addAssociation('order') ->addAssociation('paymentMethod') ->addAssociation('order.currency'), $event->getContext() )->first(); if (!$transaction) { return; } $paymentMethod = $transaction->getPaymentMethod(); $identifier = $paymentMethod->getHandlerIdentifier(); // 仅处理指定支付方式 if (!in_array($identifier, [Creditcard::class, Paypal::class])) { return; } // 调用支付提供商API $result = Order::captureNow($transaction->getOrder()); if (!$result['status']) { // 直接抛出自定义异常,Shopware自动触发后台错误提示 throw new FailedCaptureException($result["response"]["Description"]); } // 成功后的业务逻辑... }
3. 优化自定义异常(可选)
你的自定义异常已继承ShopwareHttpException,若需多语言支持,可将异常消息改为翻译键:
namespace Example\Plugin\Helper\Exceptions; use Shopware\Core\Framework\ShopwareHttpException; class FailedCaptureException extends ShopwareHttpException { public function __construct(string $message, array $parameters = []) { // 使用翻译键,替换为实际错误消息参数 parent::__construct('example.plugin.failed_capture', ['message' => $message]); } public function getErrorCode(): string { return 'EXAMPLE__FAILED_CAPTURE'; } public function getStatusCode(): int { return 400; } }
同时在插件的snippet文件中添加翻译(如src/Resources/snippet/de-DE/plugin.json):
{ "example": { "plugin": { "failed_capture": "金额捕获失败:{{ message }}" } } }
关键说明
PreWriteValidationEvent用于数据持久化前的字段验证,异常仅阻止写入,不会触发后台UI通知。StateMachineTransitionEvent是状态转换的核心事件,此处抛出的ShopwareHttpException会被Shopware捕获,并自动在后台右上角展示错误消息。- 抛出异常后,Shopware会自动取消当前状态转换,无需手动回滚支付状态。
内容的提问来源于stack exchange,提问作者Chris Schrut
相关产品推荐
相关产品推荐

