Magento 2: Observador de eventos para la selección del método de pago

13

Estoy trabajando en una extensión personalizada donde necesito llamar a un observador cuando se selecciona cualquier método de pago de la lista de métodos de pago disponibles en la página de pago frontend.

¿Alguien puede decirme qué observador de eventos debo usar para esto? Necesito llamar a una función personalizada y agregar una tarifa al subtotal del carrito.

ingrese la descripción de la imagen aquí

Dhiren Vasoya
fuente

Respuestas:

10

Desafortunadamente, los observadores son útiles solo dentro de las funciones de php. Esto significa que para que un evento se active, debe ser enviado inicialmente dispatch()por un despachador de eventos nativo o personalizado. En este caso particular, la acción tomada es hacer clic sobre un botón de método de pago. Este clic no activa la ejecución de ningún código php, solo se ejecuta el código Javascript.

Como el proceso de pago en Magento 2 se basa principalmente en Knockout JS, la mayoría de las acciones ocurren en la interfaz usando Javascript en lugar del php del lado del servidor.

Knockout JS es muy flexible y es posible vincular eventos y observar variables. Por otro lado, puede requerir una curva de aprendizaje empinada.

Un buen ángulo para observar su proyecto sería utilizar un controlador en lugar de un observador:

1. Comencemos creando un módulo ...

2. Cree un controlador que haga su lógica cuando se active

Estructura del controlador: http://www.example.com/route/controller_folder/action

2.1 Crear la Actionclase de 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 una ruta para sus 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 esto se usará al finalizar la compra, agregue su ruta a la lista segura de URL [EDITAR]

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. Agregue un archivo javascript en la página de pago utilizando el siguiente archivo de diseño:

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. En este script, simplemente puede agregar una función para enviar una solicitud de publicación ajax cada vez que se hace clic en una pestaña de método de pago.


El mejor método: Knockout: suscribirse a observables

La mejor forma de activar el evento de clic sin extender / anular el archivo principal o afectar la función de clic original implicaría suscribir un observable con la ayuda de Knockout.

Método 2 - Extender la clase JS [EDITAR]

También debería haber una manera de extender la clase 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: anulación de select-payment-method.js

Jugar con Knockout JS puede ser delicado a veces y para el propósito de esta respuesta simplemente anularemos la función responsable de registrar el método de pago en la cotización que se activa mediante la función selectPaymentMethod. Puede que no sea la solución más elegante en comparación con el uso de 100% Knockout JS, pero debería funcionar según lo previsto sin afectar ninguna funcionalidad a menos que una futura actualización de Magento interfiera modificando la función original.

Para comprender mejor, puede encontrar la función selectPaymentMethoden la línea 139 de este archivo:

Magento_Checkout / js / view / payment / default.js

1. Ahora tenemos que declarar nuestra función de anulación:

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 la función responsable de seleccionar el método de pago con una pequeña adición para hacer nuestra llamada 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 un cliente haga clic en la pestaña de un método de pago, su método Javascript enviará una solicitud posterior ajax a su controlador que ejecutará el código php con su lógica.

Esto toca varios aspectos diferentes de Magento 2. Aunque me gustaría proporcionar una solución rápida y fácil a su pregunta, esa es la forma en que Magento 2 se ha creado. Ahora, una gran parte de la lógica se implementa del lado del cliente y aún más cuando se acerca al sistema de pago.

Recuerde siempre tener cuidado al tratar con el sistema de pago, un error en una página de pago puede dañar gravemente a una tienda.

NOTA: todo el código anterior no se ha probado

ElGatito
fuente
Muy buena información
Pandurang
5

exigir

'Magento_Checkout/js/model/quote'

y observar

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

ya que hay mucho para observar allí

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
fuente
1
¡Gracias! ¡Funciona genial! Además, si desea verificar el método de pago dentro de una función, puede usar el primer argumento , como: quote.paymentMethod.subscribe(function(method){console.log(method);}, null, 'change');
Siarhey Uchukhlebau
0

Estos 2 puedes probar en consecuencia

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
fuente