3

I have a requirement like below.

If there aren't any payment methods, There is a text showing in payment page

No Payment method available.

under the path

Magento_Checkout\web\template\payment.html

My requirement here is to include a link after the text like below

No Payment method available. click here to edit address. ==> It should be linked to customer account page

How can this be achieved, I am not so good in knockout.js to bind the links in html pages.

Please can anyone help me implement this functionality? Thanks!!

3

First of all, To update message in checkout payment step you need to update payment.html file and then, to pass custom link you need to create mixin of payment.js

Follow below steps for add link in payment steps when no payment methods available :

1) app/code/RH/CustomCheckout/view/frontend/requirejs-config.js

var config = {
    map: {
        '*': {
            'Magento_Checkout/template/payment.html': 
                'RH_CustomCheckout/template/payment.html' //override payment.html file
        }
    },
    config: {
        mixins: {
            'Magento_Checkout/js/view/payment': {
                'RH_CustomCheckout/js/view/payment-mixin': true // Create mixin of payment.js to add custom link
            }
        }
    }
};

2) app/code/RH/CustomCheckout/view/frontend/web/template/payment.html

<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<li id="payment" role="presentation" class="checkout-payment-method" data-bind="fadeVisible: isVisible">
    <div id="checkout-step-payment"
         class="step-content"
         data-role="content"
         role="tabpanel"
         aria-hidden="false">
        <!-- ko if: (quoteIsVirtual) -->
            <!-- ko foreach: getRegion('customer-email') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->
        <!--/ko-->
        <form id="co-payment-form" class="form payments" novalidate="novalidate">
            <input data-bind='attr: {value: getFormKey()}' type="hidden" name="form_key"/>
            <fieldset class="fieldset">
                <legend class="legend">
                    <span data-bind="i18n: 'Payment Information'"></span>
                </legend><br />
                <!-- ko foreach: getRegion('beforeMethods') -->
                    <!-- ko template: getTemplate() --><!-- /ko -->
                <!-- /ko -->
                <div id="checkout-payment-method-load" class="opc-payment" data-bind="visible: isPaymentMethodsAvailable">
                    <!-- ko foreach: getRegion('payment-methods-list') -->
                        <!-- ko template: getTemplate() --><!-- /ko -->
                    <!-- /ko -->
                </div>
                <div class="no-quotes-block" data-bind="visible: isPaymentMethodsAvailable() == false">
                     <!-- ko if: (!isPaymentMethodsAvailable()) -->
                    <span data-bind="i18n: 'No Payment method available.'"></span>
                    <b><a data-bind="i18n: 'click here', attr: { href: getCustomerAccountUrl() }" target="_new"></a></b>
                    <span data-bind="i18n: 'to edit address.'"></span>
                    <!-- /ko -->
                </div>
                <!-- ko foreach: getRegion('afterMethods') -->
                    <!-- ko template: getTemplate() --><!-- /ko -->
                <!-- /ko -->
            </fieldset>
        </form>
    </div>
</li>

3) app/code/RH/CustomCheckout/view/frontend/web/js/view/payment-mixin.js

define([
    'jquery',
    'underscore',
    'uiComponent',
    'ko',
    'Magento_Checkout/js/model/quote',
    'Magento_Checkout/js/model/step-navigator',
    'Magento_Checkout/js/model/payment-service',
    'Magento_Checkout/js/model/payment/method-converter',
    'Magento_Checkout/js/action/get-payment-information',
    'Magento_Checkout/js/model/checkout-data-resolver',
    'mage/translate',
    'mage/url'
], function (
    $,
    _,
    Component,
    ko,
    quote,
    stepNavigator,
    paymentService,
    methodConverter,
    getPaymentInformation,
    checkoutDataResolver,
    $t,
    url
) {
    'use strict';
    var mixin = {
        getCustomerAccountUrl: function () {
            return window.checkoutConfig.customUrl; // Get URL from Block file
        }
    };

    return function (target) {
        return target.extend(mixin);
    };
});

To pass URL from block/helper ,You have to just override getConfig() function of CompositeConfigProvider.php file.

4) app/code/RH/CustomCheckout/etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!-- pass custom data to checkout page -->
    <type name="Magento\Checkout\Model\CompositeConfigProvider">
        <arguments>
            <argument name="configProviders" xsi:type="array">
                <item name="checkout_custom_payment_block" xsi:type="object">RH\CustomCheckout\Model\CustomConfigProvider</item>
            </argument>
        </arguments>
    </type>
</config>

5) app/code/RH/CustomCheckout/Model/CustomConfigProvider.php

<?php
namespace RH\CustomCheckout\Model;

use Magento\Checkout\Model\ConfigProviderInterface;

class CustomConfigProvider implements ConfigProviderInterface {
    protected $customCheckout;

    public function __construct(
        \RH\CustomCheckout\Block\CustomBlock $customCheckout
    ) {
        $this->customCheckout = $customCheckout;
    }
    public function getConfig() {
        $config = [];
        $config['customUrl'] = $this->customCheckout->getCustomerAccountURL();
        return $config;
    }
}

6) app/code/RH/CustomCheckout/Block/CustomBlock.php

<?php
namespace RH\CustomCheckout\Block;
class CustomBlock extends \Magento\Framework\View\Element\Template {
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }
    public function getCustomerAccountURL() {
        return 'customer account url which you want to add';
    }
}
?>

If you want to add this custom URL into your theme's checkout payment.html file. Then, you just need to replace this below code in your html file. and no need to override payment.html file from requirejs-config.js. So, remove payment.html override code from requirejs-config.js [Step 1] if you want to access that data in your theme's checkout payment.html

Replace this below div in your theme's payment.html file :

From :

<div class="no-quotes-block" data-bind="visible: isPaymentMethodsAvailable() == false">
    <!-- ko i18n: 'No Payment method available.'--><!-- /ko -->
</div>

To :

<div class="no-quotes-block" data-bind="visible: isPaymentMethodsAvailable() == false">
     <!-- ko if: (!isPaymentMethodsAvailable()) -->
    <span data-bind="i18n: 'No Payment method available.'"></span>
    <b><a data-bind="i18n: 'click here', attr: { href: getCustomerAccountUrl() }" target="_new"></a></b>
    <span data-bind="i18n: 'to edit address.'"></span>
    <!-- /ko -->
</div>

Output :

enter image description here Hope, It will helpful for you.

| improve this answer | |
  • 1
    Thanks @Rohan. It was very clear and nice explanation!!. – Manjunath Nov 21 '19 at 5:59
  • Happy coding !! :) +1 for acceptance – Rohan Hapani Nov 21 '19 at 5:59
1

You can create one function in payment.js file using this way

Create requirejs-config.js file here in your custom module

app/code/Vendor/Module/view/frontend/requirejs-config.js

Content for this file is..

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/view/payment': {
                'Vendor_Module/js/view/payment-mixin': true
            }
        }
    }
};

Now you need to create one payment-mixin.js file here

app/code/Vendor/Module/view/frontend/web/js/view/payment-mixin.js

Content for this file is..

define([
    'jquery',
    'underscore',
    'uiComponent',
    'ko',
    'Magento_Checkout/js/model/quote',
    'Magento_Checkout/js/model/step-navigator',
    'Magento_Checkout/js/model/payment-service',
    'Magento_Checkout/js/model/payment/method-converter',
    'Magento_Checkout/js/action/get-payment-information',
    'Magento_Checkout/js/model/checkout-data-resolver',
    'mage/translate',
    'mage/url'
], function (
    $,
    _,
    Component,
    ko,
    quote,
    stepNavigator,
    paymentService,
    methodConverter,
    getPaymentInformation,
    checkoutDataResolver,
    $t,
    url
) {
    'use strict';

    var mixin = {
        defaults: {
            template: 'Vendor_Module/payment'
        },
        getBaseUrl: function () {
            /*You can add your URL here.*/
            return url.build('customer/account');
        }
    };

    return function (target) {
        return target.extend(mixin);
    };
});

I've created getBaseUrl() function here in this mixin file and also override template file from Magento_Checkout/payment to Vendor_Module/payment.

So now we need to create one template file here in our custom module

app/code/Vendor/Module/view/frontend/web/template/payment.html

Content for this file is

<li id="payment" role="presentation" class="checkout-payment-method" data-bind="fadeVisible: isVisible">
    <div id="checkout-step-payment"
         class="step-content"
         data-role="content"
         role="tabpanel"
         aria-hidden="false">
        <!-- ko if: (quoteIsVirtual) -->
            <!-- ko foreach: getRegion('customer-email') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->
        <!--/ko-->
        <form id="co-payment-form" class="form payments" novalidate="novalidate">
            <input data-bind='attr: {value: getFormKey()}' type="hidden" name="form_key"/>
            <fieldset class="fieldset">
                <legend class="legend">
                    <span data-bind="i18n: 'Payment Information'"></span>
                </legend><br />
                <!-- ko foreach: getRegion('beforeMethods') -->
                    <!-- ko template: getTemplate() --><!-- /ko -->
                <!-- /ko -->
                <div id="checkout-payment-method-load" class="opc-payment" data-bind="visible: isPaymentMethodsAvailable">
                    <!-- ko foreach: getRegion('payment-methods-list') -->
                        <!-- ko template: getTemplate() --><!-- /ko -->
                    <!-- /ko -->
                </div>
                <div class="no-quotes-block" data-bind="visible: isPaymentMethodsAvailable() == false">
                    <!-- ko i18n: 'No Payment method available.'--><!-- /ko -->
                    <a data-bind="attr: { href: getBaseUrl() }"><b>click here</b> to edit address</a>
                </div>
                <!-- ko foreach: getRegion('afterMethods') -->
                    <!-- ko template: getTemplate() --><!-- /ko -->
                <!-- /ko -->
            </fieldset>
        </form>
    </div>
</li>

I've called that function in this html template file.

Hope this will work for you!

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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