カスタム支払い方法にテキストフィールドを追加する必要があります


8

ACLはカスタムの支払い方法です。チェックアウトページのACLオプションの下にカスタムフィールドを追加します。

PFA

ここに画像の説明を入力してください


「bank_name」属性は作成されていますか?はいの場合、どのタイプの属性を作成しましたか?
PY Yick

いいえ、属性は作成していません
Akash '19

「bank_name」にどの属性タイプを設定しますか?顧客または顧客の住所?
PY Yick

ユーザーは銀行情報、その支払い方法の口座番号を入力するだけで、管理者はその情報を見ることができます。それでおしまい。この機能を作成するフローを説明できますか?
Akash

同じ顧客からの「bank_name」の注文はすべて異なりますか?
PY Yick

回答:


2

あなたの質問に答えるために、3つの部分があります:

  1. 注文属性の作成
  2. 注文時に属性を挿入
  3. 支払いモジュールで注文属性を読み取る

注文属性の作成

注文属性を作成するには、次のコードでセットアップスクリプトを使用する必要があります。

<?php


namespace Vendor\Module\Setup;

use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Quote\Setup\QuoteSetupFactory;
use Magento\Sales\Setup\SalesSetupFactory;

class UpgradeData implements UpgradeDataInterface
{
    /**
     * @var QuoteSetupFactory
     */
    protected $quoteSetupFactory;

    /**
     * @var SalesSetupFactory
     */
    protected $salesSetupFactory;

    /**
     * @var EavSetupFactory
     */
    protected $eavSetupFactory;

    /**
     * Constructor
     */
    public function __construct(
        QuoteSetupFactory $quoteSetupFactory,
        SalesSetupFactory $salesSetupFactory,
        EavSetupFactory $eavSetupFactory
    ) {
        $this->quoteSetupFactory = $quoteSetupFactory;
        $this->salesSetupFactory = $salesSetupFactory;
        $this->eavSetupFactory = $eavSetupFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function upgrade(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $setup->startSetup();

        if (version_compare($context->getVersion(), '1.0.1', '<')) {

            /** @var \Magento\Quote\Setup\QuoteSetup $quoteInstaller */
            $quoteInstaller = $this->quoteSetupFactory->create(['resourceName' => 'quote_setup', 'setup' => $setup]);

            /** @var \Magento\Sales\Setup\SalesSetup $salesInstaller */
            $salesInstaller = $this->salesSetupFactory->create(['resourceName' => 'sales_setup', 'setup' => $setup]);

            //Add attributes to quote
            $entityAttributesCodes = [
                'bank_name' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
            ];

            foreach ($entityAttributesCodes as $code => $type) {
                $quoteInstaller->addAttribute('quote', $code, ['type' => $type, 'length' => 255, 'visible' => true, 'nullable' => true,]);
                $salesInstaller->addAttribute('order', $code, ['type' => $type, 'length' => 255, 'visible' => true, 'nullable' => true,]);
        }
        $setup->endSetup();
    }
}

例としてアップグレードスクリプトを使用しましたが、inscriptを使用して同じ機能を実行することもできます。

注文時に属性を挿入

このプロセスは少しトリッキーですが、それでも問題はありません。

  • app/code/Vendor/Module/etc/extension_attributes.xml次のコードで新しいファイルを作成します。

    <?xml version="1.0" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
        <extension_attributes for="Magento\Quote\Api\Data\AddressInterface">
            <attribute code="bank_name" type="string"/>
        </extension_attributes>
    </config>
  • app/code/Vendor/Module/view/frontend/requirejs-config.js次のコードでファイルを作成します。

    var config = {
        config: {
            mixins: {
                'Magento_Checkout/js/action/set-shipping-information': {
                    'Vendor_Module/js/order/set-shipping-information-mixin': true
                }
            }
        }
    };
  • app/code/Vendor/Module/view/frontend/web/js/order/set-shipping-information-mixin.js次のコードで新しいファイルを作成します。

    define([
        'jquery',
        'mage/utils/wrapper',
        'Magento_Checkout/js/model/quote'
    ], function ($, wrapper, quote) {
        'use strict';
    
        return function (setShippingInformationAction) {
    
            return wrapper.wrap(setShippingInformationAction, function (originalAction) {
                var shippingAddress = quote.shippingAddress();
                if (shippingAddress['extension_attributes'] === undefined) {
                    shippingAddress['extension_attributes'] = {};
                }
    
                // you can extract value of extension attribute from any place (in this example I use customAttributes approach)
                shippingAddress['extension_attributes']['bank_name'] = jQuery('input[name="bank_name"]').val();
                // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
                return originalAction();
            });
        };
    });
  • ファイルを作成する app/code/Vendor/Module/view/frontend/layout/checkout_index_index.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" 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="shipping-step" xsi:type="array">
                                                <item name="children" xsi:type="array">
                                                    <item name="shippingAddress" xsi:type="array">
                                                        <item name="children" xsi:type="array">
                                                            <item name="before-form" xsi:type="array">
                                                                <item name="children" xsi:type="array">
                                                                    <!-- Your form declaration here -->
                                                                    <item name="custom-checkout-form-container" xsi:type="array">
                                                                        <item name="component" xsi:type="string">Vendor_Module/js/view/order_attr</item>
                                                                        <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                        <item name="config" xsi:type="array">
                                                                            <item name="template" xsi:type="string">Vendor_Module/order_attr</item>
                                                                        </item>
                                                                        <item name="children" xsi:type="array">
                                                                            <item name="custom-checkout-form-fieldset" xsi:type="array">
                                                                                <!-- uiComponent is used as a wrapper for form fields (its template will render all children as a list) -->
                                                                                <item name="component" xsi:type="string">uiComponent</item>
                                                                                <!-- the following display area is used in template (see below) -->
                                                                                <item name="displayArea" xsi:type="string">custom-checkout-form-fields</item>
                                                                                <item name="children" xsi:type="array">
                                                                                    <item name="bank_name" xsi:type="array">
                                                                                        <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item>
                                                                                        <item name="config" xsi:type="array">
                                                                                            <!-- customScope is used to group elements within a single form (e.g. they can be validated separately) -->
                                                                                            <item name="customScope" xsi:type="string">customCheckoutForm</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="provider" xsi:type="string">checkoutProvider</item>
                                                                                        <item name="dataScope" xsi:type="string">customCheckoutForm.bank_name</item>
                                                                                        <item name="label" xsi:type="string">Clearance Full Name</item>
                                                                                        <item name="sortOrder" xsi:type="string">1</item>
                                                                                        <item name="validation" xsi:type="array">
                                                                                            <item name="required-entry" xsi:type="string">true</item>
                                                                                        </item>
                                                                                    </item>
                                                                                </item>
                                                                            </item>
                                                                        </item>
                                                                    </item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </argument>
                </arguments>
            </referenceBlock>
        </body>
    </page>
  • app/code/Vendor/Module/view/frontend/web/template/order_attr.html次のコードでファイルを作成します。

    <div>
        <form id="custom-checkout-form" class="form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
            <fieldset class="fieldset">
                <legend data-bind="i18n: 'Clearance Info'"></legend>
                <div><!-- ko i18n: 'This is clearance description' --><!-- /ko --></div>
                <!-- ko foreach: getRegion('custom-checkout-form-fields') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
                <!--/ko-->
            </fieldset>
        </form>
    </div>
  • app/code/Vendor/Module/view/frontend/web/js/view/order_attr.js次のコードでファイルを作成します。

    define([
        'Magento_Ui/js/form/form'
    ], function(Component) {
        'use strict';
        return Component.extend({
            initialize: function () {
                this._super();
                // component initialization logic
                return this;
            },
    
            /**
             * Form submit handler
             *
             * This method can have any name.
             */
            onSubmit: function() {
                // trigger form validation
                this.source.set('params.invalid', false);
                this.source.trigger('customCheckoutForm.data.validate');
    
                // verify that form data is valid
                if (!this.source.get('params.invalid')) {
                    // data is retrieved from data provider by value of the customScope property
                    var formData = this.source.get('customCheckoutForm');
                    // do something with form data
                    console.dir(formData);
                }
            }
        });
    });
  • app/code/Vendor/Module/etc/di.xml次のコードでファイルを作成します。

    <?xml version="1.0" encoding="UTF-8"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <type name="Magento\Checkout\Model\ShippingInformationManagement">
            <plugin name="save-in-quote" type="Vendor\Module\Plugin\AddOrderAttrToQuote" sortOrder="10"/>
        </type>
    </config>
  • app/code/Vendor/Module/Plugin/AddOrderAttrToQuote.php次のコードで新しいファイルを作成します。

    <?php
    
    namespace Vendor\Module\Plugin;
    
    
    class AddOrderAttrToQuote
    {
        protected $quoteRepository;
    
        public function __construct(
            \Magento\Quote\Model\QuoteRepository $quoteRepository
        ) {
            $this->quoteRepository = $quoteRepository;
        }
    
        /**
         * @param \Magento\Checkout\Model\ShippingInformationManagement $subject
         * @param $cartId
         * @param \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
         */
        public function beforeSaveAddressInformation(
            \Magento\Checkout\Model\ShippingInformationManagement $subject,
            $cartId,
            \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
        ) {
            $extAttributes = $addressInformation->getShippingAddress()->getExtensionAttributes();
            $bank_name = $extAttributes->getBankName();
            $quote = $this->quoteRepository->getActive($cartId);
            $quote->setBankName($bank_name);
            $extAttributes->setBankName("");
        }
    }
  • 新しいファイルを作成 app/code/Cleargo/NewAttributes/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_model_service_quote_submit_before">
            <observer name="handle_order_attrs" instance="Vendor\Module\Observer\HandleOrderAttrs" />
        </event>
    </config>
  • app/code/Vendor/Module/Observer/HandleOrderAttrs.php次のコードで新しいファイルを作成します。

    <?php        
    namespace Vendor\Module\Observer;
    
    use \Magento\Framework\Event\ObserverInterface;
    use \Magento\Framework\Event\Observer;
    
    class HandleOrderAttrs implements ObserverInterface
    {
        public function execute(Observer $observer)
        {
            $order = $observer->getOrder();
            $quote = $observer->getQuote();
            //Load the values
            $bank_name = $quote->getData("bank_name");
            $order->setData('bank_name', $bank_name)
                ->save();
        }
    }

支払いモジュールで注文属性を読み取る

ケース3の場合、サードパーティのモジュールからのものと思われます。とにかく、bank_name注文の値を取得したい場合は、次のコードを使用できます。

$order->getData('bank_name')

結論

order属性に対して行うのはかなりの作業ですが、キーポイントを取得すると、すべてがスムーズになります。


ありがとうございます。配送情報にカスタムタブを追加しましたが、カスタム支払い方法の下に追加したいと思います。お支払い方法をクリックすると表示されます
Akash

@Akashは解決策を見つけましたか?同じ
Tirth Patel
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.