How to Create a Basic Payment Module in Magento 2

Magento 2 provides a powerful module system that allows developers to add custom payment methods. In this tutorial, we will create a basic payment module that shows up on the checkout page but does not process real payments. This is perfect for testing or learning how to develop payment modules.

1. Prepare Module Structure

Assume your module is called Vendor_Payment, with Vendor as your namespace.

app/code/Vendor/Payment/
├── etc
│   ├── module.xml
│   └── frontend
│       └── di.xml
├── registration.php
├── composer.json
├── Model
│   └── Payment.php
└── view
    └── frontend
        └── layout
            └── checkout_index_index.xml

2. Declare the Module

File: app/code/Vendor/Payment/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="Vendor_Payment" setup_version="1.0.0"/>
</config>

File: app/code/Vendor/Payment/registration.php

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

3. Create Payment Model

Magento 2 payment methods are implemented as a model extending \Magento\Payment\Model\Method\AbstractMethod.

File: app/code/Vendor/Payment/Model/Payment.php

<?php
namespace Vendor\Payment\Model;

use Magento\Payment\Model\Method\AbstractMethod;

class Payment extends AbstractMethod
{
    const PAYMENT_METHOD_CODE = 'vendor_payment';

    protected $_code = self::PAYMENT_METHOD_CODE;

    // Allow the payment method to appear in the frontend
    protected $_isOffline = true; // Offline payment (no API connection)
}

Note: For real online payments, you would override authorize() or capture() methods. In this basic module, we only display it at checkout.

4. Register the Payment Method in di.xml

File: app/code/Vendor/Payment/etc/frontend/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\Payment\Model\MethodList">
        <arguments>
            <argument name="methods" xsi:type="array">
                <item name="vendor_payment" xsi:type="string">Vendor\Payment\Model\Payment</item>
            </argument>
        </arguments>
    </type>
</config>

5. Add Payment Method to Checkout (UI)

Magento 2 uses UI Components for frontend checkout.

File: app/code/Vendor/Payment/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>
        <referenceContainer name="checkout.root">
            <block class="Magento\Framework\View\Element\Template" name="vendor_payment" template="Vendor_Payment::payment.phtml"/>
        </referenceContainer>
    </body>
</page>

Optional template: view/frontend/templates/payment.phtml

<div>
    <p>Test Payment Method: Vendor Payment</p>
</div>

6. Enable the Module

  1. Run upgrade command:
    php bin/magento setup:upgrade
  2. Clear cache:
    php bin/magento cache:clean
  3. Check module status:
    php bin/magento module:status

You should see Vendor_Payment as Enabled.

7. Test on Frontend

  • Visit the Checkout page.
  • You will see the payment method "Vendor Payment" available.
  • This module does not perform real payments yet but provides a foundation for further development.

8. Next Steps (Optional Enhancements)

  • Add a form to collect payment details (card, bank code, etc.)
  • Override methods like authorize() or capture() for online payments
  • Add system configuration to enable/disable the module and change display name
  • Use KnockoutJS to render responsive payment forms

Conclusion

You have successfully created a basic payment module for Magento 2 that appears at checkout. This foundation allows you to develop more advanced payment integrations or use it as a testing module for learning Magento 2 module development.