Custom offline payment module with custom validation on checkout page

In this blog session i am going to add an extra custom validation on checkout page which will verify user's email domain with the email domain you provided in store config. If both domain matches then only a success message shown and you can proceed with place order, other wise it will show error message and you are unable to  place order.

                                                            This blog is related to my previous blog in which i had created an extra offline payment method on checkout page so please check it here .


So, at that time we have already these files and folder structure

* etc
   * adminhtml
      * system.xml
   * config.xml
   * module.xml
   * payment.xml
* Model
   * CustomPayment.php
* view
    * frontend
       * layout
          * checkout_index_index.xml
       * web
          * js
             * view
                * payment
                   * method-rendered
                      * custompayment-method.js
                   * offline-payment.js
        * template
           * payment
              * custompayment.html
        registration.php



All file details are available in my previous blog so make sure you have cheked it.

add your extra domain field into system.xml file

 <?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="custompayment" translate="label" type="text" sortOrder="101" showInDefault="1" showInWebsite="1" showInStore="1">  
                     <label>Custom Payment</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>  
                 <!-- add your email domain field here -->  
                     <field id="email_domain" translate="label" type="text" sortOrder="110" showInDefault="1" showInWebsite="1" showInStore="0">  
                          <label>Email Domain</label>  
                     </field>  
                     <field id="model"></field>  
                </group>  
           </section>  
      </system>  
 </config>  





Next we have to create your controller.

file location : app/code/Excellence/OfflinePaymanetMethods/controller/valildate/
file : ValidateEmail.php

 <?php  
 namespace Excellence\OfflinePaymentMethods\Controller\Validate;  
 class ValidateEmail extends \Magento\Framework\App\Action\Action  
 {  
   protected $_scopeConfig;  
   public function __construct(  
     \Magento\Framework\App\Action\Context $context,  
     \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,  
     \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory  
   )  
   {  
      $this->resultJsonFactory = $resultJsonFactory;  
     $this->_scopeConfig = $scopeConfig;  
     return parent::__construct($context);  
   }  
   public function execute()  
   {  
     $result = $this->resultJsonFactory->create();  
     /* domain validation starts here */  
     $storeAllowedDomain = $this->_scopeConfig->getValue('payment/custompayment/email_domain'); // getting configration's allowed domain  
     $flag = 0;  
     $email = $this->getRequest()->getPostValue('customerEmail'); //this is the email entered by user on store front  
     $extractedDomainName = substr(strrchr($email, "@"), 1);  
     if( $storeAllowedDomain === $extractedDomainName)  
       $flag = 1;  
     return $result->setData($flag);  
   }  
 }  


file location : app/code/Excellence/OfflinePaymentMethods/etc/frontend/
file : routes.xml



 <?xml version="1.0"?>  
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">  
   <router id="standard">  
     <route frontName="validate" id="validate">  
       <module name="Excellence_OfflinePaymentMethods"/>  
     </route>  
   </router>  
 </config>   



file location : /app/code/Excellence/OfflinePaymentMethods/view/frontend/web/js/view/payment/method-renderer/
file : custompayment-method.js




 define(  
      [  
      'Magento_Checkout/js/view/payment/default',  
      'ko',  
      'jquery',  
   'Magento_Checkout/js/model/quote',  
   'mage/url',  
   'Magento_Ui/js/model/messageList'  
      ],  
           function (Component,ko,$,quote,url,messageList) {  
           'use strict';  
           return Component.extend({  
                defaults: {  
                     template: 'Excellence_OfflinePaymentMethods/payment/custompayment'  
                },  
                getMailingAddress: function() {  
                     return window.checkoutConfig.payment.custompayment.mailingAddress;  
                },  
                initialize: function () {  
               var self = this;  
               self._super();  
               self.btnPlaceOrder = ko.observable(false);  
            self.btnContinue = ko.observable(true);  
       },  
                validateDomain:function(){  
                     /* gathering details of current user either logged in or guest user */  
                     var self = this;  
         var currentEmail;   
         if(quote.guestEmail)   
           currentEmail = quote.guestEmail;  
         else   
           currentEmail = window.checkoutConfig.customerData.email;  
         var validationUrl = url.build('validate/validate/validateemail');  
         /* ajax calling */  
         $.ajax(  
                               {   
                                    url : validationUrl,  
                                    type : 'POST',  
                                    data:   
                                         {  
                                              customerEmail: currentEmail  
                                         },  
                  showLoader: true,  
                  success : function(flag) {  
                       if(flag)  
                       {  
                         self.btnPlaceOrder(true);  
                         self.btnContinue(false);  
                         messageList.addSuccessMessage({ message: 'You are allowed to place order.' });  
                            }  
                       else {  
                          messageList.addErrorMessage({ message: 'You are not allowed to place order with provided email domain.' });  
                            }  
                          }  
                        }  
                      );  
                     }  
                }  
           );  
      }  
 );  

file location : app/code/Excellence/OfflinePaymentMethods/view/frontend/web/js/view/payment/
file : offline-payment.js


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


file location : app/code/Excellence/OfflinePaymentMethods/view/frontend/web/template/payment/
file : custompayment.html




 <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">  
                <span data-bind="visible: btnContinue">  
                     <button class="action primary checkout" type="submit" data-bind="  click: validateDomain, attr: {title: $t('Continue')} " >  
                          <span>Continue</span>  
                     </button>  
                </span>  
                <span data-bind="visible : btnPlaceOrder">  
                     <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>  
                </span>  
           </div>  
           </div>  
      </div>  
 </div>  



Thats it all files are ready now enable module using command

sudo php bin/magento seetup:upgraded

sudo php bin/magento c:c

sudo php bin/magento c:f

sudo chmod  -R 777 /var /generated / pub


Comments

Popular posts from this blog

Jasper report integration in Spring boot/Spring MVC.

FireBase Crud operation in Spring Boot

Xero Developer account setup with REST API auth flow.