Magento 2 – Payment Methods Missing on Custom Checkout Module

magento2onepage-checkout

I'm modifying all Magento 2 to accept login with mobile phone instead of email. Register, login, account info, backend, login at checkout, everything is going well.

But when I use my own checkout_index_index.xml instead of the core one, the object which stores the list of renders of each payment method (rendererList) is not filled in.

In the moment of the checkout, using the original checkout_index_index.xml I got this when I debug list.js:

rendered list in the beginning >> 
[Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object] list.js:30 

Using my checkout_index_index.xml:

rendered list in the beginning >> 
[] list.js:30 

The object with the payment methods in both situations:

[Object, Object, Object, Object]
0: Object
method: "paypal_express"
title: "PayPal Express Checkout"
__proto__: Object
1: Object
method: "purchaseorder"
title: "Purchase Order"
__proto__: Object
2: Object
method: "checkmo"
title: "Check / Money order"
__proto__: Object
3: Object
method: "free"
title: "No Payment Information Required"
__proto__: Object
length: 4
__proto__: Array[0]

So, the rendererList used in list.js to render each payment method for my custom module is empty. I spend a whole day trying to find where does this object is filled in without success.

I must say I'm editing checkout_index_index.xml to use my own js files on checkout steps like this:

<item name="component" xsi:type="string">Tmo_Checkout/js/view/shipping</item>
     <item name="provider" xsi:type="string">checkoutProvider</item>
     <item name="sortOrder" xsi:type="string">1</item>
     <item name="children" xsi:type="array">
           <item name="customer-email" xsi:type="array">
                <item name="component" xsi:type="string">Tmo_Checkout/js/view/form/element/username</item>
                <item name="displayArea" xsi:type="string">customer-email</item>
                <item name="tooltip" xsi:type="array">
                      <item name="description" xsi:type="string" translate="true">We'll send your order confirmation here.</item>
                </item>
                <item name="children" xsi:type="array">
                      <item name="before-login-form" xsi:type="array">
                      <item name="component" xsi:type="string">uiComponent</item>
                      <item name="displayArea" xsi:type="string">before-login-form</item>
                      <item name="children" xsi:type="array">
                            <!-- before login form fields -->
                      </item>
               </item>
               <item name="additional-login-form-fields" xsi:type="array">
                   <item name="component" xsi:type="string">uiComponent</item>
                   <item name="displayArea" xsi:type="string">additional-login-form-fields</item>
                   <item name="children" xsi:type="array">
                      <!-- additional login form fields -->
               </item>
          </item>
     </item>
</item>

Finally, the questions are: how do I fill that rendererList?? or where Magento does it?? or how can I specify custom js files for checkout without touching checkout_index_index.xml?? Thanks in advance!

Best Answer

The rendererList is observable JavaScript array provided by the Magento_Checkout/js/model/payment/renderer-list component.

In order to use rendererList in custom payment module the following should be done:

  1. Create in your module view/frontend/layout/checkout_index_index.xml file and declare new payment renderer component (adding as an image to give an idea):

enter image description here

  1. Create the Custom_Payment/js/view/payment/custom_payment.js component and add rendererList component as a dependency. It will allow you to add custom payment renderer into rendererList array:
define(
    [
        'uiComponent',
        'Magento_Checkout/js/model/payment/renderer-list'
    ],
    function (
        Component,
        rendererList
    ) {
        'use strict';
        rendererList.push(
            {
                type: 'custom_payment',
                component: 'Custom_Payment/js/view/payment/method-renderer/custom-payment-renderer'
            }
        );
        /** Add view logic here if needed */
        return Component.extend({});
    }
);
  1. Create Custom_Payment/js/view/payment/method-renderer/custom-payment-renderer component and assign template to render custom payment:
define(
    [
        'jquery',
        'Magento_Payment/js/view/payment/iframe',
        'Magento_Checkout/js/action/set-payment-information'
    ],
    function ($, Component, setPaymentInformationAction) {
        'use strict';

        return Component.extend({
            defaults: {
                template: 'Custom_Payment/payment/custom-payment'
            },
            ...
        });
    }
);
  1. Finally, create Custom_Payment/view/frontend/web/template/payment/custom-payment.html template to have custom payment form.

All Core Payment modules modifies rendererList in the way described above.

I hope answer gives you an idea how rendererList is filled with payment methods.

It is recommended to add custom js files via checkout_index_index.xml. This has to be done very carefully, respecting nested levels of jsLayout component.

Let me know if you still have questions.

Related Topic