如何在Shopware 6结账页面添加自定义地址字段并实现校验
Shopware 6 结账页地址区块自定义字段实现方案
以下实现完全覆盖需求:自有数据库地址下拉选择、配送站点编号字段新增、前后端字段校验、数据持久化、后端订单页展示。
1. 扩展订单地址实体新增自定义字段
优先扩展OrderAddress(订单地址实体)存储地址关联字段,也可根据需求扩展Order实体:
- 在自定义插件下新建实体扩展文件
src/Extension/OrderAddressExtension.php,添加两个自定义字段:
<?php declare(strict_types=1); namespace YourPluginNamespace\Extension; use Shopware\Core\Checkout\Order\Aggregate\OrderAddress\OrderAddressDefinition; use Shopware\Core\Framework\DataAbstractionLayer\EntityExtension; use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\ApiAware; use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\Required; use Shopware\Core\Framework\DataAbstractionLayer\Field\StringField; use Shopware\Core\Framework\DataAbstractionLayer\FieldCollection; class OrderAddressExtension extends EntityExtension { public function extendFields(FieldCollection $collection): void { // 用户选择的标准化地址字段 $collection->add( (new StringField('custom_selected_address', 'customSelectedAddress')) ->addFlags(new ApiAware(), new Required()) ); // 配送站点编号字段 $collection->add( (new StringField('delivery_station_code', 'deliveryStationCode')) ->addFlags(new ApiAware(), new Required()) ); } public function getDefinitionClass(): string { return OrderAddressDefinition::class; } }
- 在插件的
src/Resources/config/services.xml中注册实体扩展,执行bin/console database:migrate和bin/console cache:clear生效。
2. 扩展结账页模板、渲染字段并实现校验
通过插件视图继承覆盖原生地址表单模板:
- 新建模板文件
src/Resources/views/storefront/component/address/address-form.html.twig,插入自定义字段:
{% block component_address_form_fields %} {{ parent() }} {# 标准化地址选择下拉 #} <div class="form-group"> <label class="form-label required" for="customSelectedAddress"> {{ 'custom.address.select'|trans }} </label> <select class="form-select" id="customSelectedAddress" name="customSelectedAddress" required > <option value="">{{ 'custom.address.placeholder'|trans }}</option> <!-- 选项由后续Ajax动态填充 --> </select> <div class="invalid-feedback"> {{ 'custom.address.required'|trans }} </div> </div> {# 配送站点编号输入框 #} <div class="form-group"> <label class="form-label required" for="deliveryStationCode"> {{ 'custom.delivery.stationCode'|trans }} </label> <input type="text" class="form-control" id="deliveryStationCode" name="deliveryStationCode" pattern="[0-9A-Z]{6,10}" required > <div class="invalid-feedback"> {{ 'custom.delivery.stationCode.error'|trans }} </div> </div> {% endblock %}
- 新增前端JS逻辑:调用后续接口拉取自有数据库地址列表填充下拉,绑定字段值到Shopware结账提交流程,同时实现前端表单校验逻辑。
3. 新增接口返回地址下拉数据
新建StoreApi控制器对外开放地址查询能力:
- 新建控制器文件
src/Controller/CustomAddressController.php:
<?php declare(strict_types=1); namespace YourPluginNamespace\Controller; use Shopware\Core\System\SalesChannel\SalesChannelContext; use Shopware\Storefront\Controller\StorefrontController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Routing\Annotation\Route; #[Route(defaults: ['_routeScope' => ['storefront']])] class CustomAddressController extends StorefrontController { #[Route( path: '/custom/address/list', name: 'frontend.custom.address.list', methods: ['GET'] )] public function getAddressList(SalesChannelContext $context): JsonResponse { // 此处替换为你的自有数据库地址查询逻辑,返回标准化地址列表 $addressList = $this->yourCustomDbService->getValidAddressOptions($context); return new JsonResponse($addressList); } }
- 在
src/Resources/config/routes.xml中注册路由,清理缓存后即可通过接口拉取地址数据填充下拉。
4. 扩展后端订单模板展示自定义字段
覆盖后端订单详情模板,展示新增字段内容:
- 新建后台模板文件
src/Resources/views/administration/module/sw-order/view/sw-order-detail-base.html.twig:
{% block sw_order_detail_base_summary_additional_information %} {{ parent() }} <sw-card title="{{ 'custom.order.addressTitle'|trans|sw_sanitize }}"> <sw-description-list> <dt>{{ 'custom.address.select'|trans|sw_sanitize }}</dt> <dd>{{ order.addresses.first.customSelectedAddress }}</dd> <dt>{{ 'custom.delivery.stationCode'|trans|sw_sanitize }}</dt> <dd>{{ order.addresses.first.deliveryStationCode }}</dd> </sw-description-list> </sw-card> {% endblock %}
注意事项
- 所有自定义文案需在插件的
src/Resources/translations/zh-CN.messages.yml中添加对应中文翻译,避免展示英文key - 后端建议订阅
CheckoutOrderPlacedEvent事件对提交的自定义字段做二次校验,防止前端校验被绕过 - 每次代码修改后需执行
bin/console cache:clear清理缓存生效
内容的提问来源于stack exchange,提问作者Mikael
相关产品推荐
相关产品推荐

