cancel
Showing results for 
Search instead for 
Did you mean: 

How to display instructions for custom payment method

How to display instructions for custom payment method

I have finally gave up. I spent 2 whole days trying to do this but I finally could not.

I am developing a custom payment method which needs to show instructions for the customer before the actual purchase.

That simple thing could not be made.

 

First, this is the layout definition (checkout_index_index.xml):

 

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<item name="billing-step" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="children" xsi:type="array">
<item name="payment" xsi:type="array">
<item name="children" xsi:type="array">
<item name="renders" xsi:type="array">
<!-- merge payment method renders here -->
<item name="children" xsi:type="array">
<item name="desytec_transbank_methods" xsi:type="array">
<item name="component" xsi:type="string">Desytec_Transbank/js/view/payment/method-renderer</item>
<item name="methods" xsi:type="array">
<item name="webpay" xsi:type="array">
<item name="isBillingAddressRequired" xsi:type="boolean">true</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>

The renderer is:

 

define(
[
'uiComponent',
'Magento_Checkout/js/model/payment/renderer-list'
],
function (
Component,
rendererList
) {
'use strict';
rendererList.push(
{
type: 'webpay',
component: 'Desytec_Transbank/js/view/payment/method-renderer/webpay'
}
);

return Component.extend({});
}
);

 

And the webpay renderer is:

 

/*browser:true*/
/*global define*/
define(
[
'ko',
'Magento_Checkout/js/view/payment/default',
],
function (ko, Component) {
return Component.extend({
defaults: {
template: 'Desytec_Transbank/payment/webpay'
},
/**
* Get value of instruction field.
* @returns {String}
*/
getInstructions: function () {
return window.checkoutConfig.payment.instructions[this.item.method];
} 
});
}
);

 

The template is:

 

<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
<div class="payment-method-title field choice">
<input type="radio"
name="payment[method]"
class="radio"
data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()"/>
<label data-bind="attr: {'for': getCode()}" class="label"><span data-bind="text: getTitle()"></span></label>
</div>
<div class="payment-method-content">
<div class="payment-method-billing-address">
<!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>
<p data-bind="html: getInstructions()"></p>
<div class="checkout-agreements-block">
<!-- ko foreach: $parent.getRegion('before-place-order') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>
<div class="actions-toolbar">
<div class="primary">
<button class="action primary checkout"
type="submit"
data-bind="
click: placeOrder,
attr: {title: $t('Place Order')},
css: {disabled: !isPlaceOrderActionAllowed()},
enable: (getCode() == isChecked())
"
disabled>
<span data-bind="text: $t('Place Order')"></span>
</button>
</div>
</div>
</div>
</div>

 

And finally, this is the block:

 

<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Desytec\Transbank\Block\Form;
/**
* Abstract class for Cash On Delivery and Bank Transfer payment method form
*/
abstract class Transbank extends \Magento\Payment\Block\Form
{
/**
* Instructions text
*
* @var string
*/
protected $_instructions;
protected $_template = 'form/webpay.phtml';
/**
* Get instructions text from config
*
* @return null|string
*/
public function getInstructions()
{
if ($this->_instructions === null) {
/** @var \Magento\Payment\Model\Method\AbstractMethod $method */
$method = $this->getMethod();
$this->_instructions = $method->getConfigData('instructions');
}
return $this->_instructions;
}
}

 

What is missing here?

Regards
Jaime

Tags (3)
4 REPLIES

Re: How to display instructions for custom payment method

As you can see from your code, the instructions are not passed from PHP (server) to JavaScript (browser).

You should pass it through a config provider: https://mage2.pro/t/630
https://mage2.pro/tags/checkout-config-provider

Re: How to display instructions for custom payment method

Thanks, it does not work, or it is not clear at all.

 

I have added a di.xml file:

 

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Model\CompositeConfigProvider">
        <arguments>
            <argument name="configProviders" xsi:type="array">
                <item name="offline_payment_instructions_config_provider" xsi:type="object">Desytec\Transbank\Model\InstructionsConfigProvider</item>
            </argument>
        </arguments>
    </type>
</config>

Then, I added the model:

 

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Desytec\Transbank\Model;

use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Framework\Escaper;
use Magento\Payment\Helper\Data as PaymentHelper;

class InstructionsConfigProvider implements ConfigProviderInterface
{
    /**
     * @var string[]
     */
    protected $methodCodes = [
        WebPay::CODE,
    ];

    /**
     * @var \Magento\Payment\Model\Method\AbstractMethod[]
     */
    protected $methods = [];

    /**
     * @var Escaper
     */
    protected $escaper;

    /**
     * @param PaymentHelper $paymentHelper
     * @param Escaper $escaper
     */
    public function __construct(
        PaymentHelper $paymentHelper,
        Escaper $escaper
    ) {
        $this->escaper = $escaper;
        foreach ($this->methodCodes as $code) {
            $this->methods[$code] = $paymentHelper->getMethodInstance($code);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getConfig()
    {
        $config = [];
        foreach ($this->methodCodes as $code) {
            if ($this->methods[$code]->isAvailable()) {
                $config['payment']['instructions'][$code] = $this->getInstructions($code);
            }
        }
        return $config;
    }

    /**
     * Get instructions text from config
     *
     * @param string $code
     * @return string
     */
    protected function getInstructions($code)
    {
        return nl2br($this->escaper->escapeHtml($this->methods[$code]->getInstructions()));
    }
}

I have copied them from banktransfer payment method. Other code that your page shows is not really useful, since they belong to magento2 core.

 

I think a little explanation is missing besides just put some lines of code.

 

Thanks

Re: How to display instructions for custom payment method

And finally, I gave up again. It was impossible.

 

How can I expose getInstructions() method to JS? it seems it is defined in Magento core as a default implementation, but how can I actually call it?

 

Thanks

Jaime

Re: How to display instructions for custom payment method

I had the same mistake as you and finally found where I was wrong.

In fact, I've put the di.xml file (with config provider path) into etc folder. But to make it work, this file has to be in etc/frontend folder.

 

Hope this helps !