Magento 2: Obserwator zdarzeń do wyboru metody płatności

13

Pracuję nad niestandardowym rozszerzeniem, w którym muszę zadzwonić do obserwatora, gdy dowolna metoda płatności zostanie wybrana z listy dostępnych metod płatności na stronie kasy.

Czy ktoś może mi powiedzieć, którego obserwatora zdarzeń powinienem użyć do tego? Muszę wywołać funkcję niestandardową i dodać opłatę do sumy częściowej koszyka.

wprowadź opis zdjęcia tutaj

Dhiren Vasoya
źródło

Odpowiedzi:

10

Niestety obserwatorzy są przydatni tylko w ramach funkcji php. Oznacza to, że aby zdarzenie mogło zostać uruchomione, musi zostać początkowo wywołane dispatch()przez macierzystego lub niestandardowego dyspozytora zdarzeń. W tym konkretnym przypadku podjęte działanie polega na kliknięciu przycisku metody płatności. To kliknięcie nie wyzwala wykonania kodu php, wykonywany jest tylko kod JavaScript.

Ponieważ proces realizacji transakcji w Magento 2 opiera się głównie na Knockout JS, większość akcji dzieje się na froncie przy użyciu Javascript zamiast php po stronie serwera.

Knockout JS jest bardzo elastyczny i można powiązać zdarzenia i obserwować zmienne. Z drugiej strony może wymagać stromej krzywej uczenia się.

Dobrym kątem do spojrzenia na twój projekt byłoby użycie kontrolera zamiast obserwatora:

1. Zacznijmy od utworzenia modułu ...

2. Utwórz kontroler, który wykona logikę po uruchomieniu

Struktura kontrolera: http://www.example.com/route/controller_folder/action

2.1 Utwórz Actionklasę kontrolera :

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 Zarejestruj trasę dla swoich kontrolerów

app / code / NameSpace / Module / etc / adminhtml / tras.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 Ponieważ zostanie to wykorzystane przy kasie, dodaj swoją trasę do listy bezpiecznych adresów URL [EDYCJA]

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. Dodaj plik javascript na stronie kasy za pomocą następującego pliku układu:

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. W tym skrypcie możesz po prostu dodać funkcję wysyłania żądania postu ajax za każdym razem, gdy klikniesz kartę metody płatności.


Najlepsza metoda - Nokaut: Subskrybowanie obserwowalnego

Najlepszym sposobem na wywołanie zdarzenia kliknięcia bez rozszerzenia / zastąpienia pliku podstawowego lub wpływu na oryginalną funkcję kliknięcia byłoby zasubskrybowanie obserwowalnego za pomocą Knockout.

Metoda 2 - Rozszerzenie klasy JS [EDYCJA]

Powinien również istnieć sposób na rozszerzenie początkowej klasy JS

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


    });
});

Metoda 3 - Przesłonięcie metody select-payment-method.js

Gra z Knockout JS może być czasem delikatna i dla celów tej odpowiedzi po prostu zastąpimy funkcję odpowiedzialną za rejestrację metody płatności w wycenie, która jest uruchamiana przez funkcję selectPaymentMethod. To może nie być najbardziej eleganckie rozwiązanie w porównaniu do użycia 100% Knockout JS, ale powinno działać zgodnie z przeznaczeniem bez wpływu na funkcjonalność, chyba że przyszła aktualizacja Magento zakłóci modyfikację oryginalnej funkcji.

Aby lepiej zrozumieć, możesz znaleźć funkcję selectPaymentMethodw wierszu 139 tego pliku:

Magento_Checkout / js / view / payment / default.js

1. Teraz musimy zadeklarować zastąpienie naszej funkcji:

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

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

2. Wreszcie, ponownie używamy funkcji odpowiedzialnej za wybranie metody płatności z niewielkim dodatkiem, aby wykonać nasze wywołanie 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);
        }
});

Za każdym razem, gdy klient kliknie kartę metody płatności, twoja metoda Javascript wyśle ​​do kontrolera żądanie post ajax, które wykona kod php zgodnie z twoją logiką.

Dotyczy to kilku różnych aspektów Magento 2. Chociaż chciałbym zapewnić szybkie i łatwe rozwiązanie twojego pytania, tak właśnie zbudowano Magento 2. Teraz duża część logiki jest implementowana po stronie klienta, a nawet więcej, gdy zbliża się do systemu kasy.

Pamiętaj, aby zawsze zachować ostrożność podczas obsługi systemu kas, ponieważ błąd na stronie kasy może bardzo zaszkodzić sklepowi.

UWAGA: Cały powyższy kod nie został przetestowany

ElGatito
źródło
Naprawdę dobra informacja
Pandurang,
5

wymagać

'Magento_Checkout/js/model/quote'

i obserwuj

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

ponieważ jest tam wiele do obserwowania

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.
źródło
1
Dziękuję Ci! Działa świetnie! Dodatkowo, jeśli chcesz sprawdzić metodę płatności wewnątrz funkcji, możesz użyć pierwszego argumentu , takiego jak: quote.paymentMethod.subscribe(function(method){console.log(method);}, null, 'change');
Siarhey Uchukhlebau,
0

Te 2 Możesz spróbować odpowiednio

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
źródło