JavaScript popup issue: window.opener becomes undefined after domain redirect

I’m stuck with a weird problem on my site. I’m using window.open() to show a payment popup. The popup goes to another website and comes back to a results page. On this page, I try to tell the main window the payment’s done by changing window.opener.

It works fine for some people, but others get an error saying window.opener is undefined. I can’t figure out why.

Here’s a basic example of what I’m doing:

// Main page
function showPaymentPopup() {
  let paymentWindow = window.open('payment-start.html', 'paymentPopup');
}

// Results page
function updateMainWindow() {
  // This line causes issues for some users
  window.opener.document.querySelector('#status').textContent = 'Payment successful';
}

I’ve tried this on my computer and it works, but I can’t recreate the error some users are seeing. Any ideas what could be causing this? Could it be something to do with browser settings?

hey bob, i’ve seen this before. it’s probably cuz of browser security stuff. have u tried using sessionStorage instead? it’s like:

main page:

window.addEventListener('storage', e => {
  if (e.key === 'paymentDone' && e.newValue) {
    document.querySelector('#status').textContent = 'Payment successful';
    sessionStorage.removeItem('paymentDone');
  }
});

results page:

sessionStorage.setItem('paymentDone', 'true');

this should work across domains n stuff. hope it helps!

This issue could be related to cross-origin restrictions. When the payment popup navigates to a different domain and then returns, some browsers may treat it as a new window, causing window.opener to become undefined.

To mitigate this, you could try using postMessage() instead. It’s more reliable for cross-origin communication. Here’s a basic example:

// Main page
window.addEventListener('message', (event) => {
  if (event.data === 'payment_successful') {
    document.querySelector('#status').textContent = 'Payment successful';
  }
});

// Results page
window.opener.postMessage('payment_successful', '*');

This approach is more robust and should work across different browsers and domains. Remember to replace ‘*’ with your actual origin for better security.

I’ve dealt with similar issues before, and it’s often related to browser security policies. Some browsers are stricter about maintaining the opener relationship when the popup navigates across domains.

One workaround I’ve found effective is to use localStorage for communication instead. Here’s a rough idea:

On the main page:

window.addEventListener('storage', function(e) {
  if (e.key === 'paymentStatus' && e.newValue === 'success') {
    document.querySelector('#status').textContent = 'Payment successful';
    localStorage.removeItem('paymentStatus');
  }
});

On the results page:

localStorage.setItem('paymentStatus', 'success');

This method bypasses the need for window.opener entirely. It’s worked well for me across different browsers and domains. Just remember to clean up the localStorage item after use to avoid potential conflicts.