Steps to Create Custom Payment Method in Magento 2

Here is a tutorial about how to create a custom payment method in Magento 2. Magento 2 offers a few default payment methods such as Bank Transfer, Cash on delivery, Check/money order, etc.

When you are planning to create custom payment method, you need to create custom module. In order to create a custom payment method follow the below steps:

How to Create Custom Payment Method in Magento 2

Follow below steps to create custom payment method in Magento 2.

Step 1.

First of all, Create a registration.php file to register your module at app/code/MD/CustomPayment/ file path and paste the below code:

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'MD_CustomPayment',
    __DIR__
);

Step 2.

Secondly, Create module.xml for defining your module at app/code/MD/CustomPayment/etc/ file path and paste the below code:

<?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="MD_CustomPayment" setup_version="1.0.0"/>
</config>

Step 3.

Then, Create a config.xml file to set your payment method active at app/code/MD/CustomPayment/etc/ and paste the below code:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Store/etc/config.xsd">
    <default>
        <payment>
            <custompayment>
                <payment_action>true</payment_action> <!-- You can use another method like authorize,capture etc.  -->
                <model>MD\CustomPayment\Model\PaymentMethod</model>
                <active>1</active>
                <title>MD Custom Payment</title>
                <order_status>pending_payment</order_status> <!-- Set your default order status -->
            </custompayment>
        </payment>
    </default>
</config>

Step 4.

Now, For display payment method in configuration Create system.xml file at app/code/MD/CustomPayment/etc/adminhtml/ and paste the below code:

<?xml version="1.0"?>

-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="payment">
                <group id="custompayment" translate="label" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>MD Custom Payment</label>
                    <field id="active" translate="label comment" sortOrder="1" type="select" showInDefault="1" showInWebsite="1" showInStore="0">
                        <label>Enable</label>
                        <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                    </field>
                </group>
        </section>
    </system>
</config>

In addition, you can add more fields in the custom payment method based on your requirement.

Step 5.

After that, For define payment method, Create PaymentMethod.php file at app/code/MD/CustomPayment/Model/ and paste the below code:

<?php

namespace MD\CustomPayment\Model;

/**
 * MD Custom Payment Method Model
 */
class PaymentMethod extends \Magento\Payment\Model\Method\AbstractMethod {

    /**
     * Payment Method code
     *
     * @var string
     */
    protected $_code = 'custompayment';
}

Step 6.

After that, To register template and render file create method-renderer.js file at app/code/MD/CustomPayment/view/frontend/web/js/view/payment/ and paste the below code:

define(
    [
        'uiComponent',
        'Magento_Checkout/js/model/payment/renderer-list'
    ],
    function (
        Component,
        rendererList
    ) {
        'use strict';
        rendererList.push(
            {
                type: 'custompayment',
                component: 'MD_CustomPayment/js/view/payment/method-renderer/custompayment'
            }
        );
        return Component.extend({});
    }
);

Step 7.

Now, Create custompayment.js file at app/code/MD/CustomPayment/view/frontend/web/js/view/payment/method-renderer/ and paste the below code:

define(
    [
        'Magento_Checkout/js/view/payment/default'
    ],
    function (Component) {
        'use strict';
  
        return Component.extend({
            defaults: {
                template: 'MD_CustomPayment/payment/custompayment'
            }
        });
    }
);

Step 8.

After that, Create custompayment.html template file at app/code/MD/CustomPayment/view/frontend/web/template/payment/ and paste the below code:

<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">
     <!-- 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')},
                        css: {disabled: !isPlaceOrderActionAllowed()},
                        enable: (getCode() == isChecked())
                        "
                        disabled>
                    <span data-bind="i18n: 'Place Order'"></span>
                </button>
            </div>
        </div>
    </div>
</div>

Step 9.

To display payment method at checkout page, Create checkout_index_index.xml file at app/code/MD/CustomPayment/view/frontend/layout/ and paste the below code:

<?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="billing-step" xsi:type="array">
                                            <item name="component" xsi:type="string">uiComponent</item>
                                            <item name="children" xsi:type="array">
                                                <item name="payment" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="renders" xsi:type="array">
                                                            <!-- merge payment method renders here -->
                                                            <item name="children" xsi:type="array">
                                                                <item name="custompayment" xsi:type="array">
                                                                    <item name="component" xsi:type="string">MD_CustomPayment/js/view/payment/method-renderer</item>
                                                                    <item name="methods" xsi:type="array">
                                                                        <item name="custompayment" xsi:type="array">
                                                                            <item name="isBillingAddressRequired" xsi:type="boolean">true</item>
                                                                        </item>
                                                                    </item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Now, execute this below command:

php bin/magento s:up
php bin/magento s:s:d -f
php bin/magento c:c

This will let you see your custom payment method. We have tried to cover all the steps to help you create a custom payment method on your Magento store. If in case we missed out on anything, feel free to reach us out!


Also read:

How to Restrict Payment Methods by Attribute/Category in Magento 2

How to Disable a Payment Method Programmatically in Magento 2

How to Get the Payment Method Title of an Order in Magento 2

How to Create Custom Payment Method in Magento 2

How to Setup Cash on Delivery (COD) Payment Method in Magento 2

How to Configure Braintree Payment Method in Magento 2

How to Get List of Payment Methods using Command Line in Magento 2

How to Disable Payment Method for Certain Customer Groups in Magento 2