/   /   /  Save Payment Method with additional Data (show custom field on payment check)

Note:

For more extensions and themes visit our store

Save Payment Method with additional Data (show custom field on payment check)


What's happen if you want add custom data with specific pyament method , by example add custom input text which will show on check of payment method , ok let's start.
Download or Explore  code example in github
First create your schema file inside Ibnab/Additional/Setup/InstallSchema.php :

  1.  
  2. <?php
  3. namespace Ibnab\Additional\Setup;
  4. use Magento\Framework\Setup\InstallSchemaInterface;
  5. use Magento\Framework\Setup\ModuleContextInterface;
  6. use Magento\Framework\Setup\SchemaSetupInterface;
  7. class InstallSchema implements InstallSchemaInterface
  8. {
  9.     public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
  10.     {
  11.         $setup->startSetup();   
  12.         $setup->getConnection()->addColumn(
  13.             $setup->getTable('quote_payment'),
  14.             'bankowner',
  15.             [
  16.                 'type' => 'text',
  17.                 'nullable' => true  ,
  18.                 'comment' => 'Bank',
  19.             ]
  20.         );
  21.         $setup->getConnection()->addColumn(
  22.             $setup->getTable('sales_order_payment'),
  23.             'bankowner',
  24.             [
  25.                 'type' => 'text',
  26.                 'nullable' => true  ,
  27.                 'comment' => 'Bank',
  28.             ]
  29.         );
  30.         $setup->endSetup();
  31.   }
  32. }
  33.  
  34.  

We will add this behavior on bank transfert methode , ok let's remap offline-payments٫js inside Ibnab/Additional/view/frontend/requirejs-config.js :
  1.  
  2. var config = {
  3.     map: {
  4.         '*': {
  5.           'Magento_OfflinePayments/js/view/payment/offline-payments':       'Ibnab_Additional/js/view/payment/offline-payments',
  6.         }
  7.     }
  8. }
  9.  
  10.  

now you need copy the original file from magento vendor and pas in your module with some change (Ibnab/Additional/view/frontend/web/js/view/payment/offline-payments.js):
  1.  
  2. define(
  3.     [
  4.         'uiComponent',
  5.         'Magento_Checkout/js/model/payment/renderer-list'
  6.     ],
  7.     function (
  8.         Component,
  9.         rendererList
  10.     ) {
  11.         'use strict';
  12.         rendererList.push(
  13.             {
  14.                 type: 'checkmo',
  15.                 component: 'Magento_OfflinePayments/js/view/payment/method-renderer/checkmo-method'
  16.             },
  17.             {
  18.                 type: 'banktransfer',
  19.                 component: 'Ibnab_Additional/js/view/payment/method-renderer/banktransfer-method'
  20.             },
  21.             {
  22.                 type: 'cashondelivery',
  23.                 component: 'Magento_OfflinePayments/js/view/payment/method-renderer/cashondelivery-method'
  24.             },
  25.             {
  26.                 type: 'purchaseorder',
  27.                 component: 'Magento_OfflinePayments/js/view/payment/method-renderer/purchaseorder-method'
  28.             }
  29.         );
  30.         /** Add view logic here if needed */
  31.         return Component.extend({});
  32.     }
  33. );
  34.  
  35.  

we have changed the banktransfert renderer :

  1.  
  2.             {
  3.                 type: 'banktransfer',
  4.                 component: 'Ibnab_Additional/js/view/payment/method-renderer/banktransfer-method'
  5.             }
  6.  
  7.  

and create other one from original file in vendor (Ibnab/Additional/view/frontend/web/js/view/payment/method-renderer/banktransfer-method.js) :
  1.  
  2. define(
  3.     [
  4.         'ko',
  5.         'Magento_Checkout/js/view/payment/default',
  6.         'jquery'
  7.     ],
  8.     function (ko, Component,$) {
  9.         'use strict';
  10.         return Component.extend({
  11.             defaults: {
  12.                 template: 'Ibnab_Additional/payment/banktransfer'
  13.             },
  14.             getData: function() {
  15.                 return {
  16.                     'method': this.item.method,
  17.                     'additional_data': {
  18.                         'bankowner': $('#banktransfer_bankowner').val()
  19.                     }
  20.                 };
  21.             },
  22.             /**
  23.              * Get value of instruction field.
  24.              * @returns {String}
  25.              */
  26.             getInstructions: function () {
  27.                 return window.checkoutConfig.payment.instructions[this.item.method];
  28.             }
  29.         });
  30.     }
  31. );
  32.  
  33.  

In the banktransfer-method.js we have changed the path to our new html template (Ibnab/Additional/view/frontend/web/template/payment/banktransfer.html) :

  1.  
  2.             defaults: {
  3.                 template: 'Ibnab_Additional/payment/banktransfer'
  4.             }
  5.  
  6.  

And we have added the value of bank account owner to additional data bu using the id :
  1.  
  2.             getData: function() {
  3.                 return {
  4.                     'method': this.item.method,
  5.                     'additional_data': {
  6.                         'bankowner': $('#banktransfer_bankowner').val()
  7.                     }
  8.                 };
  9.             }
  10.  
  11.  

And that is the code of our html template (the original code is inside vendor) :
  1.  
  2. <div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
  3.     <div class="payment-method-title field choice">
  4.         <input type="radio"
  5.                name="payment[method]"
  6.                class="radio"
  7.                data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()" />
  8.         <label data-bind="attr: {'for': getCode()}" class="label"><span data-bind="text: getTitle()"></span></label>
  9.     </div>
  10.     <div class="payment-method-content">
  11.     <p data-bind="html: getInstructions()"></p>
  12.     <fieldset data-bind="attr: {class: 'fieldset payment items allbank ' + getCode(), id: 'payment_form_' + getCode()}">
  13.     <div class="field _required">
  14.         <label data-bind="attr: {for: getCode() + '_bankowner'}" class="label">
  15.             <span><!-- ko i18n: 'Account Owner'--><!-- /ko --></span>
  16.         </label>
  17.         <div class="control">
  18.             <input data-validate="{'required-entry':true}" type="text" name="payment[bankowner]" class="input-text" value=""
  19.                    data-bind="attr: {
  20.                                     id: getCode() + '_bankowner',
  21.                                     title: $t('Account Owner'),
  22.                                     'data-container': getCode() + '-bankowner',
  23.                                     'data-validate': JSON.stringify({'required':true})},
  24.                                     valueUpdate: 'keyup' "/>
  25.         </div>
  26.     </div>
  27.     </fieldset>
  28.         <!-- ko foreach: getRegion('messages') -->
  29.         <!-- ko template: getTemplate() --><!-- /ko -->
  30.         <!--/ko-->
  31.         <div class="payment-method-billing-address">
  32.             <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
  33.             <!-- ko template: getTemplate() --><!-- /ko -->
  34.             <!--/ko-->
  35.         </div>      
  36.         <div class="checkout-agreements-block">
  37.             <!-- ko foreach: $parent.getRegion('before-place-order') -->
  38.                 <!-- ko template: getTemplate() --><!-- /ko -->
  39.             <!--/ko-->
  40.         </div>
  41.         <div class="actions-toolbar">
  42.             <div class="primary">
  43.                 <button class="action primary checkout"
  44.                         type="submit"
  45.                         data-bind="
  46.                         click: placeOrder,
  47.                         attr: {'title': $t('Place Order')},
  48.                         enable: (getCode() == isChecked()),
  49.                         css: {disabled: !isPlaceOrderActionAllowed()}
  50.                         "
  51.                         disabled>
  52.                     <span data-bind="i18n: 'Place Order'"></span>
  53.                 </button>
  54.             </div>
  55.         </div>
  56.     </div>
  57. </div>
  58.  
  59.  

Our custom input text is with name name="payment[bankowner]" :

  1.  
  2. <fieldset data-bind="attr: {class: 'fieldset payment items allbank ' + getCode(), id: 'payment_form_' + getCode()}">
  3.     <div class="field _required">
  4.         <label data-bind="attr: {for: getCode() + '_bankowner'}" class="label">
  5.             <span><!-- ko i18n: 'Account Owner'--><!-- /ko --></span>
  6.         </label>
  7.         <div class="control">
  8.             <input data-validate="{'required-entry':true}" type="text" name="payment[bankowner]" class="input-text" value=""
  9.                    data-bind="attr: {
  10.                                     id: getCode() + '_bankowner',
  11.                                     title: $t('Account Owner'),
  12.                                     'data-container': getCode() + '-bankowner',
  13.                                     'data-validate': JSON.stringify({'required':true})},
  14.                                     valueUpdate: 'keyup' "/>
  15.       </div>
  16.     </div>
  17.     </fieldset>
  18.  
  19.  

Now is the time to add observer (Ibnab/Additional/etc/events.xml):

  1.  
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
  4.     <event name="sales_order_payment_save_before">
  5.         <observer name="save_bank_infos" instance="Ibnab\Additional\Observer\SaveBankInfoToOrderObserver"/>
  6.     </event>
  7. </config>
  8.  
  9.  

is very clear the system will declanche this event on before order payment save (Ibnab/Additional/Observer/SaveBankInfoToOrderObserver.php) :

  1.  
  2. <?php
  3. namespace Ibnab\Additional\Observer;
  4. use Magento\Framework\Event\Observer as EventObserver;
  5. use Magento\Framework\Event\ObserverInterface;
  6. use Magento\OfflinePayments\Model\Banktransfer;
  7. class SaveBankInfoToOrderObserver implements ObserverInterface {
  8.     protected $_inputParamsResolver;
  9.     protected $_quoteRepository;
  10.     protected $logger;
  11.     protected $_state;
  12.     public function __construct(\Magento\Webapi\Controller\Rest\InputParamsResolver $inputParamsResolver, \Magento\Quote\Model\QuoteRepository $quoteRepository, \Psr\Log\LoggerInterface $logger,\Magento\Framework\App\State $state) {
  13.         $this->_inputParamsResolver = $inputParamsResolver;
  14.         $this->_quoteRepository = $quoteRepository;
  15.         $this->logger = $logger;
  16.         $this->_state = $state;
  17.     }
  18.     public function execute(EventObserver $observer) {
  19.         $inputParams = $this->_inputParamsResolver->resolve();
  20.         if($this->_state->getAreaCode() != \Magento\Framework\App\Area::AREA_ADMINHTML){
  21.         foreach ($inputParams as $inputParam) {
  22.             if ($inputParam instanceof \Magento\Quote\Model\Quote\Payment) {
  23.                 $paymentData = $inputParam->getData('additional_data');
  24.                 $paymentOrder = $observer->getEvent()->getPayment();
  25.                 $order = $paymentOrder->getOrder();
  26.                 $quote = $this->_quoteRepository->get($order->getQuoteId());
  27.                 $paymentQuote = $quote->getPayment();
  28.                 $method = $paymentQuote->getMethodInstance()->getCode();
  29.                 if ($method == Banktransfer::PAYMENT_METHOD_BANKTRANSFER_CODE) {
  30.                     if(isset($paymentData['bankowner'])){
  31.                     $paymentQuote->setData('bankowner', $paymentData['bankowner']);
  32.                     $paymentOrder->setData('bankowner', $paymentData['bankowner']);
  33.                     }
  34.                 }
  35.             }
  36.         }
  37.        }
  38.     }
  39. }
  40.  
  41.  

We have use one way to get value of our input text from additional data of payment quote with inputParamsResolver  :

  1.  
  2. $inputParams = $this->_inputParamsResolver->resolve();
  3.  
  4.  

we have use foreach clause the extract the value and push inside payment qoute and payment order.

So now if you create an order the value of your custom field will be saved in column bankowner of quote_payment and sales_order_payment table .
But how you can show it in order view (inside admin) , you can add layout (Ibnab/Additional/view/adminhtml/layout/sales_order_view.xml) and push :

  1.  
  2. <?xml version="1.0"?>
  3. <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
  4.     <body>
  5.         <referenceContainer name="payment_additional_info">
  6.             <block class="Ibnab\Additional\Block\Info\BanktransferInfo" name="ibnab_banktransfert_infos" template="Ibnab_Additional::info/banktransferinfo.phtml" />
  7.         </referenceContainer>
  8.     </body>
  9. </page>
  10.  
  11.  

Now create you .phtml (Ibnab/Additional/view/adminhtml/templates/info/banktransferinfo.phtml):

  1.  
  2. <?php
  3. use Magento\OfflinePayments\Model\Banktransfer;
  4. $payment = $block->getOrder()->getPayment();
  5. $method = $payment->getMethodInstance()->getCode();
  6. ?>
  7. <?php if ($method == Banktransfer::PAYMENT_METHOD_BANKTRANSFER_CODE) :?>
  8. <div class="admin__page-section-item-content">
  9.     <strong><?php echo __('Account Name:') ?></strong>
  10.     <span class="price"><?php echo $payment->getData('bankowner'); ?></span>                        
  11. </div>
  12. <?php endif; ?>
  13.  
  14.  

we will show the account now just if bank transfert method :
  1.  
  2. <?php if ($method == Banktransfer::PAYMENT_METHOD_BANKTRANSFER_CODE) :?>
  3.  
  4.  

All is Done .
Download or Explore  code example in github

Comments

IBNAB is a company made of a group of professionals whose work is providing secure open source solutions. Our company strives for reaching magnificent results with each experience and provides professional open source solutions that cover every part of the business process.

Newsletter