In this post you will learn how to create custom Payment Module in Magento 2. For creating a Payment Module in Magento 2 you need to follow the below steps and your Payment Module will be ready.
Here “Cedcommerce” is our workspace and “Payment” is our extension name.
1. Create app/code/Cedcommerce/Payment/registration.php
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Cedcommerce_Payment', __DIR__ );
2. Create app/code/Cedcommerce/Payment/etc/module.xml
<?xml version="1.0"?> <config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> <module name="Cedcommerce_Payment" setup_version="1.0.0" schema_version="1.0.0"></module> </config>
After that you need to run the following commands to register your module:
For Linux users-
/opt/lampp/bin/php bin/magento setup:upgrade
For Windows Users-
php bin/magento setup:upgrade
3. Create app/code/Cedcommerce/Payment/etc/adminhtml/system.xml
<?xml version="1.0"?> <!-- /** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */--> <config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Config/etc/system_file.xsd"> <system> <section id="payment"> <group id="money" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Payment Cedcommerce </label> <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Enabled</label> <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> </field> <field id="title" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Title</label> </field> <field id="order_status" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0"> <label>New Order Status</label> <source_model>Cedcommerce\Payment\Model\Config\Source\Order\Status\Pendingpayment</source_model> </field> <field id="allowspecific" translate="label" type="allowspecific" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Payment from Applicable Countries</label> <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model> </field> <field id="specificcountry" translate="label" type="multiselect" sortOrder="41" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Payment from Specific Countries</label> <source_model>Magento\Directory\Model\Config\Source\Country</source_model> <can_be_empty>1</can_be_empty> </field> <field id="instructions" translate="label" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Instructions</label> </field> <field id="sort_order" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Sort Order</label> <frontend_class>validate-number</frontend_class> </field> </group> </section> </system> </config>
After creating system.xml you can see this section by going to admin>stores>configurations>sales>Payment methods.
4. Create app/code/Cedcommerce/Payment/etc/config.xml, it provides default values for your admin configurations.
<?xml version="1.0"?> <!-- /** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */--> <config xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Store/etc/config.xsd"> <default> <payment> <money> <active>1</active> <title>Money</title> <order_status>pending_payment</order_status> <instructions>Instruction.</instructions> <payment_action>true</payment_action> <model>Cedcommerce\Payment\Model\Money</model> <group>offline</group> </money> </payment> </default> </config>
5. Create app/code/Cedcommerce/Payment/etc/payment.xml
<?xml version="1.0"?> <!-- /** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */--> <payment xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Magento/Payment/etc/payment.xsd"> <groups> <group id="offline"> <label>Offline Payment Methods</label> </group> </groups> <methods> <method name="money"> <allow_multiple_address>1</allow_multiple_address> </method> </methods> </payment>
6. Create app/code/Cedcommerce/Payment/Model/Config/Source/Order/Status/Pendingpayment.php
<?php /** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */namespace Cedcommerce\Payment\Model\Config\Source\Order\Status; use Magento\Sales\Model\Order; use Magento\Sales\Model\Config\Source\Order\Status; /** * Order Status source model */class Pendingpayment extends Status { /** * @var string[] */ protected $_stateStatuses = [Order::STATE_PENDING_PAYMENT]; }
7. Create app/code/Cedcommerce/Payment/Model/Money.php
<?php /** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */namespace Cedcommerce\Payment\Model; /** * Pay In Store payment method model */class Money extends \Magento\Payment\Model\Method\AbstractMethod { /** * Payment code * * @var string */ protected $_code = 'money'; /** * Availability option * * @var bool */ protected $_isOffline = true; }
8. Create app/code/Cedcommerce/Payment/view/frontend/layout/checkout_index_index.xml
<?xml version="1.0"?> <!-- /** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */--> <page xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/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"> <!-- merge payment method renders here --> <item name="children" xsi:type="array"> <item name="payment-payments" xsi:type="array"> <item name="component" xsi:type="string">Cedcommerce_Payment/js/view/payment/money</item> <item name="methods" xsi:type="array"> <item name="money" 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>
9. Create app/code/Cedcommerce/Payment/view/frontend/web/js/view/payment/method-renderer/money-method.js
/** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. *//*browser:true*//*global define*/define( [ 'Magento_Checkout/js/view/payment/default' ], function (Component) { 'use strict'; return Component.extend({ defaults: { template: 'Cedcommerce_Payment/payment/money' }, /** Returns send check to info */ getMailingAddress: function() { return window.checkoutConfig.payment.checkmo.mailingAddress; }, }); } );
10. Create app/code/Cedcommerce/Payment/view/frontend/web/js/view/payment/money.js
/** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. *//*browser:true*//*global define*/define( [ 'uiComponent', 'Magento_Checkout/js/model/payment/renderer-list' ], function ( Component, rendererList ) { 'use strict'; rendererList.push( { type: 'money', component: 'Cedcommerce_Payment/js/view/payment/method-renderer/money-method' } ); /** Add view logic here if needed */ return Component.extend({}); } );
11. Create app/code/Cedcommerce/Payment/view/frontend/web/template/payment/money.html
<!-- /** * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */--> <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>
Your Payment Method is ready now. You can place an order and check that your payment method is applicable or not.
When you will order any product you will see this payment method (frontend name: Money) on checkout page.
This brings us to the end of this blog. Please feel free to share your comments with us.