Magento 2: Observateur d'événements pour la sélection des méthodes de paiement


13

Je travaille sur une extension personnalisée où je dois appeler un observateur lorsqu'un mode de paiement est sélectionné dans la liste des modes de paiement disponibles sur la page de paiement frontale.

Quelqu'un peut-il me dire quel observateur d'événement dois-je utiliser pour cela? Je dois appeler une fonction personnalisée et ajouter des frais au sous-total du panier.

entrez la description de l'image ici

Réponses:


10

Malheureusement, les observateurs ne sont utiles que dans les fonctions php. Cela signifie que pour qu'un événement soit déclenché, il doit être initialement distribué dispatch()par un répartiteur d'événements natif ou personnalisé. Dans ce cas particulier, l'action entreprise est un clic sur un bouton de mode de paiement. Ce clic ne déclenche aucune exécution de code php, seul le code Javascript est exécuté.

Comme le processus de paiement dans Magento 2 est principalement construit autour de Knockout JS, la plupart des actions se produisent sur le frontend en utilisant Javascript au lieu du php côté serveur.

Knockout JS est très flexible et il est possible de lier des événements et d'observer des variables. De l'autre côté, cela peut nécessiter une courbe d'apprentissage abrupte.

Un bon angle à considérer pour votre projet serait d'utiliser un contrôleur au lieu d'un observateur:

1. Commençons par créer un module ...

2. Créez un contrôleur qui fait votre logique lorsqu'il est déclenché

Structure du contrôleur: http://www.example.com/route/controller_folder/action

2.1 Créez la Actionclasse de contrôleur :

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 Enregistrer un itinéraire pour vos contrôleurs

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 Comme cela sera utilisé lors du paiement, ajoutez votre itinéraire à la liste des URL sécurisées [MODIFIER]

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. Ajoutez un fichier javascript sur la page de paiement à l'aide du fichier de mise en page suivant:

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. Dans ce script, vous pouvez simplement ajouter une fonction pour envoyer une demande de publication ajax chaque fois qu'un onglet de mode de paiement est cliqué.


Meilleure méthode - Knockout: abonnement à observable

La meilleure façon de déclencher l'événement de clic sans étendre / remplacer le fichier de base ou sans impact sur la fonction de clic d'origine consisterait à souscrire un observable à l'aide de Knockout.

Méthode 2 - Étendre la classe JS [EDIT]

Il devrait également y avoir un moyen d'étendre la classe JS initiale

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éthode 3 - Remplacer select-payment-method.js

Jouer avec Knockout JS peut parfois être délicat et dans le cadre de cette réponse, nous remplacerons simplement la fonction responsable de l'enregistrement du mode de paiement dans le devis qui est déclenché par la fonction selectPaymentMethod. Ce n'est peut-être pas la solution la plus élégante par rapport à l'utilisation de 100% Knockout JS, mais cela devrait fonctionner comme prévu sans affecter aucune fonctionnalité, à moins qu'une future mise à jour de Magento n'interfère en modifiant la fonction d'origine.

Pour mieux comprendre, vous pouvez trouver la fonction selectPaymentMethodà la ligne 139 de ce fichier:

Magento_Checkout / js / view / payment / default.js

1. Maintenant, nous devons déclarer le remplacement de notre fonction:

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. Enfin, nous réutilisons la fonction de sélection du mode de paiement avec un petit plus pour effectuer notre appel 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);
        }
});

Chaque fois qu'un client cliquera sur un onglet de méthode de paiement, votre méthode Javascript enverra une requête post ajax à votre contrôleur qui exécutera le code php avec votre logique.

Cela touche plusieurs aspects différents de Magento 2. Bien que j'aimerais fournir une solution rapide et facile à votre question, c'est juste la façon dont Magento 2 a été construit. Désormais, une grande partie de la logique est implémentée côté client et encore plus à l'approche du système de caisse.

N'oubliez pas de toujours être prudent lorsque vous traitez avec le système de paiement, un bogue sur une page de paiement peut faire très mal à un magasin.

REMARQUE: tout le code ci-dessus n'est pas testé


Vraiment de bonnes informations
Pandurang

5

exiger

'Magento_Checkout/js/model/quote'

et observer

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

car il y a beaucoup à observer

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
Merci! Fonctionne très bien! De plus, si vous souhaitez vérifier le mode de paiement à l'intérieur d'une fonction, vous pouvez utiliser le premier argument , comme: quote.paymentMethod.subscribe(function(method){console.log(method);}, null, 'change');
Siarhey Uchukhlebau

0

Ces 2 Vous pouvez essayer en conséquence

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
        ]);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.