How to create a custom payment method in Magento 2

Many new eCommerce store owners think that why to choose Magento for their store. But there are so many reasons to choose Magento. Moreover, online shopping is not just about buying a product that you like. But there are also a few things that include in the customer's shopping experience. Such as product size, color, quantity, quality, price, etc. Furthermore, the main process of online product purchasing is a payment method. If you compare it with other platforms then Magento is the most secure open-source e-commerce platform. However, Magento supports other payments methods and admin can also create their own custom payment method. Therefore, today we will learn how to create a custom payment method in Magento 2.

Furthermore, it's also important to choose the right hosting server for your Magento store. Upgrade your hosting server to nexcess or hostinger. They are the most popular ones and provide the best service above all.

How to create a custom payment method in Magento 2.

Firstly, to create a custom payment method, we need to create some files to render it to the checkout page in Magento 2. So let's get started!

Step 1 - First of all, you have to create a registration.php in app/code/Milople/CustomPayment/  to register your module. Paste the below code in the file.

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Milople_CustomPayment',
    __DIR__
);

Step 2 - Create module.xml file under app/code/Milople/CustomPayment/etc/ to declare your module.

<?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="Milople_CustomPayment" setup_version="0.1.0">
        <sequence>
            <module name="Magento_Sales"/>
            <module name="Magento_Payment"/>
            <module name="Magento_Checkout"/>
            <module name="Magento_Directory" />
            <module name="Magento_Config" />
        </sequence>
    </module>
</config>

Step 3 - Now, create a config.xml file at app/code/Milople/CustomPayment/etc/ to set your payment method active.

<?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>Milople\CustomPayment\Model\PaymentMethod</model>
                <active>1</active>
                <title>Milople Custom Payment</title>
                <order_status>pending_payment</order_status> 
                <!-- Set your default order status -->
            </custompayment>
        </payment>
    </default>
</config>

Step 4 - Create a system.xml file to display the payment method in configuration at app/code/Milople/CustomPayment/etc/adminhtml/. Paste the following code in the system.xml file.

<?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>Milople 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>

Moreover, you can add other necessary fields here as you want.

Step 5 - Then, We have to define the payment method. So create a paymentmethod.php file at app/code/Milople/CustomPayment/Model/

<?php

namespace Milople\CustomPayment\Model;

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

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

Step 6 - Now create a javascript file MethodRender.js at app/code/Milople/CustomPayment/view/frontend/web/js/view/payment/. Furthermore, this file will help you to register the template and to render the file.

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

Step 7 - After that, you have to create a custompayment.js javascript file at app/code/Milople/CustomPayment/view/frontend/web/js/view/payment/method-renderer/.

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

Step 8 - Then, create a KO template customtemplate.html file at app/code/Milople/CustomPayment/view/frontend/web/template/payment/.

<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 - At the end, create a checkout_index_index.xml file at app/code/MD/CustomPayment/view/frontend/layout/ to display the custom payment method at the checkout page.

<?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>

Step 10 - After that, run the following commands.

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

In addition, you can implement various custom methods to your Magento store with above listed simple steps.  Integrate this custom payment method with your Magento 2 store easily.

Conclusion

When you are running an eCommerce store, you first need to implement the payment method. However, it is an initial step of your online business. However, multiple payment methods will also help you to increase the customer conversation rate. The above-listed steps are very easy to implement. I hope this article, on how to create a custom payment method in Magento 2 will help you. Moreover, don't hesitate to contact us if you face any further difficulties regarding Magento development.

Keep Learning.