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?

| improve this question | | | | |
  • I suggest you can make it hidden by CSS. – Dhara Bhatti Jun 6 '19 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 '19 at 12:48
  • Ok I wasn't thought about that. Thanks. – Dhara Bhatti Jun 6 '19 at 12:51
  • You can solve problem well by customizing the checkout page. – tokey Jun 10 '19 at 8:46
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.

| improve this answer | | | | |
  • 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 '19 at 10:35
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;
    }
| improve this answer | | | | |
  • Your way will work but we need to add more logic. – Khoa TruongDinh Jun 10 '19 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 '19 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 '19 at 10:35

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.