2

While implementing a payment gateway, I ran into the situation where it is best for the user experience to use popups for the 3D Secure process.

The flow is like this:

  1. User is on the payment page and enters credit card data into hosted fields.
  2. On the "Buy" onclick event, I call the javascript snippet of the gateway to get the card token.
  3. I post that to the back-end.
  4. The back-end checks if 3DS is required.
  5. If yes, the front-end opens a new window with the 3DS form.

The code for the onclick is the following:

var win;

$("#buy").click(function() {

    gateway.Tokenize(function(token) {

        $.ajax({
            url: 'backend.php',
            type: "POST",
            data: {
                token: token
            }
        }).done(function(data) {

            if (data.threeDRequired) {
                win = window.open(data.url, "_blank");
                win.focus();
            }

        });

    });

});

Normally there is no problem with this and the pop up opens but if the Tokenize method or the $.ajax call takes too long to complete, the popup blocker gets triggered. Even adding async: false to the $.ajax call does not help.

Is there anything I can do to make that work in all cases? The only solution I can think of currently is to either open a popup right at the start of the click event and then load the URL when it is available or to let the user click an additional button if the popup got blocked. Both do not seem ideal.

maddo7
  • 4,503
  • 6
  • 31
  • 51

1 Answers1

0

events are synchronous and expire right away, meaning you can't trap a click and use it's privileges/permissions at any time in the future.

What you could do, is open the popup right away, and either close it, or update its location, once the Tokenize returns.

This is an optimistic approach, but if you are confident success is the most expected behavior, it shouldn't be too annoying.

var win;
$("#buy").click(function() {
  win = window.open("about:blank", "_blank");
  gateway.Tokenize(function(token) {
    $.ajax({
      url: 'backend.php',
      type: "POST",
      data: {token: token}
    }).done(function(data) {
      if (data.threeDRequired) {
        win.location = data.url;
        win.focus();
      }
      else {
        win.close();
      }
    });
  });
});

This should do the trick.

Andrea Giammarchi
  • 3,038
  • 15
  • 25