You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 17:25:03