3

I've created a custom payment method in Magento.

The custom payment method requires additional fields to be filled in and are required for that specific payment method only.

I've found an answer in this post: Magento 2 - How to add a custom field to checkout and then send it

But this will add custom fields in every payment method...

So my question is, is it possible to add custom form in a specific payment method?

1 Answer 1

4

app/code/Ktpl/Ordercomment/etc/frontned/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\Block\Checkout\LayoutProcessor">
        <plugin name="sr_add_custom_field"
                type="Ktpl\Ordercomment\Plugin\Checkout\Model\Checkout\LayoutProcessor" sortOrder="100"/>
    </type>
</config>

app/code/Ktpl/Ordercomment/Plugin/Checkout/Model/Checkout/LayoutProcessor.php

<?php
namespace Ktpl\Ordercomment\Plugin\Checkout\Model\Checkout;

class LayoutProcessor
{
    public function afterProcess(
        \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
        array $jsLayout
    ){
        $jsLayout = [
            'component' => 'Magento_Ui/js/form/element/abstract',
            'config' => [
                'customScope' => 'customCheckoutForm',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/input',
            ],
            'provider' => 'checkoutProvider',
            'dataScope' => 'customCheckoutForm.text_field',
            'label' => 'Text Field',
            'sortOrder' => 1,
            'validation' => [
                'required-entry' => true,
            ],
        ];

        return $jsLayout;
    }
}

app/code/Ktpl/Ordercomment/view/frontend/layout/checkout_index_index.xml

<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="custom-checkout-form-container" xsi:type="array">
                                            <item name="component" xsi:type="string">Ktpl_Ordercomment/js/view/ordercomment</item>
                                            <item name="provider" xsi:type="string">checkoutProvider</item>
                                            <item name="sortOrder" xsi:type="string">2</item>
                                            <item name="children" xsi:type="array">
                                                <item name="custom-checkout-form-fieldset" xsi:type="array">

                                                    <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="text_field" 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/textarea</item>
                                                            </item>
                                                            <item name="provider" xsi:type="string">checkoutProvider</item>
                                                            <item name="dataScope" xsi:type="string">customCheckoutForm.ordercomment</item>
                                                            <item name="label" xsi:type="string">Order Comment</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>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

app/code/Ktpl/Ordercomment/view/frontend/web/js/view/ordercomment.js

define(
    [
        'ko',
        'Magento_Ui/js/form/form',
        'underscore',
        'Magento_Checkout/js/model/step-navigator'
    ],
    function (
        ko,
        Component,
        _,
        stepNavigator
    ) {
        'use strict';
        /**
         *
         * mystep - is the name of the component's .html template,
         * my_module - is the name of the your module directory.
         *
         */
        return Component.extend({
            defaults: {
                template: 'Ktpl_Ordercomment/ordercomment'
            },

            //add here your logic to display step,
            isVisible: ko.observable(false),


            initialize: function () {
                this._super();
                // register your step
                stepNavigator.registerStep(
                    //step code will be used as step content id in the component template
                    'custom-checkout-form-container',
                    //step alias
                    'custom-checkout-form-container',
                    //step title value
                    'Order Comment',
                    //observable property with logic when display step or hide step
                    this.isVisible,

                    _.bind(this.navigate, this),

                    /**
                     * sort order value
                     * 'sort order value' < 10: step displays before shipping step;
                     * 10 < 'sort order value' < 20 : step displays between shipping and payment step
                     * 'sort order value' > 20 : step displays after payment step
                     */
                    15
                );
                return this;
            },

            /**
             * The navigate() method is responsible for navigation between checkout step
             * during checkout. You can add custom logic, for example some conditions
             * for switching to your custom step
             */
            navigate: function () {
                var self = this;
                //getPaymentInformation().done(function () {
                    self.isVisible(true);
                //});
            },

            navigateToNextStep: function () {

                this.source.set('params.invalid', false);
                this.source.trigger('customCheckoutForm.data.validate');
                if (!this.source.get('params.invalid')) {
                    var formData = this.source.get('customCheckoutForm');
                    // do something with form data
                    console.dir(formData);
                }
                //stepNavigator.next();
            }
        });
    }
);

app/code/Ktpl/Ordercomment/view/frontend/web/template/ordercomment.html

<li id="custom-checkout-form" data-bind="fadeVisible: isVisible">
    <div class="step-title" data-bind="i18n: 'Order Comment'" data-role="title"></div>
    <div id="checkout-step-title"
         class="step-content"
         data-role="content">

        <form name="customCheckoutForm" id="customCheckoutForm" class="form" data-bind="submit: navigateToNextStep" ><!---->
            <fieldset class="fieldset">
                <legend data-bind="i18n: '  '"></legend>
                <!-- ko foreach: getRegion('custom-checkout-form-fields') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
                <!--/ko-->
            </fieldset>
            <div class="actions-toolbar">
                <div class="primary">
                    <button data-role="opc-continue" type="submit" class="button action continue primary">
                        <span><!-- ko i18n: 'Next'--><!-- /ko --></span>
                    </button>
                </div>
            </div>

        </form>

    </div>
</li>

this worked for me you can try this

1
  • Sorry for the late response, above will just add a textfield into the checkout page. This will not handle the POST content.... Jul 7, 2017 at 12:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.