Magento2: isPaymentMethodsAvailable is not defined

Created on 6 Jan 2017  路  46Comments  路  Source: magento/magento2

After upgrading 2.1.2 to 2.1.3 with Web Setup Wizard, checkout payment page not working.


Preconditions


  1. Magento 2.1.3
  2. PHP 7.0.11
  3. Clean & flush all caches etc.

Steps to reproduce

  1. Add to cart an item
  2. Go to checkout, fill shipping information
  3. Click next, wait for payment methods

Expected result

  1. Payments method listed (there are 3 active payment methods)

Actual result

  1. No payment methods listed
  2. An error occured
    sct

Checkout bug report

Most helpful comment

No result on my side :(
How is the community can't hear us such an important issue like this?

There are several fixes about less important things and contributors working 'hard' on these (cleaning code styling etc.) but (i think) very most important issues (payment, marketing, performance etc) delaying.

We can not progress to latest versions/improvements with this like issues.

All 46 comments

@rbostan Did you try with Incognito Browser Mode? Try to get the Local Storage: localStorage.getItem('mage-cache-storage') to check the available payment methods.

@mrkhoa99 Tried everything (Incognito mode, deleting all cookies, storages etc).
Even new installed OS/browser 馃槂

It happened suddenly.
I were working on cache mechanisms (varnish, redis, raw etc ..) and bumm!

Revert back to 2.1.2. Everything is ok for me now.
I will look it deeper later.

Same problem coming with me have tried with deleting cache and Incognito browser but not resolved i have upgraded from 2.1.2 to 2.1.3

We are also seeing this issue after upgrade from 2.1.2 to 2.1.3 on CentOS 7 php7.
Error reported in knockout.js:3012

ReferenceError: Unable to process binding "if: function (){return isPaymentMethodsAvailable() }"
Message: Can't find variable: isPaymentMethodsAvailable

screen shot 2017-01-10 at 16 19 11

I've checked window.checkoutConfig.

window.checkoutConfig. paymentMethods is empty.
So in payment.js, paymentService's method can not be set. (Magento_Checkout/view/frontend/web/js/view/payment.js):

/** Set payment methods to collection */
paymentService.setPaymentMethods(methodConverter(window.checkoutConfig.paymentMethods));
. This issue may be related with methodConverter or/also latest update's payment module enhancements. After disabling Paypal and Braintree modules, white blank section (which payment methods listed in) gone and standard message shown.
No Payment method available.

Problem still exists in 2.1.4

Any updates on this ?
We are waiting to update main project after resolving this.

We are also seeing this upgrading from 2.1.0 to 2.1.4. The strange thing about it is it seems like a server issue.
We deployed the upgrade to a staging server and the payments worked fine. When we deployed it to production we got the same error as above with no payment methods. We setup another virtual host on our production machine and have the upgraded code isolated there and we are getting payment methods on the same box that did not before.
We are also trying to figure out what is causing this as it is holding up our upgrade.

Also i tried (2.1.2 to 2.1.4) in totally new server, -not vhost or virtual machine :)- but no change(both developer and production modes).

It seems payment methods view model not working properly.

Hope this is addressed ASAP. This is blocking our upgrade deployment. Kind of defeats the purpose of an e-commerce platform if a customer cannot enter payment ;)

@rbostan have you had any luck with this? I am just trying to duplicate the issue after we saw it when deployed to production and had to roll back. I can see where the code is but cannot work on a fix as I have not been able to replicate anywhere.

@jpratt No 馃槥
Error still exists in all situations. Waiting for an answer from contributors.
Anybody handle this ?
/cc @amanuni @stevewinni @veloraven

@rbostan Just curious how your server is setup? Are you using a CDN for static files? compiling js? Just trying to replicate so I can find the issue in code, but cannot replicate unless we push to production which we cannot do again after the last failure when this happened.

@jpratt we are not using cdn for static files. Just merging js&css, not minified.
But tried both merged and not merged version.

Theses days, we are working hard on our live version (2.1.2) and not have too much time to debug this error. Next days, i'm planning for a line by line debugging to solve this.

If i find a clue, will share in here.

@pixiesky and @rbostan wonder if we have common 3rd party modules installed that cause this?

I've removed my comment yesterday as it's misleading and I got the vanilla install to list payment methods. Still getting ReferenceError: Unable to process binding "if: function (){return isPaymentMethodsAvailable() }" on the modified site.

@jpratt there are few modules in use but none of them doesn't affects payment model.
I'll check it again.

Is there anybody tried clean install with sample data ?

Okay so I've spent yet another day on this. Keep hitting knowledge gaps and then filling them in.

So in the payment.html module I am trying to do a console.log of what there is for the method and I'm getting a strange result.

__Note: This is recently inherited code so if you see anything that's rubbish it's not us!__

in app/design/frontend/OLD_AGENCY/THEME_NAME/Magento_Checkout/web/js/view/payment.js :

/**
 * Copyright 漏 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
/*jshint browser:true jquery:true*/
/*global alert*/
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'
    ],
    function (
        $,
        _,
        Component,
        ko,
        quote,
        stepNavigator,
        paymentService,
        methodConverter,
        getPaymentInformation,
        checkoutDataResolver,
        $t
    ) {
        'use strict';

        /** Set payment methods to collection */
        paymentService.setPaymentMethods(methodConverter(window.checkoutConfig.paymentMethods));

        return Component.extend({
            defaults: {
                template: 'Magento_Checkout/payment',
                activeMethod: ''
            },
            isVisible: ko.observable(quote.isVirtual()),
            quoteIsVirtual: quote.isVirtual(),
            isPaymentMethodsAvailable: ko.computed(function () {
                return paymentService.getAvailablePaymentMethods().length > 0;
            }),

            initialize: function () {
                this._super();
                this.isVisible.subscribe(function(val) {
                    if (val === true) {
                        $('.opc-summary-wrapper').css( "visibility", "visible" );
                    }
                });
                checkoutDataResolver.resolvePaymentMethod();
                stepNavigator.registerStep(
                    'payment',
                    null,
                    $t('2. Review & Pay'),
                    this.isVisible,
                    _.bind(this.navigate, this),
                    20
                );
                return this;
            },

            navigate: function () {
                var self = this;
                getPaymentInformation().done(function () {
                    self.isVisible(true);
                });
            },

            getFormKey: function() {
                return window.checkoutConfig.formKey;
            }
        });
    }
);

For debugging only, as it's core code in vendor, I've inserted into vendor/magento/module-checkout/view/frontend/web/template/payment.html

<input data-bind="visible: console.log(isPaymentMethodsAvailable)" />`

Here's the whole edited file:

<!--
/**
 * Copyright 漏 2016 Magento. 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>
                <input data-bind="visible: console.log(isPaymentMethodsAvailable)" />


                <div ifnot="isPaymentMethodsAvailable"
                     class="no-payments-block"
                     translate="'No Payment Methods'">
                </div>
                <!-- ko foreach: getRegion('afterMethods') -->
                    <!-- ko template: getTemplate() --><!-- /ko -->
                <!-- /ko -->
            </fieldset>
        </form>
    </div>
</li>

In the hope that I see the function you can see above:

 isPaymentMethodsAvailable: ko.computed(function () {
                return paymentService.getAvailablePaymentMethods().length > 0;
            }),

But no. It's something from knockout.js itself:

selection_155

_Here it is in full. static/frontend/OLD_AGENCY/THEME_NAME/en_US/knockoutjs/knockout.js_

function dependentObservable() {
        if (arguments.length > 0) {
            if (typeof writeFunction === "function") {
                // Writing a value
                writeFunction.apply(evaluatorFunctionTarget, arguments);
            } else {
                throw new Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
            }
            return this; // Permits chained assignments
        } else {
            // Reading the value
            ko.dependencyDetection.registerDependency(dependentObservable);
            if (_needsEvaluation || (isSleeping && haveDependenciesChanged())) {
                evaluateImmediate();
            }
            return _latestValue;
        }
    }

(I wonder about that return this; // Permits chained assignments line; is that why I'm seeing this function?)

If I edit my debug log to:

<input data-bind="visible: console.log(getFormKey)" />

I see the correct thing

function() {
                return window.checkoutConfig.formKey;
            }

I even edited it from within the file to make sure it's the same one so the return says return window.checkoutConfig.formKey || null; and I got ....

selection_156

So make sense of that if you will! I'm assuming that my limited knockout.js knowledge might be stopping me from grasping why this is happening so I hope to brush up over the weekend. Also, I want to try my same experiment with the vanilla install on my system. I will update unless this triggers an answer to the problem.

Here's the modules installed (with Magento ones removed and the old agency's name has been hidden; which means I can moan about them without naming them).

+-------------------------------------+------------------+
| Name                                | (Schema) Version |
+-------------------------------------+------------------+
| Aheadworks_Followupemail            | 1.1.0            |
| Amasty_Base                         | 1.0.0            |
| ********_CategoryAttributes         | 1.0.0            |
| ********_Menu                       | 1.0.0            |
| ********_TrustPilot                 | 1.0.0            |
| Firebear_ImportExport               | 1.0.2            |
| Iazel_RegenProductUrl               | 1.0.0            |
| MageWorx_HtmlSitemap                | 2.0.0            |
| MageWorx_SeoBase                    | 2.0.3            |
| MageWorx_SeoBreadcrumbs             | 2.0.0            |
| MageWorx_SeoCrossLinks              | 2.0.0            |
| MageWorx_SeoExtended                | 2.0.0            |
| MageWorx_SeoMarkup                  | 2.0.0            |
| MageWorx_SeoRedirects               | 2.0.0            |
| MageWorx_SeoXTemplates              | 2.0.0            |
| Magebuzz_Ajaxcart                   | 1.0.0            |
| Magebuzz_Core                       | 1.0.0            |
| Magefan_Blog                        | 2.2.4            |
| Magefan_LoginAsCustomer             | 2.1.0            |
| Anowave_Package                     | 2.0.0            |
| ********_Compare                    | 1.0.0            |
| ********_GeneralConfig              | 1.0.0            |
| ********_Import                     | 1.0.0            |
| ********_ProductAccessories         | 1.0.0            |
| Amasty_Promo                        | 1.0.2            |
| ********_Widgets                    | 1.0.0            |
| ********_Checkout                   | 1.0.0            |
| MageWorx_XmlSitemap                 | 2.0.0            |
| ********_ProductCanonical           | 1.0.0            |
| ********_PickADay                   | 1.0.5            |
| Anowave_Ec                          | 2.0.0            |
| Ebizmarts_MageMonkey                | 3.0.7            |
| Manadev_Core                        | 1                |
| Manadev_ProductCollection           | 1                |
| Manadev_LayeredNavigation           | 8                |
| PCAPredict_Tag                      | 1.0.7            |
| Sebwite_Sidebar                     | 2.0.2            |
| Ves_All                             | 1.0.0            |
| Ves_ImageSlider                     | 1.0.0            |
| Wyomind_Core                        | 3.0.5            |
| Wyomind_DataFeedManager             | 8.0.6            |
| Wyomind_OrdersExportTool            | 5.0.9            |
+-------------------------------------+------------------+

@mrkhoa99 I had a peak inside localStorage.getItem('mage-cache-storage') and this is what's in it.

selection_157

Can't see anything about payment methods in there.

Tried this with Luma on a fresh install and seeing that dependantObservable function seems to be a normal thing to happen. What I'm seeing on the inherited site are artefacts of previous modifications that I don't seem to be able to get rid of even if I'm flushing cache storage etc so I'm changing my focus to why that is happening.

OK the fix is. Make sure your development environment is actually running in developer mode. Nuke all the var stuff and do a di:compile and a static content deployment, check the env.php file (as it will get overwritten) or make sure with bin/magento deploy:mode:set developer after the upgrade

@pixiesky have you fix the main problem or dependantObservable issue in fresh install ?

@rbostan The dependantObservable thing was still happening in a vanilla install but not producing the error so it's a red herring.

Forgot to mention. In Chrome I needed to do an "empty cache and hard reload" (right click on refresh button with the dev tools open) in order to get everything to come through.

Still broken on my side. Am finally able to replicate on a staging site. This is from a fresh build on the server. Anyone have a resolution to this yet?

No result on my side :(
How is the community can't hear us such an important issue like this?

There are several fixes about less important things and contributors working 'hard' on these (cleaning code styling etc.) but (i think) very most important issues (payment, marketing, performance etc) delaying.

We can not progress to latest versions/improvements with this like issues.

I had the same error message on checkout page after an update from 2.1.3 to 2.1.5. After I changed from the project's custom theme to the Luma theme, the error has been gone. Please check if this may come from overwriting template files.

@rbostan, we couldn't reproduce this issue when upgrading CE from 2.1.2 to 2.1.3. If you did additional steps or specific configurations please provide!

There are the steps we followed:

  1. Install Magento 2.1.2 (CE/EE) version.
  2. Configure payment methods:
    PayPal Checkout Express
    Braintree
    Authorize.net Direct Post
    Credentials for payment methods
  3. Create category and create/assign product to this category.
  4. Go to frontend
  5. Add product to cart
  6. Proceed to checkout
  7. Fill in information for shipping address.
  8. Go to payment and review section
  9. Check that all payment methods are available.
  10. Go to admin panel
  11. Go to System->Tools->Web Setup Wizard
  12. Go to System Config tab. Fill in information for public and private access keys from your magento market place.
  13. Go to System Upgrade tab.
  14. Select version (e.g. Version 2.1.3 CE/EE) and click next
  15. Start readiness check (after checking click next)
  16. Create backup if it necessary.
  17. Upgrade the system.
  18. After upgrade execute steps 4-8
    Expected Result:
    All payment method, which was configured in previous version, are available in Review and Payments section

@KrystynaKabannyk finally 馃憦 馃帄 馃

I did update via composer. There is not any extension or module affects payment progress.
Changed/test with Luma and current theme (SM Market). Both same issue.

Tried to update 2.1.5, no changes. Still payment methods not listed and js error persist.

Forgot my situations or configuration. If you can solve the other(@amanuni, @jpratt and @pixiesky)'s issues, it will be a solution for me 馃槈

same issue

@rbostan, @mrkhoa99, @amanuni, @stevewinni, @jpratt, @hapablap, @pixiesky, Can someone have a call with Magento specialists to demonstrate the error appearance on your instances?

Can everyone check which locale static-content:deploy [LOCAL_HERE] is putting files in, maybe even try to manually copy all files from US to your locale and see if the problem goes away? I'm hitting a different problem on a different project but I think this might be related; I don't have time for a while to test this theory.

(Delete or move your static contents first.)

@KrystynaKabannyk
you had the chance for a call with the other contributors?
if not we could make a call next week.

@splendidinternet, nobody else answered, so we can have a call. What day would work for you from 3pm to 7pm by Kiev time?

Same problem with 2.1.5 :-(

@senders, @KrystynaKabannyk when deploying static content could you try to use

bin/magento setup:static-content:deploy --no-html-minify 

I believe I had similar issue last week. I haven't had time to investigate why, but it helped in my case on v 2.1.5

Is there any update on this ?

@rbostan: can you make sure if your custom modifications (modules or theme) don't overwrite the Magento/Checkout/view/frontend/web/js/view/payment/list.js file somewhere?

Because you are saying you saw this happening in the upgrade from 2.1.2 to 2.1.3 and the isPaymentMethodsAvailable method was introduced in version 2.1.3. This could mean that because you get the error about the method being undefined, that some customization has overwritten the payment/list.js file and this older one is getting loaded instead of the core Magento one, and the older one will most likely not contain the isPaymentMethodsAvailable method.

If I remember correctly we had a very similar problem while doing the same upgrade. This was also because we had overwritten some javascript file for some reason. But we detected this before doing to upgrade on production, because we meticulously go through the diff for each version, because Magento upgrades (even minor releases) are never 100% backwards compatible, especially not in the frontend part. Only when you make 0 customization changes, it is going to be backwards compatible.

Hope this helps.

@hostep Thanks for feedback.
After your comment, tried to update 2.1.6 with no errors.
But it was still same.

Tried with Luma again, all payment methods came back.

At this time, there were some other errors occurs. Please see below.
screen shot 2017-04-17 at 15 53 03

Problem is totally about custom theme (a premium theme which is purchased, shame on them 馃槃 ) but can't find the exact point.

Thanks again.

@rbostan: ok good, so you've narrowed the problem down to your premium theme 馃憤

If I were you, I'd contact them and ask if they have an update of the theme which works on newer Magento versions.
You can't really blame the makers of the theme, because they built something on top of a specific Magento version, and when Magento releases a new version, it almost always has some changes in the frontend which can cause problems like this. If the theme vendor is any good, they should then quickly figure out if their theme is still compatible, and if not, release a new version with fixes for that specific Magento version.

I believe you can now close this issue, as it isn't a bug in Magento itself, but in your custom theme, right? :)

@hostep yeah, may be you are right. but i'm trying with latest (released for compatibility with 2.1.4) updated theme, and this error is occurs with current and previous theme version (really shame on them 馃槃 )

for me, i have started to investigate around theme, because if Luma works, other themes should be.
but other people on this, may have different situations.

closing, thanks again.

@rbostan , did you get this resolved? we just tried update to 2.1.6 and still not working. Which part of the theme needed updating?

@stevewinni-cc not yet. I have not much time to check theme so still waiting. But if you switch luma theme, then payment methods will come back.

You may look theme/modules requirejs-config.js files to check any override of payment methods related files.

fyi.

@rbostan thanks will do... Ill feedback any findings to this thread....

Was this page helpful?
0 / 5 - 0 ratings