Magento 2: Event Observer zur Auswahl der Zahlungsmethode

13

Ich arbeite an einer benutzerdefinierten Erweiterung, bei der ich einen Beobachter anrufen muss, wenn eine Zahlungsmethode aus der Liste der verfügbaren Zahlungsmethoden auf der Checkout-Seite des Frontends ausgewählt wird.

Kann mir jemand sagen, welchen Ereignisbeobachter ich dafür verwenden soll? Ich muss eine benutzerdefinierte Funktion aufrufen und eine Gebühr zur Zwischensumme des Einkaufswagens hinzufügen.

Bildbeschreibung hier eingeben

Dhiren Vasoya
quelle

Antworten:

10

Leider sind Beobachter nur innerhalb von PHP-Funktionen nützlich. Dies bedeutet, dass ein Ereignis, das ausgelöst werden soll, zunächst dispatch()entweder von einem systemeigenen oder einem benutzerdefinierten Ereignis-Dispatcher ausgelöst werden muss . In diesem speziellen Fall handelt es sich bei der ausgeführten Aktion um einen Klick auf eine Zahlungsmethode. Dieser Klick löst keine PHP-Code-Ausführung aus, nur Javascript-Code wird ausgeführt.

Da der Checkout-Prozess in Magento 2 hauptsächlich auf Knockout JS basiert, werden die meisten Aktionen auf dem Frontend mithilfe von Javascript anstelle von serverseitigem PHP ausgeführt.

Knockout JS ist sehr flexibel und es ist möglich, Ereignisse zu binden und Variablen zu beobachten. Andererseits kann eine steile Lernkurve erforderlich sein.

Ein guter Blickwinkel für Ihr Projekt ist die Verwendung eines Controllers anstelle eines Beobachters:

1. Beginnen wir mit der Erstellung eines Moduls ...

2. Erstellen Sie einen Controller, der Ihre Logik beim Auslösen ausführt

Controller-Struktur: http://www.example.com/route/controller_folder/action

2.1 Erstellen Sie die Controller- ActionKlasse:

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 Registrieren Sie eine Route für Ihre Steuerungen

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 Da dies beim Auschecken verwendet wird, fügen Sie Ihre Route der Liste sicherer URLs hinzu [BEARBEITEN]

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. Fügen Sie auf der Checkout-Seite eine Javascript-Datei mit dem folgenden Layout hinzu:

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. In diesem Skript können Sie einfach eine Funktion hinzufügen, um jedes Mal eine Ajax-Post-Anfrage zu senden, wenn auf eine Registerkarte für die Zahlungsmethode geklickt wurde.


Beste Methode - Knockout: Abonnieren von Observable

Die beste Möglichkeit, das Klickereignis auszulösen, ohne die Kerndatei zu erweitern / zu überschreiben oder die ursprüngliche Klickfunktion zu beeinträchtigen, besteht darin, eine Observable mit Hilfe von Knockout zu abonnieren.

Methode 2 - JS-Klasse erweitern [BEARBEITEN]

Es sollte auch eine Möglichkeit geben, die anfängliche JS-Klasse zu erweitern

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


    });
});

Methode 3 - Überschreiben von select-payment-method.js

Das Spielen mit Knockout JS kann manchmal heikel sein. Zum Zweck dieser Antwort überschreiben wir einfach die Funktion, die für die Registrierung der Zahlungsmethode in dem Angebot verantwortlich ist, das von der Funktion selectPaymentMethod ausgelöst wird. Es ist möglicherweise nicht die eleganteste Lösung im Vergleich zur Verwendung von 100% Knockout JS, aber es sollte wie beabsichtigt funktionieren, ohne die Funktionalität zu beeinträchtigen, es sei denn, ein zukünftiges Magento-Update würde durch die Änderung der ursprünglichen Funktion stören.

Zum besseren Verständnis finden Sie die Funktion selectPaymentMethodin Zeile 139 dieser Datei:

Magento_Checkout / js / view / payment / default.js

1. Jetzt müssen wir unsere Funktion als Override deklarieren:

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. Schließlich verwenden wir die für die Auswahl der Zahlungsmethode verantwortliche Funktion mit einem kleinen Zusatz, um unseren Ajax-Anruf zu tätigen!

app / code / NameSpace / Modul / 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);
        }
});

Jedes Mal, wenn ein Kunde auf eine Zahlungsmethode klickt, sendet Ihre Javascript-Methode eine Post-Ajax-Anfrage an Ihren Controller, der den PHP-Code mit Ihrer Logik ausführt.

Dies betrifft verschiedene Aspekte von Magento 2. Obwohl ich gerne eine schnelle und einfache Lösung für Ihre Frage bieten möchte, wurde Magento 2 genau so erstellt. Jetzt wird ein großer Teil der Logik clientseitig implementiert und noch mehr, wenn Sie sich dem Kassensystem nähern.

Denken Sie daran, beim Umgang mit dem Checkout-System immer vorsichtig zu sein. Ein Fehler auf einer Checkout-Seite kann einen Laden sehr schwer verletzen.

HINWEIS: Der gesamte obige Code ist nicht getestet

ElGatito
quelle
Wirklich gute Informationen
Pandurang
5

benötigen

'Magento_Checkout/js/model/quote'

und beobachten

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

da gibt es viel zu beobachten

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
quelle
1
Danke! Funktioniert super! Wenn Sie die Zahlungsmethode in einer Funktion überprüfen möchten, können Sie auch das erste Argument verwenden , z. quote.paymentMethod.subscribe(function(method){console.log(method);}, null, 'change');
B .
0

Diese 2 kannst du dementsprechend probieren

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
quelle