1

I'm looking to stop a specific payment method (check / money order) from displaying on the checkout page. I can't disable the payment method, as I still need it to be used by the API on another checkout.

Doing some digging I can see this part loops through all the payment methods -

/vendor/magento/module-checkout/view/frontend/web/template/payment-methods/list.html

<div if="isPaymentMethodsAvailable()"
 class="items payment-methods">
<div repeat="foreach: paymentGroupsList, item: '$group'"
     class="payment-group">
    <div if="getRegion($group().displayArea)().length"
         translate="getGroupTitle($group)"
         class="step-title"
         data-role="title">
    </div>
    <each args="data: getRegion($group().displayArea), as: 'method'" render=""/>
</div>

I've tried to add in some logic of "if paymentMethod code = 'checkmo' don't display" = But I can't seem to do it this way, it gets rid of displaying any payment methods.

Would this be the best approach to do what I need, or is there another way?

4
  • I suggest you can make it hidden by CSS. Jun 6, 2019 at 12:46
  • This was thought about, but it doesn't seem the most secure as someone could easily unhide the payment method using CSS and essentially put through an order for free. This should be able to be picked up by manual checks in the process, but i was hoping to eliminate this worry.
    – BigDaddyL
    Jun 6, 2019 at 12:48
  • Ok I wasn't thought about that. Thanks. Jun 6, 2019 at 12:51
  • You can solve problem well by customizing the checkout page.
    – Tokey Tu
    Jun 10, 2019 at 8:46

2 Answers 2

1
+50

On the payment step, Magento will call the payment info api to get the payment list. vendor/magento/module-checkout/view/frontend/web/js/action/get-payment-information.js.

paymentService.setPaymentMethods(methodConverter(response['payment_methods']));

So, my idea, in your case, if we need to hide a specific payment on checkout page, we need to override the setPaymentMethods method.

[NOTE] There are many ways to achieve the goal.

For example:

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

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/model/payment-service': {
                'Vendor_OfflinePayment/js/mixins/model/payment-service': true
            }
        }
    }
};

app/code/Vendor/OfflinePayment/view/frontend/web/js/mixins/model/payment-service.js

define([
    'underscore',
    'Magento_Checkout/js/model/quote',
    'Magento_Checkout/js/model/payment/method-list',
    'Magento_Checkout/js/action/select-payment-method'
], function (_, quote, methodList, selectPaymentMethod) {

    return function (paymentService) {
        /**
         * Free method filter
         * @param {Object} paymentMethod
         * @return {Boolean}
         */
        var isFreePaymentMethod = function (paymentMethod) {
                return paymentMethod.method === 'free';
            },

            /**
             * Grabs the grand total from quote
             * @return {Number}
             */
            getGrandTotal = function () {
                return quote.totals()['grand_total'];
            };

        // Custom code
        var isCheckmoPaymentMethod = function (paymentMethod) {
            return paymentMethod.method === 'checkmo';
        };

        /**
         * Populate the list of payment methods
         * @param {Array} methods
         */
        paymentService.setPaymentMethods = function (methods) {
            var freeMethod,
                filteredMethods,
                methodIsAvailable,
                methodNames;

            freeMethod = _.find(methods, isFreePaymentMethod);
            this.isFreeAvailable = !!freeMethod;

            if (freeMethod && getGrandTotal() <= 0) {
                methods.splice(0, methods.length, freeMethod);
                selectPaymentMethod(freeMethod);
            }

            filteredMethods = _.without(methods, freeMethod);

            if (filteredMethods.length === 1) {
                selectPaymentMethod(filteredMethods[0]);
            } else if (quote.paymentMethod()) {
                methodIsAvailable = methods.some(function (item) {
                    return item.method === quote.paymentMethod().method;
                });
                //Unset selected payment method if not available
                if (!methodIsAvailable) {
                    selectPaymentMethod(null);
                }
            }

            //Custom code - Prevent checkmo to render on checkout page.
            var checkmo = _.find(methods, isCheckmoPaymentMethod);
            methods = _.without(methods, checkmo);


            /**
             * Overwrite methods with existing methods to preserve ko array references.
             * This prevent ko from re-rendering those methods.
             */
            methodNames = _.pluck(methods, 'method');
            _.map(methodList(), function (existingMethod) {
                var existingMethodIndex = methodNames.indexOf(existingMethod.method);

                if (existingMethodIndex !== -1) {
                    methods[existingMethodIndex] = existingMethod;
                }
            });

            methodList(methods);
        };
        return paymentService;
    };
});

Our custom code:

        // Custom code
        var isCheckmoPaymentMethod = function (paymentMethod) {
            return paymentMethod.method === 'checkmo';
        };
        .......
        .......
        //Custom code - Prevent checkmo to render on checkout page.
        var checkmo = _.find(methods, isCheckmoPaymentMethod);
        methods = _.without(methods, checkmo);

@HoangHieu solution will work.

2
  • Thank you. Looked into mixins and have taken a similar idea as proposed here, the magento checkout parts were confusing me at first.
    – BigDaddyL
    Jun 12, 2019 at 10:35
  • Thanks @khoa-truongdinh. That solution worked for me as well. But if i want to stop rendering those payment methods saved in System configuration. How to do that? How can i call that System Config Variable in this payment-service.js. Oct 25, 2020 at 12:03
2

First think you should create mixins to overwrite payment/list.js

/magento/module-checkout/view/frontend/web/js/view/payment/list.js

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/view/payment/list': {
                'PackageName_ModuleName/js/view/payment/list': true
            }
        }
    }
};

Read more here: https://www.solutiontutorials.com/development/magento-2/how-to-override-magento-2-js-using-mixins/

Override initialize: function ()

            /**
     * Initialize view.
     *
     * @returns {Component} Chainable.
     */
    initialize: function () {
        this._super().initDefaulGroup().initChildren();
        paymentMethods.subscribe(
            function (changes) {
                checkoutDataResolver.resolvePaymentMethod();
                //remove renderer for "deleted" payment methods
                _.each(changes, function (change) {
                    if (change.status === 'deleted') {
                        this.removeRenderer(change.value.method);
                    }
                }, this);
                //add renderer for "added" payment methods
                _.each(changes, function (change) {
                    if (change.status === 'added') {
                        if(change.value.method !== 'remove_method_code') {
                            this.createRenderer(change.value);
                        }
                    }
                }, this);
            }, this, 'arrayChange');

        return this;
    }
3
  • Your way will work but we need to add more logic. Jun 10, 2019 at 11:37
  • This solution is simple ways to stop render payment methods to the checkout page If Author need to advance more, Author should learn Magento and do it by himself (a @KhoaTruongDinh e ko muốn làm hết cho ẻm)
    – HoangHieu
    Jun 11, 2019 at 2:40
  • Thank you. Looked into mixins and have taken a similar idea as proposed here, the magento checkout parts were confusing me at first.
    – BigDaddyL
    Jun 12, 2019 at 10:35

Your Answer

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

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