magento2结账页面付款方式添加自定义字段

7天成为Magento系统架构师,现在开始学习Magento全栈开发!

《Magento2.X企业级开发实战》

magento2结账页面付款方式添加自定义字段效果演示:

如果您想使用特定的 pyament 方法添加自定义数据,例如添加自定义输入文本,该文本将显示在付款方式检查中我们开始。
下载或搜索github 中的代码示例

或从商店下载扩展
首先在 Ibnab/Additional/Setup/InstallSchema.php 中创建您的架构文件:

<?php
namespace Ibnab\Additional\Setup;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
class InstallSchema implements InstallSchemaInterface
{
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();   
        $setup->getConnection()->addColumn(
            $setup->getTable('quote_payment'),
            'bankowner',
            [
                'type' => 'text',
                'nullable' => true  ,
                'comment' => 'Bank',
            ]
        );
        $setup->getConnection()->addColumn(
            $setup->getTable('sales_order_payment'),
            'bankowner',
            [
                'type' => 'text',
                'nullable' => true  ,
                'comment' => 'Bank',
            ]
        );
        $setup->endSetup();
  }
}

我们将在magento支付方式页面银行转帐方法上添加此行为,让我们重新映射 Ibnab/Additional/view/frontend/requirejs-config.js 中的 offline-payments٫js :

var config = {
    map: {
        '*': {
          'Magento_OfflinePayments/js/view/payment/offline-payments':       'Ibnab_Additional/js/view/payment/offline-payments',
        }
    }
}

现在您需要从 magento 的vendor找到原文件复制并进行一些更改(Ibnab/Additional/view/frontend/web/js/view/payment/offline-payments.js):

define(
    [
        'uiComponent',
        'Magento_Checkout/js/model/payment/renderer-list'
    ],
    function (
        Component,
        rendererList
    ) {
        'use strict';
        rendererList.push(
            {
                type: 'checkmo',
                component: 'Magento_OfflinePayments/js/view/payment/method-renderer/checkmo-method'
            },
            {
                type: 'banktransfer',
                component: 'Ibnab_Additional/js/view/payment/method-renderer/banktransfer-method'
            },
            {
                type: 'cashondelivery',
                component: 'Magento_OfflinePayments/js/view/payment/method-renderer/cashondelivery-method'
            },
            {
                type: 'purchaseorder',
                component: 'Magento_OfflinePayments/js/view/payment/method-renderer/purchaseorder-method'
            }
        );
        /** Add view logic here if needed */
        return Component.extend({});
    }
);

我们更改了 banktransfert 渲染器:

 {
                type: 'banktransfer',
                component: 'Ibnab_Additional/js/view/payment/method-renderer/banktransfer-method'
            }

并从magento 的 vendor目录找到checkout模块原文件复制一份到 (Ibnab/Additional/view/frontend/web/js/view/payment/method-renderer/banktransfer-method.js)

define(
    [
        'ko',
        'Magento_Checkout/js/view/payment/default',
        'jquery'
    ],
    function (ko, Component,$) {
        'use strict';
        return Component.extend({
            defaults: {
                template: 'Ibnab_Additional/payment/banktransfer'
            },
            getData: function() {
                return {
                    'method': this.item.method,
                    'additional_data': {
                        'bankowner': $('#banktransfer_bankowner').val()
                    }
                };
            },
            /**
             * Get value of instruction field.
             * @returns {String}
             */
            getInstructions: function () {
                return window.checkoutConfig.payment.instructions[this.item.method];
            }
        });
    }
);

在 banktransfer-method.js 中,我们更改了新 html 模板的路径 (Ibnab/Additional/view/frontend/web/template/payment/banktransfer.html):

  defaults: {
                template: 'Ibnab_Additional/payment/banktransfer'
            }

我们使用 id 将银行账户所有者的值添加到其他数据中:

getData: function() {
                return {
                    'method': this.item.method,
                    'additional_data': {
                        'bankowner': $('#banktransfer_bankowner').val()
                    }
                };
            }

下面是magento支付页面添加字段对应的 html 模板的代码(原始代码在 vendor 中):

<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
    <div class="payment-method-title field choice">
        <input type="radio"
               name="payment[method]"
               class="radio"
               data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()" />
        <label data-bind="attr: {'for': getCode()}" class="label"><span data-bind="text: getTitle()"></span></label>
    </div>
    <div class="payment-method-content">
    <p data-bind="html: getInstructions()"></p>
    <fieldset data-bind="attr: {class: 'fieldset payment items allbank ' + getCode(), id: 'payment_form_' + getCode()}">
    <div class="field _required">
        <label data-bind="attr: {for: getCode() + '_bankowner'}" class="label">
            <span><!-- ko i18n: 'Account Owner'--><!-- /ko --></span>
        </label>
        <div class="control">
            <input data-validate="{'required-entry':true}" type="text" name="payment[bankowner]" class="input-text" value=""
                   data-bind="attr: {
                                    id: getCode() + '_bankowner',
                                    title: $t('Account Owner'),
                                    'data-container': getCode() + '-bankowner',
                                    'data-validate': JSON.stringify({'required':true})},
                                    valueUpdate: 'keyup' "/>
        </div>
    </div>
    </fieldset>
        <!-- ko foreach: getRegion('messages') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
        <!--/ko-->
        <div class="payment-method-billing-address">
            <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
            <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->
        </div>      
        <div class="checkout-agreements-block">
            <!-- ko foreach: $parent.getRegion('before-place-order') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->
        </div>
        <div class="actions-toolbar">
            <div class="primary">
                <button class="action primary checkout"
                        type="submit"
                        data-bind="
                        click: placeOrder,
                        attr: {'title': $t('Place Order')},
                        enable: (getCode() == isChecked()),
                        css: {disabled: !isPlaceOrderActionAllowed()}
                        "
                        disabled>
                    <span data-bind="i18n: 'Place Order'"></span>
                </button>
            </div>
        </div>
    </div>
</div>

我们的自定义输入文本名称为 name="payment[bankowner]" :

<fieldset data-bind="attr: {class: 'fieldset payment items allbank ' + getCode(), id: 'payment_form_' + getCode()}">
    <div class="field _required">
        <label data-bind="attr: {for: getCode() + '_bankowner'}" class="label">
            <span><!-- ko i18n: 'Account Owner'--><!-- /ko --></span>
        </label>
        <div class="control">
            <input data-validate="{'required-entry':true}" type="text" name="payment[bankowner]" class="input-text" value=""
                   data-bind="attr: {
                                    id: getCode() + '_bankowner',
                                    title: $t('Account Owner'),
                                    'data-container': getCode() + '-bankowner',
                                    'data-validate': JSON.stringify({'required':true})},
                                    valueUpdate: 'keyup' "/>
      </div>
    </div>
    </fieldset>

magento支付页面添加字段需要添加观察者(Ibnab/Additional/etc/events.xml):

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_order_payment_save_before">
        <observer name="save_bank_infos" instance="Ibnab\Additional\Observer\SaveBankInfoToOrderObserver"/>
    </event>
</config>

在订单付款保存之前取消此事件(Ibnab/Additional/Observer/SaveBankInfoToOrderObserver.php)

<?php
namespace Ibnab\Additional\Observer;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
use Magento\OfflinePayments\Model\Banktransfer;
class SaveBankInfoToOrderObserver implements ObserverInterface {
    protected $_inputParamsResolver;
    protected $_quoteRepository;
    protected $logger;
    protected $_state;
    public function __construct(\Magento\Webapi\Controller\Rest\InputParamsResolver $inputParamsResolver, \Magento\Quote\Model\QuoteRepository $quoteRepository, \Psr\Log\LoggerInterface $logger,\Magento\Framework\App\State $state) {
        $this->_inputParamsResolver = $inputParamsResolver;
        $this->_quoteRepository = $quoteRepository;
        $this->logger = $logger;
        $this->_state = $state;
    }
    public function execute(EventObserver $observer) {
        $inputParams = $this->_inputParamsResolver->resolve();
        if($this->_state->getAreaCode() != \Magento\Framework\App\Area::AREA_ADMINHTML){
        foreach ($inputParams as $inputParam) {
            if ($inputParam instanceof \Magento\Quote\Model\Quote\Payment) {
                $paymentData = $inputParam->getData('additional_data');
                $paymentOrder = $observer->getEvent()->getPayment();
                $order = $paymentOrder->getOrder();
                $quote = $this->_quoteRepository->get($order->getQuoteId());
                $paymentQuote = $quote->getPayment();
                $method = $paymentQuote->getMethodInstance()->getCode();
                if ($method == Banktransfer::PAYMENT_METHOD_BANKTRANSFER_CODE) {
                    if(isset($paymentData['bankowner'])){
                    $paymentQuote->setData('bankowner', $paymentData['bankowner']);
                    $paymentOrder->setData('bankowner', $paymentData['bankowner']);
                    }
                }
            }
        }
       }
    }
}

我们使用一种方法从带有 inputParamsResolver 的支付报价的附加数据中获取输入文本的值:

$inputParams = $this->_inputParamsResolver->resolve();

我们使用 foreach 子句提取值并发送到支付 qoute 和支付订单中。
因此,现在如果您创建订单,您的自定义字段的值将保存在 quote_payment 和 sales_order_payment 表的 bankowner 列中。
但是如何在订单视图(在管理员内部)中显示它,您可以添加布局(Ibnab/Additional/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>
        <referenceContainer name="payment_additional_info">
            <block class="Ibnab\Additional\Block\Info\BanktransferInfo" name="ibnab_banktransfert_infos" template="Ibnab_Additional::info/banktransferinfo.phtml" />
        </referenceContainer>
    </body>
</page>

现在来创建 .phtml (Ibnab/Additional/view/adminhtml/templates/info/banktransferinfo.phtml):

<?php
use Magento\OfflinePayments\Model\Banktransfer;
$payment = $block->getOrder()->getPayment();
$method = $payment->getMethodInstance()->getCode();
?>
<?php if ($method == Banktransfer::PAYMENT_METHOD_BANKTRANSFER_CODE) :?>
<div class="admin__page-section-item-content">
    <strong><?php echo __('Account Name:') ?></strong>
    <span class="price"><?php echo $payment->getData('bankowner'); ?></span>                        
</div>
<?php endif; ?>

我们现在将显示帐户字段,如果选择银行转账方式:

<?php if ($method == Banktransfer::PAYMENT_METHOD_BANKTRANSFER_CODE) :?>

最后,执行php bin/magento setup:upgrade更新模块,在订单结算页的第二步支付方式中查看效果。

如无特殊说明或标注,任何个人或组织,复制、转载、采集本站内容请注明:
本文来源于:【Magento中文网】,并添加本文地址链接。
如未按上述操作复制或转载,本站有权追究法律责任。
若本站内容侵犯了原著者的合法权益,可联系我们进行处理。