Magento 2: Observador de eventos para seleção de método de pagamento

13

Estou trabalhando em uma extensão personalizada na qual preciso chamar um observador quando qualquer método de pagamento for selecionado na lista de formas de pagamento disponíveis na página de check-out de front-end.

Alguém pode me dizer qual observador de eventos devo usar para isso? Preciso chamar uma função personalizada e adicionar taxa ao subtotal do carrinho.

insira a descrição da imagem aqui

Dhiren Vasoya
fonte

Respostas:

10

Infelizmente, os observadores são úteis apenas dentro das funções php. Isso significa que, para que um evento seja acionado, ele deve ser despachado inicialmente dispatch()por um distribuidor de eventos nativo ou personalizado. Nesse caso específico, a ação executada é clicar em um botão da forma de pagamento. Este clique não aciona nenhuma execução de código php, apenas o código Javascript é executado.

Como o processo de checkout no Magento 2 é construído principalmente em torno do Knockout JS, a maioria das ações acontece no frontend usando Javascript, em vez de php no servidor.

Knockout JS é muito flexível e é possível vincular eventos e observar variáveis. Por outro lado, pode exigir uma curva de aprendizado acentuada.

Um bom ângulo para analisar o seu projeto seria usar um controlador em vez de um observador:

1. Vamos começar criando um módulo ...

2. Crie um controlador que faça sua lógica quando acionado

Estrutura do controlador: http://www.example.com/route/controller_folder/action

2.1 Crie a Actionclasse do controlador :

app / code / NameSpace / Module / Controller / Test / Action.php

namespace NameSpace\Module\Controller\Test;

class Action extends \Magento\Framework\App\Action\Action
{
    public function execute()
    {
        $request = $this->getRequest();
        //EXECUTE YOUR LOGIC HERE
    }
}

2.2 Registre uma rota para seus controladores

app / code / NameSpace / Module / etc / adminhtml / routes.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
  <router id="standard">
     <route id="route" frontName="route">
        <module name="NameSpace_Module" />
    </route>
  </router>
</config>

2.3 Como isso será usado no checkout, adicione sua rota à lista de URLs seguros [EDIT]

app / code / NameSpace / Module / etc / di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Url\SecurityInfo">
        <arguments>
            <argument name="secureUrlList" xsi:type="array">
                <item name="route" xsi:type="string">/route/</item>
            </argument>
        </arguments>
    </type>
</config>

3. Adicione um arquivo javascript na página de checkout usando o seguinte arquivo de layout:

app / code / NameSpace / Module / view / frontend / layout / 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">
    <head>
       <link src="NameSpace_Module::js/payment-method-trigger.js"/>
    </head>
</page>

4. Nesse script, você pode simplesmente adicionar uma função para enviar uma solicitação de postagem do ajax sempre que uma guia de método de pagamento for clicada.


Melhor método - Knockout: assinando o observável

A melhor maneira de acionar o evento de clique sem estender / substituir o arquivo principal ou impactar a função de clique original envolveria a assinatura de um observável com a ajuda do Knockout.

Método 2 - Estender a classe JS [EDIT]

Também deve haver uma maneira de estender a classe JS inicial

define([
    'NameSpace_Module/path/to/original/file', //JS FILE TO EXTEND
], function (originalFile) { //PASS AS A PARAMETER
    'use strict';

    return originalFile.extend({ //EXTEND
        //FUNCTIONS ADDED HERE WILL OVERRIDE FUNCTIONS
        //FROM ORIGINAL CLASS IF ALREADY EXISTS
        someFunction: {
            someLogic();
        },


    });
});

Método 3 - Substituindo select-payment-method.js

Às vezes, jogar com Knockout JS pode ser delicado e, para os fins desta resposta, substituiremos a função responsável por registrar o método de pagamento na cotação, que é acionada pela função selectPaymentMethod. Pode não ser a solução mais elegante em comparação ao uso de 100% de Knockout JS, mas deve funcionar como planejado sem afetar nenhuma funcionalidade, a menos que uma atualização futura do Magento interfira modificando a função original.

Para entender melhor, você pode encontrar a função selectPaymentMethodna linha 139 deste arquivo:

Magento_Checkout / js / view / payment / default.js

1. Agora temos que declarar nossa função substituída:

app / code / NameSpace / Module / view / frontend / requirejs-config.js

var config = {
    map: {
        '*': {
            'Magento_Checkout/js/action/select-payment-method':
                'NameSpace_Module/js/action/payment/select-payment-method'
        }
    }
};

2. Finalmente, reutilizamos a função responsável por selecionar o método de pagamento com um pequeno acréscimo para fazer nossa chamada ajax!

app / code / NameSpace / Module / view / frontend / web / js / action / payment / select-payment-method.js

define(
    [
    'jquery',
    'uiComponent',
    'ko',
    'Magento_Checkout/js/model/quote',
    ], function ($, uiComponent, ko, quote) {
        'use strict';

        function () {
            $.ajax({
                showLoader: true,
                url: 'http://www.example.com/route/controller_folder/action',
                data: { action : 1, param : 2},
                type: "POST",
                dataType: 'json'
            }).done(function (data) {
                alert('Request Sent');
            });
        };

        return function (paymentMethod) {
            quote.paymentMethod(paymentMethod);
        }
});

Cada vez que um cliente clica em uma guia de método de pagamento, seu método Javascript envia uma solicitação pós-ajax ao seu controlador, que executa o código php com sua lógica.

Isso toca vários aspectos diferentes do Magento 2. Embora eu queira fornecer uma solução rápida e fácil para sua pergunta, é assim que o Magento 2 foi criado. Agora, grande parte da lógica é implementada no lado do cliente e ainda mais ao abordar o sistema de checkout.

Lembre-se de sempre ter cuidado ao lidar com o sistema de checkout; um bug em uma página de checkout pode prejudicar muito a loja.

NOTA: Todo o código acima não foi testado

ElGatito
fonte
Informações muito boas
Pandurang
5

exigir

'Magento_Checkout/js/model/quote'

e observe

quote.paymentMethod.subscribe(function(){console.log('yay')}, null, 'change');

como há muito o que observar lá

var billingAddress = ko.observable(null);
var shippingAddress = ko.observable(null);
var shippingMethod = ko.observable(null);
var paymentMethod = ko.observable(null);
var totals = ko.observable(totalsData);
var collectedTotals = ko.observable({})
Anton S
fonte
1
Obrigado! Funciona bem! Além disso, se você quiser verificar o método de pagamento dentro de uma função, poderá usar o primeiro argumento , como: quote.paymentMethod.subscribe(function(method){console.log(method);}, null, 'change');
Siarhey Uchukhlebau
0

Estes 2 Você pode tentar em conformidade

app/code/Magento/Payment/Model/Method/Adapter.php 
    payment_method_is_active
    $this->eventManager->dispatch(
        'payment_method_is_active',
        [
    'result' => $checkResult,
    'method_instance' => $this,
    'quote' => $quote
        ]);

Or 
    app/code/Magento/Payment/Model/Method/Adapter.php 
    payment_method_assign_data_
    $this->eventManager->dispatch(
        'payment_method_assign_data_' . $this->getCode(),
        [
    'method' => $this,
    'data' => $data
        ]);
supriya mishra
fonte