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

Magento 2支付表单新增文档类型及编号字段失败,求助实现方案

在Magento 2支付表单中添加自定义字段(文档类型+文档编号)

以下是可直接落地的实现方案,覆盖字段添加、数据保存、后台展示全流程:

1. 创建自定义基础模块

先搭建模块核心结构(命名为Vendor_PaymentFields,可替换为你的厂商/模块名):

app/code/Vendor/PaymentFields/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_PaymentFields" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Checkout"/>
            <module name="Magento_Sales"/>
        </sequence>
    </module>
</config>

app/code/Vendor/PaymentFields/registration.php

<?php
use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
    ComponentRegistrar::MODULE,
    'Vendor_PaymentFields',
    __DIR__
);

2. 向支付表单添加字段

通过Checkout布局文件,将两个字段注入支付步骤的表单区域:

app/code/Vendor/PaymentFields/view/frontend/layout/checkout_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="payment-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="payment" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="payments-list" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="additional-payment-fields" xsi:type="array">
                                                                    <item name="component" xsi:type="string">uiComponent</item>
                                                                    <item name="displayArea" xsi:type="string">additional-fields</item>
                                                                    <item name="children" xsi:type="array">
                                                                        <!-- 文档类型下拉框 -->
                                                                        <item name="document_type" xsi:type="array">
                                                                            <item name="component" xsi:type="string">Magento_Ui/js/form/element/select</item>
                                                                            <item name="config" xsi:type="array">
                                                                                <item name="customScope" xsi:type="string">paymentMethod</item>
                                                                                <item name="template" xsi:type="string">ui/form/field</item>
                                                                                <item name="elementTmpl" xsi:type="string">ui/form/element/select</item>
                                                                            </item>
                                                                            <item name="dataScope" xsi:type="string">paymentMethod.document_type</item>
                                                                            <item name="label" xsi:type="string">文档类型</item>
                                                                            <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                            <item name="sortOrder" xsi:type="number">1</item>
                                                                            <item name="validation" xsi:type="array">
                                                                                <item name="required-entry" xsi:type="boolean">true</item>
                                                                            </item>
                                                                            <item name="options" xsi:type="array">
                                                                                <item name="0" xsi:type="array">
                                                                                    <item name="label" xsi:type="string">身份证</item>
                                                                                    <item name="value" xsi:type="string">id_card</item>
                                                                                </item>
                                                                                <item name="1" xsi:type="array">
                                                                                    <item name="label" xsi:type="string">护照</item>
                                                                                    <item name="value" xsi:type="string">passport</item>
                                                                                </item>
                                                                            </item>
                                                                        </item>
                                                                        <!-- 文档编号输入框 -->
                                                                        <item name="document_number" xsi:type="array">
                                                                            <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item>
                                                                            <item name="config" xsi:type="array">
                                                                                <item name="customScope" xsi:type="string">paymentMethod</item>
                                                                                <item name="template" xsi:type="string">ui/form/field</item>
                                                                                <item name="elementTmpl" xsi:type="string">ui/form/element/input</item>
                                                                            </item>
                                                                            <item name="dataScope" xsi:type="string">paymentMethod.document_number</item>
                                                                            <item name="label" xsi:type="string">文档编号</item>
                                                                            <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                            <item name="sortOrder" xsi:type="number">2</item>
                                                                            <item name="validation" xsi:type="array">
                                                                                <item name="required-entry" xsi:type="boolean">true</item>
                                                                            </item>
                                                                        </item>
                                                                    </item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

3. 保存字段数据到订单

通过插件拦截支付信息保存动作,将字段数据存入订单支付附加信息:

app/code/Vendor/PaymentFields/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Model\PaymentInformationManagement">
        <plugin name="save_document_fields_to_order" type="Vendor\PaymentFields\Plugin\SaveDocumentFields" sortOrder="10"/>
    </type>
</config>

app/code/Vendor/PaymentFields/Plugin/SaveDocumentFields.php

<?php
namespace Vendor\PaymentFields\Plugin;

use Magento\Checkout\Model\PaymentInformationManagement;
use Magento\Quote\Api\Data\PaymentInterface;
use Magento\Quote\Api\Data\AddressInterface;

class SaveDocumentFields
{
    public function beforeSavePaymentInformationAndPlaceOrder(
        PaymentInformationManagement $subject,
        $cartId,
        PaymentInterface $paymentMethod,
        AddressInterface $billingAddress = null
    ) {
        $additionalData = $paymentMethod->getAdditionalData();
        if (isset($additionalData['document_type']) && isset($additionalData['document_number'])) {
            $paymentMethod->setAdditionalInformation('document_type', $additionalData['document_type']);
            $paymentMethod->setAdditionalInformation('document_number', $additionalData['document_number']);
        }
        return [$cartId, $paymentMethod, $billingAddress];
    }
}

4. 在后台订单详情页展示字段

添加后台布局与模板,让管理员能看到用户提交的文档信息:

app/code/Vendor/PaymentFields/view/adminhtml/layout/sales_order_view.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="order_additional_info">
            <block class="Vendor\PaymentFields\Block\Order\DocumentInfo" name="document_info" template="Vendor_PaymentFields::order/document_info.phtml"/>
        </referenceBlock>
    </body>
</page>

app/code/Vendor/PaymentFields/Block/Order/DocumentInfo.php

<?php
namespace Vendor\PaymentFields\Block\Order;

use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Magento\Framework\Registry;

class DocumentInfo extends Template
{
    protected $coreRegistry;

    public function __construct(
        Context $context,
        Registry $coreRegistry,
        array $data = []
    ) {
        $this->coreRegistry = $coreRegistry;
        parent::__construct($context, $data);
    }

    public function getOrder()
    {
        return $this->coreRegistry->registry('current_order');
    }

    public function getDocumentType()
    {
        return $this->getOrder()->getPayment()->getAdditionalInformation('document_type');
    }

    public function getDocumentNumber()
    {
        return $this->getOrder()->getPayment()->getAdditionalInformation('document_number');
    }
}

app/code/Vendor/PaymentFields/view/adminhtml/templates/order/document_info.phtml

<?php if ($block->getDocumentType() && $block->getDocumentNumber()): ?>
<div class="admin__page-section-item">
    <div class="admin__page-section-item-title">
        <span class="title"><?= __('Document Information') ?></span>
    </div>
    <div class="admin__page-section-item-content">
        <table class="admin__table-secondary">
            <tr>
                <th><?= __('Document Type') ?>:</th>
                <td><?= $block->escapeHtml($block->getDocumentType() == 'id_card' ? __('身份证') : __('护照')) ?></td>
            </tr>
            <tr>
                <th><?= __('Document Number') ?>:</th>
                <td><?= $block->escapeHtml($block->getDocumentNumber()) ?></td>
            </tr>
        </table>
    </div>
</div>
<?php endif; ?>

5. 部署与测试

执行以下命令完成模块部署:

bin/magento module:enable Vendor_PaymentFields
bin/magento setup:upgrade
bin/magento setup:static-content:deploy zh_CN -f
bin/magento cache:clean

部署完成后,前端结算页的支付步骤会出现你需要的两个字段,提交订单后,后台订单详情页的「附加信息」区域会展示对应的文档数据。

内容的提问来源于stack exchange,提问作者MartiPE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 20:50:28