Creating an Offline Payment Method in Magento 2

By Sreejiith CB on October 3, 2017

Magento 2 provides extensive in-built payment methods which is a basic requirement for any e-commerce website. PayPal, Cash-on-delivery, Check or money order etc. are some of those. Some of them are online payment methods (eg: PayPal) where you will have to pay money online while some are offline (eg: Cash-on-delivery). These methods will help you to add normal product purchase functionality in your website. But there may occur some scenarios where you will need additional offline payment methods. Here we are about to see how to create an Offline Payment Method named “Invoice 30” (Invoice payable in 30 days) in Magento 2.

Step 1: Create payment method module.

1.Create directory app/code/Pits/OfflinePaymentMethods/

2.Create file registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Pits_OfflinePaymentMethods',
__DIR__
);

3.Create file module.xml in app/code/Pits/OfflinePaymentMethods/etc/

<?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="Pits_OfflinePaymentMethods" setup_version="0.1.0">
<sequence>
<module name="Magento_Store"/>
<module name="Magento_Catalog"/>
</sequence>
</module>
</config>

Step 2: Declare payment method module.

1. Create file payment.xml in app/code/Pits/OfflinePaymentMethods/etc/

<?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="invoice30">
<allow_multiple_address>1</allow_multiple_address>
</method>
</methods>
</payment>

2. Create file config.xml in app/code/Pits/OfflinePaymentMethods/etc/

<?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>
<invoice30>
<active>1</active>
<model>Pits\OfflinePaymentMethods\Model\Invoice30</model>
<order_status>pending</order_status>
<title>Offline Payment Method 1</title>
<allowspecific>0</allowspecific>
<group>offline</group>
</invoice30>
</payment>
</default>
</config>

Step 3: Create a model for the payment method module.

1. Create file Invoice30.php in app/code/Pits/OfflinePaymentMethods/Model/

<?php
namespace Pits\OfflinePaymentMethods\Model;
class Invoice30 extends \Magento\Payment\Model\Method\AbstractMethod
{
const PAYMENT_METHOD_CUSTOM_INVOICE_CODE = 'invoice30';
/**
* Payment method code
*
* @var string
*/
protected $_code = self::PAYMENT_METHOD_CUSTOM_INVOICE_CODE;
}

Step 4: Display payment method in checkout page.

In previous steps, we declared the module, config and model files. Now we need to display tthe payment method in magento 2 checkout page.

1. Create layout file checkout_index_index.xml in app/code/Pits/OfflinePaymentMethods/view/frontend/layout/

<?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">
<!-- merge payment method renders here -->
<item name="children" xsi:type="array">
<item name="pits-offlinepaymentmethods" xsi:type="array">
<item name="component" xsi:type="string">Pits_OfflinePaymentMethods/js/view/payment/offline-payments</item>
<item name="methods" xsi:type="array">
<item name="invoice30" 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>

2. Create js files to load knockout.js template files in checkout page.

a) Create js file offline-payment.js in app/code/Pits/OfflinePaymentMethods/view/frontend/web/js/view/payment/

define(
[
'uiComponent',
'Magento_Checkout/js/model/payment/renderer-list'
],
function (
Component,
rendererList
) {
'use strict';
rendererList.push(
{
type: 'invoice30',
component: 'Pits_OfflinePaymentMethods/js/view/payment/method-renderer/invoice30-method'
}
);
/** Add view logic here if needed */
return Component.extend({});
}
);

b) Create js file invoice30-method.js in app/code/Pits/OfflinePaymentMethods/view/frontend/web/js/view/payment/method-renderer/

define(
[
'Magento_Checkout/js/view/payment/default'
],
function (Component) {
'use strict';
return Component.extend({
defaults: {
template: 'Pits_OfflinePaymentMethods/payment/invoice30'
},
/** Returns send check to info */
getMailingAddress: function() {
return window.checkoutConfig.payment.invoice30.mailingAddress;
},
/** Returns payable to info */
/*getPayableTo: function() {
return window.checkoutConfig.payment.checkmo.payableTo;
}*/
});
}
);

3. Next we need to create the knockout template file invoice30.html in app/code/Pits/OfflinePaymentMethods/view/frontend/web/template/payment/

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

Step 5:  Finally display the payment method settings in Admin > Stores > Configuration > Sales > Payment Methods.

1. Create file system.xml in app/code/Pits/OfflinePaymentMethods/etc/adminhtml

<?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" translate="label" type="text" sortOrder="400" showInDefault="1" showInWebsite="1" showInStore="1">
<group id="invoice30" translate="label" type="text" sortOrder="101" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Invoice 30</label>
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
<label>Enabled</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="order_status" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
<label>New Order Status</label>
<source_model>Magento\Sales\Model\Config\Source\Order\Status\NewStatus</source_model>
</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>
<field id="title" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
<label>Title</label>
</field>
<field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
<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="51" 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="min_order_total" translate="label" type="text" sortOrder="98" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Minimum Order Total</label>
</field>
<field id="max_order_total" translate="label" type="text" sortOrder="99" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Maximum Order Total</label>
</field>
<field id="model"></field>
</group>
</section>
</system>
</config>

That’s it. We have finished creating an offline payment method for magento 2. See the frontend and admin side screenshots below.

frontend

admin

Reference:-
http://devdocs.magento.com/guides/v2.1/payments-integrations/base-integration/integration-intro.html

http://devdocs.magento.com/guides/v2.1/howdoi/checkout/checkout_payment.html

Leave a Reply

SCROLL TO TOP
This site is registered on wpml.org as a development site.