Magento 2: Event Observer per la selezione del metodo di pagamento


13

Sto lavorando su un'estensione personalizzata in cui devo chiamare un osservatore quando viene selezionato un metodo di pagamento dall'elenco dei metodi di pagamento disponibili nella pagina di pagamento del frontend.

Qualcuno può dirmi quale osservatore di eventi dovrei usare per questo? Devo chiamare una funzione personalizzata e aggiungere una commissione al totale parziale del carrello.

inserisci qui la descrizione dell'immagine

Risposte:


10

Sfortunatamente, gli osservatori sono utili solo all'interno delle funzioni php. Ciò significa che, per essere attivato, un evento deve essere inizialmente inviato dispatch()da un dispatcher di eventi nativo o personalizzato. In questo caso particolare, l'azione intrapresa è un clic sul pulsante di un metodo di pagamento. Questo clic non attiva alcuna esecuzione del codice php, viene eseguito solo il codice Javascript.

Poiché il processo di checkout in Magento 2 è principalmente basato su Knockout JS, la maggior parte delle azioni avviene sul frontend usando Javascript anziché php lato server.

Knockout JS è molto flessibile ed è possibile associare eventi e osservare variabili. Dall'altro lato, potrebbe essere necessaria una curva di apprendimento ripida.

Un buon punto di vista per il tuo progetto sarebbe quello di utilizzare un controller anziché un osservatore:

1. Cominciamo creando un modulo ...

2. Crea un controller che fa la tua logica quando attivato

Struttura del controller: http://www.example.com/route/controller_folder/action

2.1 Creare la Actionclasse controller :

app / code / namespace / modulo / 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 Registrare un percorso per i controller

app / code / namespace / modulo / 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 Poiché verrà utilizzato al momento del pagamento, aggiungi il tuo percorso all'elenco URL sicuro [EDIT]

app / code / namespace / modulo / 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. Aggiungi un file javascript nella pagina di pagamento utilizzando il seguente file di layout:

app / code / NameSpace / modulo / 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. In questo script è possibile semplicemente aggiungere una funzione per inviare una richiesta di posta Ajax ogni volta che si fa clic su una scheda del metodo di pagamento.


Metodo migliore - Knockout: iscrizione a osservabile

Il modo migliore per attivare l'evento click senza estendere / sovrascrivere il file core o influire sulla funzione click originale prevede la sottoscrizione di un osservabile con l'aiuto di Knockout.

Metodo 2 - Estendi la classe JS [EDIT]

Dovrebbe esserci anche un modo per estendere la classe JS iniziale

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();
        },


    });
});

Metodo 3 - Sostituzione di select-payment-method.js

Giocare con Knockout JS a volte può essere delicato e ai fini di questa risposta sostituiremo semplicemente la funzione responsabile della registrazione del metodo di pagamento nel preventivo che viene attivato dalla funzione selectPaymentMethod. Potrebbe non essere la soluzione più elegante rispetto all'uso di Knockout JS al 100%, ma dovrebbe funzionare come previsto senza influire su alcuna funzionalità a meno che un futuro aggiornamento di Magento non interferisca modificando la funzione originale.

Per capire meglio puoi trovare la funzione selectPaymentMethodsulla riga 139 di questo file:

Magento_Checkout / js / view / pagamento / Default.js

1. Ora dobbiamo dichiarare la nostra funzione di override:

app / code / NameSpace / modulo / immagine / frontend / requirejs-config.js

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

2. Infine, riutilizziamo la funzione responsabile della selezione del metodo di pagamento con una piccola aggiunta per effettuare la nostra chiamata ajax!

app / code / namespace / modulo / view / frontend / web / js / azione / pagamento / selezionare-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);
        }
});

Ogni volta che un cliente fa clic su una scheda del metodo di pagamento, il tuo metodo Javascript invierà una richiesta post ajax al tuo controller che eseguirà il codice php con la tua logica.

Questo tocca diversi aspetti di Magento 2. Anche se vorrei fornire una soluzione rapida e semplice alla tua domanda, questo è solo il modo in cui Magento 2 è stato creato. Ora, gran parte della logica è implementata sul lato client e ancora di più quando ci si avvicina al sistema di checkout.

Ricorda di fare sempre attenzione quando gestisci il sistema di checkout, un bug in una pagina di checkout può danneggiare gravemente un negozio.

NOTA: tutto il codice sopra non è testato


Davvero buone informazioni
Pandurang,

5

richiedere

'Magento_Checkout/js/model/quote'

e osservare

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

come ci sono molte cose da osservare 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({})

1
Grazie! Funziona alla grande! Inoltre, se si desidera verificare il metodo di pagamento all'interno di una funzione, è possibile utilizzare il primo argomento , ad esempio: quote.paymentMethod.subscribe(function(method){console.log(method);}, null, 'change');
Siarhey Uchukhlebau

0

Questi 2 Puoi provare di conseguenza

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
        ]);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.