Magento 2 - No redirect to external payment provder

淺唱寂寞╮ 提交于 2019-12-06 22:48:38

I've faced the same problem. After spending few days trying to debug getOrderPlaceRedirectUrl I've ended up doing the JavaScript ( kind of a hack ) version of redirection to payment gateway. My guess is that Magento 2 simply didn't implement that yet in new checkout flow. I could be wrong, so try to check with Magento team if there's some designed way to do this. I simply didn't have more time to investigate.

What I've done, is to modify the payment method JavaScript renderer file, and implement my redirection there. Something like this:

/*browser:true*/
/*global define*/
define(
[
    'jquery',
    'Magento_Checkout/js/view/payment/default',
    'Magento_Checkout/js/action/place-order',
    'Magento_Checkout/js/action/select-payment-method',
    'Magento_Customer/js/model/customer',
    'Magento_Checkout/js/checkout-data',
    'Magento_Checkout/js/model/payment/additional-validators',
    'mage/url',
],
function (
    $,
    Component,
    placeOrderAction,
    selectPaymentMethodAction,
    customer,
    checkoutData,
    additionalValidators,
    url) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'My_Module/payment/form-template'
        },

        placeOrder: function (data, event) {
            if (event) {
                event.preventDefault();
            }
            var self = this,
                placeOrder,
                emailValidationResult = customer.isLoggedIn(),
                loginFormSelector = 'form[data-role=email-with-possible-login]';
            if (!customer.isLoggedIn()) {
                $(loginFormSelector).validation();
                emailValidationResult = Boolean($(loginFormSelector + ' input[name=username]').valid());
            }
            if (emailValidationResult && this.validate() && additionalValidators.validate()) {
                this.isPlaceOrderActionAllowed(false);
                placeOrder = placeOrderAction(this.getData(), false, this.messageContainer);

                $.when(placeOrder).fail(function () {
                    self.isPlaceOrderActionAllowed(true);
                }).done(this.afterPlaceOrder.bind(this));
                return true;
            }
            return false;
        },

        selectPaymentMethod: function() {
            selectPaymentMethodAction(this.getData());
            checkoutData.setSelectedPaymentMethod(this.item.method);
            return true;
        },

        afterPlaceOrder: function () {
            window.location.replace(url.build('mymodule/standard/redirect/'));
        }
    });
}
);

afterPlaceOrder is the key modification here. This will redirect to internal controller "mymodule/standard/redirect" right after Place order is clicked. Then use this controller to construct your external redirection, usually POST form submitted to payment gateway page.

The important here is to be aware that:

  1. "mymodule/standard/redirect" will not receive any data from order page, so this approach is only possible if you can construct external redirection without data entered by customer during the checkout process.
  2. "mymodule/standard/redirect" is basically hardcoded in JavaScript file, hence the "hack" reference.

The best thing to analyse that i found for payment gateways was the paypal module. If you see the

./vendor/magento/module-paypal/view/frontend/web/js/action/set-payment-method.js

You see what they do to redirect the user to a certain url. This url is provided by a config provider.

In my case, i developed a Redirect controller which redirects the user to the payment gateway.

The flow is:

Checkout -> (js) -> Redirect Controller -> (php) -> External Gateway -> Success/Cancel Controller -> (php) -> Checkout Onepage Success

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!