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
相关产品推荐
相关产品推荐

