Creating a Payment Gateway Integration in Magento 2

Magento 2 allows you to create unlimited custom payment methods based on your business requirements. Additional payment options improve checkout experience and reduce cart abandonment.

How to Create a Payment Gateway in Magento 2

Step 1: Create a Custom Module

Create the module configuration file app/code/Hikmadh/Pay/etc/module.xml

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

Create registration file app/code/Hikmadh/Pay/registration.php

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

Enable the module:

php bin/magento module:enable Hikmadh_Pay
php bin/magento setup:upgrade

Step 2: Create system.xml (Admin Configuration)

File: app/code/Hikmadh/Pay/etc/adminhtml/system.xml

<?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="testpayment" translate="label" sortOrder="2"
                   showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Test Payment Method</label>

                <field id="active" translate="label" type="select"
                       sortOrder="1" showInDefault="1" showInWebsite="1">
                    <label>Enable</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                </field>
            </group>
        </section>
    </system>
</config>

Step 3: Create config.xml

File: app/code/Hikmadh/Pay/etc/config.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <payment>
            <testpayment>
                <payment_action>authorize</payment_action>
                <model>Hikmadh\Pay\Model\PaymentMethod</model>
                <active>1</active>
                <title>Test Payment Method</title>
                <order_status>pending_payment</order_status>
            </testpayment>
        </payment>
    </default>
</config>

Step 4: Create Payment Method Model

File: app/code/Hikmadh/Pay/Model/PaymentMethod.php

<?php
namespace Hikmadh\Pay\Model;

class PaymentMethod extends \Magento\Payment\Model\Method\AbstractMethod
{
    protected $_code = 'testpayment';
}

Step 5: Add Payment Method to Checkout Page

checkout_index_index.xml

File: app/code/Hikmadh/Pay/view/frontend/layout/checkout_index_index.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>
        <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="children" xsi:type="array">
                                                <item name="payment" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="renders" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="testpayment" xsi:type="array">
                                                                    <item name="component" xsi:type="string">
                                                                        Hikmadh_Pay/js/view/payment/method-renderer
                                                                    </item>
                                                                    <item name="methods" xsi:type="array">
                                                                        <item name="testpayment" 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>

method-renderer.js

define([
    'uiComponent',
    'Magento_Checkout/js/model/payment/renderer-list'
], function (Component, rendererList) {
    'use strict';

    rendererList.push({
        type: 'testpayment',
        component: 'Hikmadh_Pay/js/view/payment/method-renderer/testpayment'
    });

    return Component.extend({});
});

testpayment.js

define([
    'Magento_Checkout/js/view/payment/default'
], function (Component) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'Hikmadh_Pay/payment/testpayment'
        }
    });
});

testpayment.html

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