All of the built in payment methods and all of the examples I've seen use a html template in view/frontend/web/template/payment/ for defining the front end content of the payment method as it displays in checkout. The layout file at view/frontend/layout/checkout_index_index.xml includes a <item name="component" xsi:type="string"> element pointing to a javascript file that adds a component to the Magento_Checkout/js/model/payment/renderer-list. The method-renderer referenced in this file is another javascript file which extends a Magento_Payment/js/view/payment/iframe component with a value for defaults.template.
What I need to do is to have the payment method load with some javascript that needs to have access to a publishable key value that is set in the admin interface. I've been trying to do this with a block so that I can grab my publishable key from the database in the php code for the block, and then insert it in the front end using a phtml view file. I've only been able to get html files to load using the defaults.template value as described above. When I try adding a block declaration to the checkout_index_index.xml I'm not sure where to put it, and I never see any of the code from my phtml file in my payment method in checkout.
Is the payment method content area in checkout a valid place to use a block with a phtml file? If not, how else can I pass the values I need into the template for my payment method? Do I need to use javascript to pull the value from magento using an ajax api call?
One more question: When I use a html template file loaded using the component + method_renderer technique described above, I'm noticing that if I include a script tag in the template, the template will load without the script tag. It seems to be getting stripped out. How do I include custom javascript with a payment method front end?
I've been stuck at this point for a few days now, so I could use some advice. Thanks.
Solved! Go to Solution.
I finally figured this out myself, so I thought I'd share the solution in case anyone else is looking for the same thing.
Use require.js to include your javascript by defining paths in view/frontend/requirejs-config.js like this:
var config = { paths: { "my_external_file": "https://sample.test.com/my_file", "my_local_file": "./Company_ModuleName/js/view/myfolder/myjsfile" } };
Then include the javascript in the define section of your method renderer file at view/frontend/web/js/payment/method-renderer/ like so:
define( [ 'require', 'jquery', 'my_external_file', 'my_local_file' ], function (require, $, myExternalThing, myLocalThing) { 'use strict'; return Component.extend({ ...
In your javascript file you can have a look at the window.checkoutConfig object. To get your config values into this object you need a config provider. Add the config provider to etc/frontend/di.xml like this:
<type name="Magento\Checkout\Model\CompositeConfigProvider"> <arguments> <argument name="configProviders" xsi:type="array"> <item name="my_config_provider" xsi:type="object">CompanyName\ModuleName\Model\MyConfigProvider</item> </argument> </arguments> </type>
Make the config provider php file in your Model folder like so:
<?php namespace CompanyName\ModuleName\Model; use Magento\Checkout\Model\ConfigProviderInterface; use \Magento\Framework\App\Config\ScopeConfigInterface as ScopeConfig; class MyConfigProvider implements ConfigProviderInterface { /** * @var \Magento\Framework\App\Config\ScopeConfigInterface */ protected $scopeConfig; /** * first config value config path */ const FIRST_CONFIG_VALUE = 'payment/mymodulename/first_config_value'; /** * second config value config path */ const SECOND_CONFIG_VALUE = 'payment/mymodulename/second_config_value'; /** * @param ScopeConfig $scopeConfig */ public function __construct( ScopeConfig $scopeConfig ) { $this->scopeConfig = $scopeConfig; } /** * {@inheritdoc} */ public function getConfig() { $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; $config = [ 'payment' => [ 'mymodulename' => [ 'first_config_value' => $this->scopeConfig->getValue(self::FIRST_CONFIG_VALUE, $storeScope), 'second_config_value' => $this->scopeConfig->getValue(self::SECOND_CONFIG_VALUE, $storeScope) ] ] ]; return $config; } }
This is the process that worked for me.
Update: I figured out how to load the javascript I needed using require.js, but I still need help with how to pass data to the javascript. I need to access the config value stored in the database (publishable key) and also the magento checkout information (such as amount).
I finally figured this out myself, so I thought I'd share the solution in case anyone else is looking for the same thing.
Use require.js to include your javascript by defining paths in view/frontend/requirejs-config.js like this:
var config = { paths: { "my_external_file": "https://sample.test.com/my_file", "my_local_file": "./Company_ModuleName/js/view/myfolder/myjsfile" } };
Then include the javascript in the define section of your method renderer file at view/frontend/web/js/payment/method-renderer/ like so:
define( [ 'require', 'jquery', 'my_external_file', 'my_local_file' ], function (require, $, myExternalThing, myLocalThing) { 'use strict'; return Component.extend({ ...
In your javascript file you can have a look at the window.checkoutConfig object. To get your config values into this object you need a config provider. Add the config provider to etc/frontend/di.xml like this:
<type name="Magento\Checkout\Model\CompositeConfigProvider"> <arguments> <argument name="configProviders" xsi:type="array"> <item name="my_config_provider" xsi:type="object">CompanyName\ModuleName\Model\MyConfigProvider</item> </argument> </arguments> </type>
Make the config provider php file in your Model folder like so:
<?php namespace CompanyName\ModuleName\Model; use Magento\Checkout\Model\ConfigProviderInterface; use \Magento\Framework\App\Config\ScopeConfigInterface as ScopeConfig; class MyConfigProvider implements ConfigProviderInterface { /** * @var \Magento\Framework\App\Config\ScopeConfigInterface */ protected $scopeConfig; /** * first config value config path */ const FIRST_CONFIG_VALUE = 'payment/mymodulename/first_config_value'; /** * second config value config path */ const SECOND_CONFIG_VALUE = 'payment/mymodulename/second_config_value'; /** * @param ScopeConfig $scopeConfig */ public function __construct( ScopeConfig $scopeConfig ) { $this->scopeConfig = $scopeConfig; } /** * {@inheritdoc} */ public function getConfig() { $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; $config = [ 'payment' => [ 'mymodulename' => [ 'first_config_value' => $this->scopeConfig->getValue(self::FIRST_CONFIG_VALUE, $storeScope), 'second_config_value' => $this->scopeConfig->getValue(self::SECOND_CONFIG_VALUE, $storeScope) ] ] ]; return $config; } }
This is the process that worked for me.
Hi,
Can share the code . it more helpful to us