Before moving forward, we have to create a basic module, However, if you already know how to create a basic module and enable it, you can skip the initial steps.
We will create module under namespace of CWM (Coffeewithmagento).
First of all, we will register our module. For this, we will create registration.php file.
Path : app/code/CWM/CustomPayment/registration.php
1 2 3 4 5 6 |
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'CWM_CustomPayment', __DIR__ ); |
Another file, we need to create is module.xml
Path : app/code/CWM/CustomPayment/etc/module.xml
1 2 3 4 |
<?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="CWM_CustomPayment" setup_version="1.0.0"/> </config> |
Now, we will enable module using command line.
bin/magento module:enable CWM_CustomPayment -c
Payment method
If you go and check Magento’s default payment methods, you will find payment method title, enable/disable, new order status when order placed using this payment method, in which countries your payment method allows to use etc.
All payment methods are defined under Stores -> Configuration -> Sales -> Payment Methods. Therefore, we will also create the same configuration.
To achieve above, we need to system.xml file under module.
Step 1 : system.xml
Path : app/code/CWM/CustomPayment/etc/adminhtml/system.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?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" showInDefault="1" showInStore="1" showInWebsite="1" translate="label" sortOrder="100"> <group id="custompayment" showInDefault="1" showInStore="1" showInWebsite="1" translate="label" sortOrder="10"> <label>Pay on Coffee</label> <field id="active" showInDefault="1" showInStore="1" showInWebsite="1" translate="label" sortOrder="10" type="select"> <label>Enabled</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> <field id="title" showInDefault="1" showInStore="1" showInWebsite="1" translate="label" sortOrder="15" type="text"> <label>Payment Method Title</label> </field> <field id="order_status" showInDefault="1" showInStore="1" showInWebsite="1" translate="label" sortOrder="20" type="select"> <label>New Order Status</label> <source_model>Magento\Sales\Model\Config\Source\Order\Status\NewStatus</source_model> <comment>Select order status when new order placed using this payment method</comment> </field> <field id="allowspecific" showInDefault="1" showInStore="1" showInWebsite="1" translate="label" sortOrder="25" type="allowspecific"> <label>Payment from Applicable Countries</label> <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model> </field> <field id="specificcountry" showInDefault="1" showInStore="1" showInWebsite="1" translate="label" sortOrder="30" type="multiselect"> <label>Payment from Applicable Countries</label> <source_model>Magento\Directory\Model\Config\Source\Country</source_model> <can_be_empty>1</can_be_empty> </field> <field id="sort_order" showInDefault="1" showInStore="1" showInWebsite="1" translate="label" sortOrder="35" type="text"> <label>Sort Order</label> </field> </group> </section> </system> </config> |
Step 2: config.xml
Why config.xml? A question in mind, let’s clear it. config.xml will declare default values of our system.xml file fields and default options. Don’t get it, don’t worry you will get it at end of this.
An eagle eye, notice that we have used <model> which is used for integration with Sales and Checkout modules.
You can read more about it at https://devdocs.magento.com/guides/v2.4/payments-integrations/base-integration/payment-option-config.html
Path : app/code/CWM/CustomPayment/etc/config.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?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> <custompayment> <active>1</active> <model>CWM\CustomPayment\Model\Payment\CustomPayment</model> <order_status>pending</order_status> <title>Pay on Coffee</title> <allowspecific>0</allowspecific> <group>offline</group> </custompayment> </payment> </default> </config> |
Step 3 : payment.xml
Now, we will create payment.xml. What is the use of it?
We have two types of payment methods,
1) Offline
2) Online.
Inside payment.xml, we will define weather payment method is offline or online, multiple address allow with checkout, credit cards support it or not etc etc.
Path : app/code/CWM/CustomPayment/etc/payment.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" ?> <payment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Payment:etc/payment.xsd"> <groups> <group id="offline"> <label>Offline Payment Methods</label> </group> </groups> <methods> <method name="custompayment"> <allow_multiple_address>1</allow_multiple_address> </method> </methods> </payment> |
Step 5: CustomPayment.php
Path : app/code/CWM/CustomPayment/Model/Payment/CustomPayment.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?php declare(strict_types=1); namespace CWM\CustomPayment\Model\Payment; class CustomPayment extends \Magento\Payment\Model\Method\AbstractMethod { /** * payment method code */ protected $_code = "custompayment"; /** * type of payment method */ protected $_isOffline = true; /** * to check weather payment method is active * @param \Magento\Quote\Api\Data\CartInterface * @return bool */ public function isAvailable( \Magento\Quote\Api\Data\CartInterface $quote = null ) { return parent::isAvailable($quote); } } |
Our admin area work is done, now we will create files for frontend.
We all know that payment methods will render (display) on the checkout page. Therefore, we will use a layout XML file to render it.
Step 6: checkout_index_index.xml
Path : app/code/CWM/CustomPayment/view/frontend/layout/checkout_index_index.xml
In this file we will define, payment method’s render component.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<?xml version="1.0" ?> <page layout="1column" 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="custompayment" xsi:type="array"> <item name="component" xsi:type="string">CWM_CustomPayment/js/view/payment/custompayment</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 7 : custompayment.js
In this file, we have to declare renderer component which will used to display.
Path : app/code/CWM/CustomPayment/view/frontend/web/js/view/payment/custompayment.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
define( [ 'uiComponent', 'Magento_Checkout/js/model/payment/renderer-list' ], function ( Component, rendererList ) { 'use strict'; rendererList.push( { type: 'custompayment', component: 'CWM_CustomPayment/js/view/payment/method-renderer/custompayment-method-component' } ); return Component.extend({}); } ); |
Step 8: custompayment-method-component.js
However, we used js files till now, but in this file , define html file which can use methods this js file and it’s above.
Path: app/code/CWM/CustomPayment/view/frontend/web/js/view/payment/method-renderer/custompayment-method-component.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
define( [ 'Magento_Checkout/js/view/payment/default' ], function (Component) { 'use strict'; return Component.extend({ defaults: { template: 'CWM_CustomPayment/payment/custompayment' }, getMailingAddress: function ( return window.checkoutConfig.payment.checkmo.mailingAddress; }, }); } |
Step 9: custompayment.html
Path: app/code/CWM/CustomPayment/view/frontend/web/template/payment/custompayment.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<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> |
All coding is done now, need to run deployment commands and check your custom payment method.
commands : bin/magento s:s:d && bin/magento c:f
If like efforts, Please share, comment and subscribe for future posts and inspire more.