custom payment method Magento 2

magento 2 custom payment method

In this article we explain about creating new custom payment method in magento 2 from the new custom module. The payment module details are
Namespace – Explorer
Module – Payment
Payment – Testpay

To register the module in magento 2 use registration.php and module.xml file with having the module name there. To know more about the module creation click here.


To register the module create registration.php file in the module.

# Explorer/Payment/registration.php


<?xml version="1.0"?>
<!--  Explorer/Payment/etc/module.xml -->
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
  <module name="Explorer_Payment" setup_version="2.0.0">


Every payment method should be listed in payment method area of store configuration in admin. Payment method should give their required admin configurations like payment method activeness api key etc here. The main thing to be noted here is all the fields should be come under the section name ‘payment’ and group name ‘‘. In our case is testpay so it is mentione in group id.

<?xml version="1.0"?>
<!--  Explorer/Payment/etc/adminhtml/system.xml -->
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="../../../Config/etc/system_file.xsd">
        <section id="payment">
            <group id="testpay" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
                <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0">
                <field id="title" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <field id="order_status" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>New Order Status</label>
                <field id="allowspecific" translate="label" type="allowspecific" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Payment from Applicable Countries</label>
                <field id="specificcountry" translate="label" type="multiselect" sortOrder="41" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Payment from Specific Countries</label>
                <field id="instructions" translate="label" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
                <field id="sort_order" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Sort Order</label>


The config.xml will have the default value of filled system configuration fields. The main thing to note here is the model() using for the payment method.

<?xml version="1.0"?>
<!--  Explorer/Payment/etc/config.xml -->
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="../../Store/etc/config.xsd">


The next important file is payment.xml file, should tell about the configuration in etc folder

<?xml version="1.0"?>
<!--  Explorer/Payment/etc/payment.xml -->
<payment xmlns:xsi=""
        <group id="offline">
            <label>Offline Payment Methods</label>
        <method name="testpay">

Testpay Model

Create the payment method model file in the below mentioned direction. The model file should define the payment method code.

namespace Explorer\Payment\Model;
class Testpay extends \Magento\Payment\Model\Method\AbstractMethod
    protected $_code = 'testpay';
    protected $_isOffline = true;


Next the important file is layout which is used to display our new payment method method in the checkout page. The important thing here is addingout payment source js file and method name in the component file of layout ‘Explorer_Payment/js/view/payment/testpay‘.

<?xml version="1.0"?>
<!--  Explorer/Payment/view/frontend/layout/checkout_index_index.xml -->
<page xmlns:xsi="" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
        <referenceBlock name="checkout.root">
                <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">
                                                            <!-- merge payment method renders here -->
                                                            <item name="children" xsi:type="array">
                                                                <item name="payment-payments" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Explorer_Payment/js/view/payment/testpay</item>
                                                                    <item name="methods" xsi:type="array">
																		 <item name="testpay" xsi:type="array">
                                                                            <item name="isBillingAddressRequired" xsi:type="boolean">true</item>


It is necessary to create the js with the following name {payment method name}-method.js. The default structure of payment js was given below.

/** Explorer/Payment/view/frontend/web/js/view/payment/testpay.js **/
    function (
    ) {
        'use strict';
                type: 'testpay',
                component: 'Explorer_Payment/js/view/payment/method-renderer/testpay-method'
        /** Add view logic here if needed */
        return Component.extend({});


Then the next step create the component js file which was mentioned above.The payment method component should extend the template path here.

/** Explorer/Payment/view/frontend/web/js/view/payment/testpay-method.js **/
    function (Component) {
        'use strict';

        return Component.extend({
            defaults: {
                template: 'Explorer_Payment/payment/testpay'

            /** Returns send check to info */
            getMailingAddress: function() {
                return window.checkoutConfig.payment.checkmo.mailingAddress;


To use the backend system configuration field value in payment method step, use the variable ‘window.checkoutConfig’ in js file. Here in our custom payment method to show the user mailing address we are using ‘window.checkoutConfig.payment.checkmo.mailingAddress’;

Testpay template

The last final step, asusual procedure of magento create the required payment method template file. The default structure of the template file is given below

<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
    <div class="payment-method-title field choice">
        <input type="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 class="payment-method-content">
        <div class="payment-method-billing-address">
        <div class="checkout-agreements-block">
        <div class="actions-toolbar">
            <div class="primary">
                <button class="action primary checkout"
                        click: placeOrder,
                        attr: {title: $t('Place Order')},
                        css: {disabled: !isPlaceOrderActionAllowed()},
                        enable: (getCode() == isChecked())
                    <span data-bind="i18n: 'Place Order'"></span>

In magento 2.x the place order button comes in the payment method steps so it is necessary to have place order button html section there. Thanks for watching this post. Enjoy your day 🙂

  • Hi,

    I am new to Magento, and I followed above instructions, I can see payment module in backend side but I am not able to see that on frontend side on checkout page.

    Please guide me as I need to work on online payment gateway for Magento2, I am taking above as a example.


      • Hi Namita,

        Clear your cache and check it out. In short to do it from terminal use these commands

        sudo chmod -R 777 var pub
        php bin/magento setup:upgrade
        sudo rm -rf var/cache/* var/generation/*

        • Hello Karthick,

          Thank you so much for your reply. I followed your instructions but I am still not able to get the payment method on checkout page.
          I tried to install via composer also but still no luck. Is there any other configuration in Magento admin panel.
          I Enabled this module through stores\configuration\advance\advance also.
          I Enabled through payment method also.

          What else I need to do? Please help me I will really appreciate your help.


  • Hi,

    I have tried this with Magento CE 2.0.7 version, but unfortunately this testpayment mwthod is not appearing in front-end, this payment option is appearing in backend. can you check this.?