2

(works fine in Chrome on the iPhone)

I get this error:

TypeError: 'undefined' is not an object (evaluating 'win.location') in dg.js line 3

And the lightbox does not open.

The code in question inside PayPal's dg.js is:

startFlow: function (url) {
    var win = that._render();
    if (win.location) {
        win.location = url;
    } else {
        win.src = url;
    }
}

So does mobile Safari not understand that._render()? How do I get around this?

If it matters, I'm using Adaptive Payments, calling it like so:

var dg = new PAYPAL.apps.DGFlow({
    trigger: null, 
    expType: 'light'
});
dg.startFlow('https://www.paypal.com/webapps/adaptivepayment/flow/pay?expType=light&payKey=' +data.paykey);

I don't have any problems getting the payKey & the entire payflow works on desktops and in mobile browsers other than Safari (it works on desktop Safari). It also does not work when our site is run as an iOS web app, which I assume is just a shell for Safari anyway.

Ben Y
  • 1,711
  • 1
  • 25
  • 37

3 Answers3

2

I can explain why you are seeing this error. Safari on iOS only allows a window to be opened as a result of a user click/touch event.

The DGFlow._render() function executes:

window.open('', "PPDG");

which returns null if triggered by anything other than a user click/touch event.

I am guessing you are issuing an XMLHttpRequest to generate a PayRequest/PayKey on the server and then in the onsuccess callback you are calling DGFlow.startFlow().

The solution is two split the process into two steps:

  1. When the user is ready to checkout, issue the call to the server to generate the pay key.
  2. Then, present the user with a button to Checkout with PayPal and when that is clicked, call DGFlow.startFlow()
bpossolo
  • 849
  • 5
  • 6
1

Found a couple of ways to get around this...location.replace with the PayPal URL or using your own lightbox. I used easybox.

// Replace
dg.startFlow('https://www.paypal.com/webapps/adaptivepayment/flow/pay?expType=light&payKey=' +data.paykey);

// with
var RUNNING_AS_WEB_APP = (window.navigator.standalone == true ? true : false);
if (RUNNING_AS_WEB_APP === false) {
    dg.startFlow('https://www.paypal.com/webapps/adaptivepayment/flow/pay?expType=light&payKey=' +data.paykey);
} else {
    location.replace('https://www.paypal.com/webapps/adaptivepayment/flow/pay?expType=light&payKey=' +data.paykey);
    // Or, lightbox option: 
    // $.easybox([{url: 'https://www.paypal.com/webapps/adaptivepayment/flow/pay?expType=light&payKey=' +data.paykey, width: 320, height: 480}]);
} 
Ben Y
  • 1,711
  • 1
  • 25
  • 37
  • 1
    I did not have any luck with a lightbox (I tried magnific). I ended up having to integrate the mini flow for iOS, which does work albeit with a new browser window. – Alex Jul 30 '14 at 02:17
  • @Alex I am also facing a similar issue. My app is an IOS app. What I do is create paykey and load UIWebView using mini browser URL. But I cannot detect when user completes a payment or cancels . Return and cancel urls are not called? How did you implement mini flow in IOS. Please help me. – arundevma Dec 10 '14 at 09:30
  • I am actually in the process of tearing this integration out of my system. From what I've gotten from PayPal support, this flow is unsupported inside a WebView and PayPal is not going to fix it because they've effectively stopped development on the Classic APIs. There is a workaround to remove the JavaScript and just do a straight redirect to PayPal, passing the payKey as a query parameter, but the user experience is awful (not mobile optimized in the least). – Alex Dec 10 '14 at 16:02
1

Try using the mini browser experience where expType=mini. Seems to work better than the lightbox on mobile devices.

Adaptive Payments without modal box or popups?

Community
  • 1
  • 1
James
  • 1,440
  • 14
  • 12
  • 1
    We tried mini too, it was still throwing the same error in Safari on iOS/iOS web app though =/ – Ben Y Jul 18 '13 at 21:11