web-dev-qa-db-fra.com

Init action hook en retard après l'URL de retour de Paypal?

J'ai la méthode process_ipn qui s'exécute sur le crochet d'action init. On dirait qu'il est renvoyé après le retour de Paypal chez le marchand. Avec cette méthode, je pouvais connaître l'état du paiement tel que completed, pending, failed de Paypal. Et enregistrez-le dans la base de données.

update_user_meta( $user_id, 'status', 'completed' );

Je suis redirigé vers la page de connexion depuis le retour de Paypal vers le marchand avec les ajouts user_id et form_id dans l'URL de retour. J'ai utilisé le filtre login_message pour remplacer le message en fonction de l'état du paiement.

add_filter( 'login_message', array( $this,'custom_login_message' ) );

    public function custom_login_message() {

        $return =  base64_decode ( $_GET['wdb_return'] );
        $return = explode( '&', $return );
        $return = explode( '=', $return[1] );           
        $user_id = isset( $return[1] ) ? $return[1] : -1;

        if( 'completed' === get_user_meta( $user_id, 'status', true ) ) {
            return print_notice( __( 'Payment Completed. Now login.','wdp' ) );
        } else {
              return print_notice( __( 'Payment Failed','wdp' ) );
        }
    }

Le retour au marchand retournera à la page de connexion. Le problème est que l'état est mis à jour trop tard après que la page de connexion apparaisse. Donc, Payment Failed apparaît si je clique sur le retour au marchand instantanément après le paiement. Si j'ai attendu quelques minutes après le paiement puis que je reviens chez le commerçant, ça va.

Notez que $user_id est extrait de l’URL de retour de Paypal et est valide.

Quelle pourrait être la solution?

Merci!

5
Sanzeeb Aryal

Si j'ai bien compris votre question, la situation de concurrence que vous décrivez entre WordPress, sachant que la transaction était "complète" et l'utilisateur qui revient sur votre site est le problème.

En ce qui concerne une solution potentielle, qu’en est-il de changer la façon dont vous abordez cette question de sorte que cette condition de concurrence critique soit acceptée comme une possibilité réelle plutôt que comme une chose que vous pouvez éviter? Vous mentionnez l'un des possibles états Paypal est "en attente" ...

Cela fait des années que je n'ai pas travaillé avec Paypal, mais je me souviens que le flux IPN peut parfois prendre du temps.

Supposons que vous utilisiez ajax: vous pouvez afficher la page de connexion avec une boîte de dialogue conditionnelle ou utiliser une page interstitielle de "traitement des transactions" qui redirige vers la connexion. Votre processus peut remercier votre client, afficher une animation de throbber et expliquer que vous traitez la transaction/attendez la confirmation de paiement de Paypal.

Votre page peut continuer à interroger WordPress et lorsque la méta status de l'utilisateur est "terminée", vous pouvez le mettre à jour et lui montrer le formulaire de connexion. S'il échoue, vous pouvez le gérer en conséquence.

Je ne sais pas si vous définissez le statut "en attente" de Paypal dans la méta de l'utilisateur, mais quel que soit le moyen le plus simple de déclencher ce cas, il suffit de vérifier la présence du user_id et du form_id dans la requête de Paypal.

Dans les cas où IPN est mis à jour rapidement et/ou si l'utilisateur marque une pause avant de revenir sur votre site, le cas de "réussite du paiement" peut déjà fonctionner de manière transparente à votre guise: nul besoin de montrer de throbbers ou quoi que ce soit du genre.

Je pense que l'ajax est la meilleure approche. Un sondage continu toutes les quelques secondes peut donner l’impression que vous générez beaucoup de demandes, mais je doute qu’un grand nombre d’utilisateurs attendent de connaître le résultat de leur transaction à tout moment. Si vous le faites, félicitations, vous gagnez beaucoup d'argent :)

WordPress possède également une API Heartbeat, mais le délai d’interrogation le plus rapide est de 15 secondes. Web Sockets est une autre approche, mais elle est probablement excessive et introduit ses propres complexités.

Voici un tutoriel qui couvre un exemple d'implémentation: https://premium.wpmudev.org/blog/using-ajax-with-wordpress/

Pour une référence à la documentation: https://developer.wordpress.org/plugins/javascript/ajax/

Pour que javascript vérifie en continu toutes les quelques secondes, voir setInterval() et setTimeout(), références: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval et il y a toujours: Il y a toujours:/- https : //www.w3schools.com/js/js_timing.asp

Bonne chance!

2
firxworx

La fonction sleep() peut être utilisée pour retarder l'exécution.

add_filter( 'login_message', array( $this,'custom_login_message' ) );

public function custom_login_message() {
        sleep(5);

        $return =  base64_decode ( $_GET['wdb_return'] );
        $return = explode( '&', $return );
        $return = explode( '=', $return[1] );           
        $user_id = isset( $return[1] ) ? $return[1] : -1;
        .
        .

Maintenant, la notification est "Paiement terminé. Connectez-vous maintenant. ' en cas de paiement réussi. Parce que l'exécution est retardée en réponse au processus retardé de Paypal. Cependant Je pense avoir besoin d'une réponse plus authentique.

0
Sanzeeb Aryal

Une autre méthode Wordpress native consiste à utiliser la planification WP_Cron. Considérez les fonctions wp_schedule_event() et wp_unschedule_event(), qui fonctionnent sous vos crochets de connexion. Chaque fois que l'utilisateur demandera à la page, le Cron vérifiera le statut distant et mettra à jour votre base de données en cas de succès. Dans le dernier cas, vous pouvez annuler la planification de l'événement et montrer à votre utilisateur un message approprié ou une page.

Avantages de la solution: * le client n'envoie pas de manière répétée des demandes ajax * inutile de connaître JS, il suffit d'affecter votre fonction existante à un autre point d'ancrage et d'ajouter un peu plus de logique. * utilisation des fonctionnalités natives de Wordpress

Inconvénients de la solution: * si vous avez un trafic important sur le site, envisagez d'utiliser une autre bibliothèque CRON à la place de Wordpress.

liens: https://codex.wordpress.org/Function_Reference/wp_schedule_eventhttps://code.tutsplus.com/articles/insights-into-wp-cron-an-introduction-to-scheduling-tasks -in-wordpress - wp-23119

0
Paul Burilichev