2

Please check my Custom payment Module, I was able to display the list in drop down in Payment method, But when i select and place order it is not working as expected.

Please download the complete module here for more details.

app\code\K2B\PickPay\view\frontend\layout\checkout_index_index.xml

<?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="component" xsi:type="string">uiComponent</item>
                                            <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="pickpay-payments" xsi:type="array">
                                                                    <item name="component" xsi:type="string">K2B_PickPay/js/view/payment/offline-payments</item>

                                                                    <item name="methods" xsi:type="array">
                                                                        <item name="pickpay" 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>

\app\code\K2B\PickPay\Model\Pickpay.php

namespace K2B\PickPay\Model;
use Magento\Framework\DataObject;
use Magento\Quote\Api\Data\PaymentInterface;
/**
 * Pay In Store payment method model
 */
class Pickpay extends \Magento\Payment\Model\Method\AbstractMethod
{
    const PAYMENT_METHOD_PICKPAY_CODE = 'pickpay';
    /**
     * Payment code
     *
     * @var string
     */
    protected $_code = self::PAYMENT_METHOD_PICKPAY_CODE;
    /**
     * Availability option
     *
     * @var bool
     */
    protected $_isOffline = true;
     /**
     * @var string
     */
    protected $_formBlockType = 'K2B\PickPay\Block\Form\Pickpay';

    /**
     * @var string
     */
    protected $_infoBlockType = 'K2B\PickPay\Block\Info\Pickpay';



    /**
     * Assign data to info model instance
     *
     * @param \Magento\Framework\DataObject|mixed $data
     * @return $this
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function assignData(\Magento\Framework\DataObject $data)
    {
        $additionalData = $data->getData(PaymentInterface::KEY_ADDITIONAL_DATA);
        if (!is_object($additionalData)) {
            $additionalData = new DataObject($additionalData ?: []);
        }       
        /*$myfile = fopen("./var/log/pickpay.txt", "a");    

        $txt = "getPickpayLocation:".$additionalData->getPickpayLocation();     
        fwrite($myfile, "\n". $txt);
        fclose($myfile);*/
        $this->getInfoInstance()->setPickpayLocation($additionalData->getPickpayLocation());
        return $this;
    }

}

\app\code\K2B\PickPay\Setup\UpgradeSchema.php

<?php
namespace K2B\PickPay\Setup;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;

class UpgradeSchema implements UpgradeSchemaInterface
{   
    /**
     * {@inheritdoc}
     */
    public function upgrade(
        SchemaSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $installer = $setup;

        $installer->startSetup();       
        if (version_compare($context->getVersion(), '2.0.1', '<')) {            
          $installer->getConnection()->addColumn(
                $installer->getTable('quote_payment'),
                'pickpay_location',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    'length' => 255,
                    'comment' => 'Pay and Pick Store Location'
                ]
            );
          $installer->getConnection()->addColumn(
                $installer->getTable('sales_order_payment'),
                'pickpay_location',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    'length' => 255,
                    'comment' => 'Pay and Pick Store Location'
                ]
            );
        }

        $installer->endSetup();
    }
}

app\code\K2B\PickPay\view\frontend\templates\form\pickpay.phtml

<?php
$methodCode = $block->escapeHtml($block->getMethodCode());
$location = $block->escapeHtml($block->getInfoData('pickpay_location'));
?>
<fieldset class="fieldset items <?php /* @noEscape */ echo $methodCode ?>" id="payment_form_<?php /* @noEscape */ echo $methodCode ?>" style="display: none">
    <div class="field number required">
        <label for="pickpay_location" class="label"><span><?php echo $block->escapeHtml(__('
        Choose your Click & Collect Store Location')) ?></span></label>
        <div class="control">
            <select id="pickpay_location" name="payment[pickpay_location]"  class="required-entry">             
                <option value="CENTRAL SUPER MARKET" <?php echo  ($location == 'CENTRAL SUPER MARKET')?'selected="selected"':''?>>CENTRAL SUPER MARKET</option>
                <option value="ZAKHER BRANCH" <?php echo  ($location == 'ZAKHER BRANCH')?'selected="selected"':''?>>ZAKHER BRANCH</option>
                <option value="MAZYED BRANCH" <?php echo  ($location == 'MAZYED BRANCH')?'selected="selected"':''?>>MAZYED BRANCH</option>
                <option value="MARKHANIYA BRANCH" <?php echo  ($location == 'MARKHANIYA BRANCH')?'selected="selected"':''?>>MARKHANIYA BRANCH</option>
                <option value="AL MAQAM BRANCH" <?php echo  ($location == 'AL MAQAM BRANCH')?'selected="selected"':''?>>AL MAQAM BRANCH</option>
                <option value="AL MAQAM BRANCH" <?php echo  ($location == 'AL MAQAM BRANCH')?'selected="selected"':''?>>AL MAQAM BRANCH</option>
                <option value="AL MANASIR BRANCH" <?php echo  ($location == 'AL MANASIR BRANCH')?'selected="selected"':''?>>AL MANASIR BRANCH</option>
                <option value="AL HAYER BRANCH" <?php echo  ($location == 'AL HAYER BRANCH')?'selected="selected"':''?>>AL HAYER BRANCH</option>
                <option value="AL YAHAR BRANCH" <?php echo  ($location == 'AL YAHAR BRANCH')?'selected="selected"':''?>>AL YAHAR BRANCH</option>
                <option value="TAWAM BRANCH" <?php echo  ($location == 'TAWAM BRANCH')?'selected="selected"':''?>>TAWAM BRANCH</option>
                <option value="TOWAYYA HABOI BRANCH" <?php echo  ($location == 'TOWAYYA HABOI BRANCH')?'selected="selected"':''?>>TOWAYYA HABOI BRANCH</option>
                <option value="HILLI KHALEEF BRANCH" <?php echo  ($location == 'HILLI KHALEEF BRANCH')?'selected="selected"':''?>>HILLI KHALEEF BRANCH</option>
                <option value="SHOIBA BRANCH" <?php echo  ($location == 'SHOIBA BRANCH')?'selected="selected"':''?>>SHOIBA BRANCH</option>
                <option value="KHALIDIYA BRANCH" <?php echo  ($location == 'KHALIDIYA BRANCH')?'selected="selected"':''?>>KHALIDIYA BRANCH</option>
                <option value="FALAJ HAZZA BRANCH" <?php echo  ($location == 'FALAJ HAZZA BRANCH')?'selected="selected"':''?>>FALAJ HAZZA BRANCH</option>
                <option value="MASOUDI BRANCH" <?php echo  ($location == 'MASOUDI BRANCH')?'selected="selected"':''?>>MASOUDI BRANCH</option>
                <option value="AL BATEEN BRANCH" <?php echo  ($location == 'AL BATEEN BRANCH')?'selected="selected"':''?>>AL BATEEN BRANCH</option>
                <option value="NAHEL BRANCH" <?php echo  ($location == 'NAHEL BRANCH')?'selected="selected"':''?>>NAHEL BRANCH</option>
                <option value="FAQAA BRANCH" <?php echo  ($location == 'FAQAA BRANCH')?'selected="selected"':''?>>FAQAA BRANCH</option>
                <option value="UM GHAFA BRANCH" <?php echo  ($location == 'UM GHAFA BRANCH')?'selected="selected"':''?>>UM GHAFA BRANCH</option>
                <option value="SALAMAT BRANCH" <?php echo  ($location == 'SALAMAT BRANCH')?'selected="selected"':''?>>SALAMAT BRANCH</option>
                <option value="SUWIHAN BRANCH" <?php echo  ($location == 'SUWIHAN BRANCH')?'selected="selected"':''?>>SUWIHAN BRANCH</option>
                <option value="SHUWAIB BRANCH" <?php echo  ($location == 'SHUWAIB BRANCH')?'selected="selected"':''?>>SHUWAIB BRANCH</option>
                <option value="ALIAH MALL" <?php echo  ($location == 'ALIAH MALL')?'selected="selected"':''?>>ALIAH MALL</option>
                <option value="AL NAYFA SUPERMARKET" <?php echo  ($location == 'AL NAYFA SUPERMARKET')?'selected="selected"':''?>>AL NAYFA SUPERMARKET</option>
            </select>

        </div>
    </div>
</fieldset>

\app\code\K2B\PickPay\view\frontend\web\js\view\payment\method-renderer\pickpay.js

define(
    [
        'Magento_Checkout/js/view/payment/default',
        'jquery',
        "mage/validation"
    ],
    function (Component, $) {
        'use strict';
        return Component.extend({
            defaults: {
                template: 'K2B_PickPay/payment/pickpay-form',
                purchaseOrderNumber: ''
            },
            initObservable: function () {
                this._super()
                    .observe('pickpayLocation');
                return this;
            },
            getData: function () {
                return {
                    "method": this.item.method,
                    'pickpay_location': this.pickpayLocation(),
                    "additional_data": null
                };

            },
            validate: function () {
                var form = 'form[data-role=pickpay-form]';
                return $(form).validation() && $(form).validation('isValid');
            }
        });
    }
);

\app\code\K2B\PickPay\view\frontend\web\js\view\payment\offline-payments.js

 define(
        [
            'uiComponent',
            'Magento_Checkout/js/model/payment/renderer-list'
        ],
        function (
            Component,
            rendererList
        ) {
            'use strict';
            rendererList.push(
                {
                    type: 'pickpay',
                    component: 'K2B_PickPay/js/view/payment/method-renderer/pickpay'
                }
            );
            return Component.extend({
                getData: function() {
                return {
                    'method': this.item.method,
                    'additional_data': {
                        'pickpay_location': this.pickPayLocation()
                    }
                };
            }
            });
        }
    );

\app\code\K2B\PickPay\view\frontend\web\template\payment\pickpay-form.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">
        <form id="pickpay-form" class="form form-pickpay" data-role="pickpay-form">
            <fieldset class="fieldset payment method" data-bind='attr: {id: "payment_form_" + getCode()}'>
                <div class="field field-number required">
                    <label for="pickpay_location" class="label">
                        <span><!-- ko i18n: 'Click & Collect Store Location'--><!-- /ko --></span>
                    </label>
                    <div class="control">
                        <select id="pickpay_location"
                               name="payment[pickpay_location]"
                               data-validate="{required:true}"
                               data-bind='
                                attr: {title: $t("Click & Collect Store Location")},
                                value: pickpayLocation'>
                            <option value="CENTRAL SUPER MARKET">CENTRAL SUPER MARKET</option>
                            <option value="ZAKHER BRANCH">ZAKHER BRANCH</option>
                            <option value="MAZYED BRANCH">MAZYED BRANCH</option>
                            <option value="MARKHANIYA BRANCH">MARKHANIYA BRANCH</option>
                            <option value="AL MAQAM BRANCH">AL MAQAM BRANCH</option>
                            <option value="AL MAQAM BRANCH">AL MAQAM BRANCH</option>
                            <option value="AL MANASIR BRANCH">AL MANASIR BRANCH</option>
                            <option value="AL HAYER BRANCH">AL HAYER BRANCH</option>
                            <option value="AL YAHAR BRANCH">AL YAHAR BRANCH</option>
                            <option value="TAWAM BRANCH">TAWAM BRANCH</option>
                            <option value="TOWAYYA HABOI BRANCH">TOWAYYA HABOI BRANCH</option>
                            <option value="HILLI KHALEEF BRANCH">HILLI KHALEEF BRANCH</option>
                            <option value="SHOIBA BRANCH">SHOIBA BRANCH</option>
                            <option value="KHALIDIYA BRANCH">KHALIDIYA BRANCH</option>
                            <option value="FALAJ HAZZA BRANCH">FALAJ HAZZA BRANCH</option>
                            <option value="MASOUDI BRANCH">MASOUDI BRANCH</option>
                            <option value="AL BATEEN BRANCH">AL BATEEN BRANCH</option>
                            <option value="NAHEL BRANCH">NAHEL BRANCH</option>
                            <option value="FAQAA BRANCH">FAQAA BRANCH</option>
                            <option value="UM GHAFA BRANCH">UM GHAFA BRANCH</option>
                            <option value="SALAMAT BRANCH">SALAMAT BRANCH</option>
                            <option value="SUWIHAN BRANCH">SUWIHAN BRANCH</option>
                            <option value="SHUWAIB BRANCH">SHUWAIB BRANCH</option>
                            <option value="ALIAH MALL">ALIAH MALL</option>
                            <option value="AL NAYFA SUPERMARKET">AL NAYFA SUPERMARKET</option>
                        </select>

                    </div>
                </div>
            </fieldset>
        </form>
        <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>

please check the module here for more details.

after installing module- I am getting following Issue enter image description here

14
  • $this->getInfoInstance()->setPickpayLocation($additionalData->getPickpayLocation()); in this line where is setPickpayLocation and getPickpayLocation methods ? Commented May 14, 2018 at 13:09
  • Can u give me format, Do i have have to return an array with all the list vales. in getPickPayLocation method. Will this class executes only once..? Commented May 14, 2018 at 14:45
  • follow this link webkul.com/blog/create-custom-payment-method-magento2 Commented May 18, 2018 at 4:31
  • have you solved your issue?
    – kunj
    Commented May 18, 2018 at 14:21
  • no, still not able understand completely. what's missing in my code Commented May 18, 2018 at 19:42

1 Answer 1

1
+50

You need to update and create some files in your module which are here:

Create this requirejs-config.js file in your module root :

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/action/place-order': {
                'K2B_PickPay/js/model/place-order-mixin': true
            },
            'Magento_Checkout/js/action/set-payment-information': {
                'K2B_PickPay/js/model/set-payment-information-mixin': true
            }
        }
    }
};

Create this file set-payment-information-mixin.js at app/code/K2B/PickPay/view/frontend/web/js/model/ with this content :

define([
    'jquery',
    'mage/utils/wrapper',
    'K2B_PickPay/js/model/pick-pay-location-assigner'
], function ($, wrapper, pickPayLocationAssigner) {
    'use strict';

    return function (placeOrderAction) {

        /** Override place-order-mixin for set-payment-information action as they differs only by method signature */
        return wrapper.wrap(placeOrderAction, function (originalAction, messageContainer, paymentData) {
            pickPayLocationAssigner(paymentData);

            return originalAction(messageContainer, paymentData);
        });
    };
});

Create this file place-order-mixin.js at app/code/K2B/PickPay/view/frontend/web/js/model/ with this content :

define([
    'jquery',
    'mage/utils/wrapper',
    'K2B_PickPay/js/model/pick-pay-location-assigner'
], function ($, wrapper, pickPayLocationAssigner) {
    'use strict';

    return function (placeOrderAction) {

        /** Override default place order action and add agreement_ids to request */
        return wrapper.wrap(placeOrderAction, function (originalAction, paymentData, messageContainer) {
            pickPayLocationAssigner(paymentData);

            return originalAction(paymentData, messageContainer);
        });
    };
});

Create this file pick-pay-location-assigner.js at app/code/K2B/PickPay/view/frontend/web/js/model/ with this content :

 define([
    'jquery'
], function ($) {
    'use strict';

    /** Override default place order action and add agreement_ids to request */
    return function (paymentData) {
        var pickPaForm,
            pickPaData;

        pickPaForm = $('form[data-role=pickpay-form] #pickpay_location');
        pickPaData = pickPaForm.val();

        if (paymentData['extension_attributes'] === undefined) {
            paymentData['extension_attributes'] = {};
        }

        paymentData['extension_attributes']['pickpay_location'] = pickPaData;
    };
});

Update this file offline-payments.js with this content :

define([
        'uiComponent',
        'Magento_Checkout/js/model/payment/renderer-list'
    ], function ( Component, rendererList ) {
        'use strict';
        rendererList.push(
            {
                type: 'pickpay',
                component: 'K2B_PickPay/js/view/payment/method-renderer/pickpay'
            }
        );
        return Component.extend({});
    }
);

Update this file pickpay.js with this content :

    define([
        'Magento_Checkout/js/view/payment/default',
        'jquery',
        "mage/validation"
    ], function (Component, $) {
        'use strict';
        return Component.extend({
            defaults: {
                template: 'K2B_PickPay/payment/pickpay-form',
                pickpayLocation: ''
            },
            initObservable: function () {
                return this;
            },
            getData: function () {
                return {
                    "method": this.item.method
                };

            },
            validate: function () {
                var form = 'form[data-role=pickpay-form]';
                return $(form).validation() && $(form).validation('isValid');
            }
        });
});

Update this file app/code/K2B/PickPay/view/frontend/templates/info/pickpay.phtml this contetn :

<dl class="payment-method pickpay">
    <dt class="title"><?php echo $block->escapeHtml($block->getMethod()->getTitle()) ?></dt>
    <dd class="content">
        <strong><?php echo $block->escapeHtml(__('Click & Collect Store Location')) ?></strong>
        <span class="number"><?php echo $block->escapeHtml($block->getPickPayLocation()) ?></span>
    </dd>
</dl>

Add this file app/code/K2B/PickPay/etc/extension_attributes.xml with this content :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Quote\Api\Data\PaymentInterface">
        <attribute code="pickpay_location" type="string"/>
    </extension_attributes>
</config>

Update this file app/code/K2B/PickPay/Block/Info/Pickpay.php With this content:

<?php
namespace K2B\PickPay\Block\Info;

class Pickpay extends \Magento\Payment\Block\Info
{
    /**
     * @var string
     */
    protected $_template = 'K2B_PickPay::info/pickpay.phtml';

    /**
     * @return string
     */
    public function toPdf()
    {
        $this->setTemplate('K2B_PickPay::info/pdf/pickpay.phtml');
        return $this->toHtml();
    }

    public function getPickPayLocation()
    {
        return $this->getMethod()->getInfoInstance()->getPickpayLocation();
    }

}

Update this file app/code/K2B/PickPay/Model/Pickpay.php with this content:

<?php

namespace K2B\PickPay\Model;

/**
 * Pay In Store payment method model
 */
class Pickpay extends \Magento\Payment\Model\Method\AbstractMethod
{
    const PAYMENT_METHOD_PICKPAY_CODE = 'pickpay';
    /**
     * Payment code
     *
     * @var string
     */
    protected $_code = self::PAYMENT_METHOD_PICKPAY_CODE;
    /**
     * Availability option
     *
     * @var bool
     */
    protected $_isOffline = true;
     /**
     * @var string
     */
    protected $_formBlockType = \K2B\PickPay\Block\Form\Pickpay::class;

    /**
     * @var string
     */
    protected $_infoBlockType = \K2B\PickPay\Block\Info\Pickpay::class;

    public function assignData(\Magento\Framework\DataObject $data)
    {
        parent::assignData($data);
        $infoInstance = $this->getInfoInstance();
        if(is_array($data->getData('additional_data')))
        {
            $additionalData = $data->getData('additional_data');
            $pickPayLocation = ($extensionAttributes = $additionalData['extension_attributes'])?$extensionAttributes->getPickpayLocation():"";
            $infoInstance->setAdditionalInformation('pickpay_location', $pickPayLocation);
            $data->setPickpayLocation($pickPayLocation);
            $infoInstance->setPickpayLocation($pickPayLocation);
        }
        return $this;
    }

}

Add this file app/code/K2B/PickPay/etc/events.xml with this content:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_order_save_before">
        <observer name="pick_pay_payment_before_save" instance="K2B\PickPay\Observer\QuoteToOrderObserver" />
    </event>
</config>

Create this file app/code/K2B/PickPay/Observer/QuoteToOrderObserver.php with this content:

<?php
/**
 * Created by PhpStorm.
 * User: kunj
 * Date: 22/5/18
 * Time: 6:29 PM
 */

namespace K2B\PickPay\Observer;

use Magento\Framework\Event\ObserverInterface;

class QuoteToOrderObserver implements ObserverInterface
{
    protected $cart;

    public function __construct(
        \Magento\Checkout\Model\Cart $cart
    )
    {
        $this->cart = $cart;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        /** @var \Magento\Sales\Model\Order\Payment $payment */
        $quotePayment = $this->cart->getQuote()->getPayment();
        $payment = $observer->getEvent()->getOrder()->getPayment();
        if ($quotePayment->getMethod() === \K2B\PickPay\Model\Pickpay::PAYMENT_METHOD_PICKPAY_CODE) {
            if (!empty($quotePayment->getPickpayLocation())) {
                $payment->setPickpayLocation($quotePayment->getPickpayLocation());
            }
        }
    }
}

As per your request, you can download the updated module from here

10
  • Can u post entire module Commented May 23, 2018 at 6:47
  • I have updated my answer, with the link, you can download it from there
    – kunj
    Commented May 23, 2018 at 6:56
  • Let me know if you get any issue related to it.
    – kunj
    Commented May 23, 2018 at 8:22
  • I am getting version error, i have updated the question with error screenshot. Can u please let me know what can i do. Commented May 23, 2018 at 9:50
  • have you pasted my code? Then change the version in my code : In this file : app/code/K2B/PickPay/etc/module.xml From : setup_version="2.0.1" To : setup_version="2.0.3" After that flush cache : php bin/magento cache:flush
    – kunj
    Commented May 23, 2018 at 9:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.