I encountered an error when user click the Paypal button, popup window opened and automatically closed.
Since I couldn't find any question on the internet regarding this problem, I thought I share my solution here.

In the console, it seems the error comes from /commerce_paypal/js/paypal-checkout.js
The error was coming from undefined variable in createOrder function
messages.add(data.responseJSON.message, options);
The data variable is undefined.
And also if you uncomment above code, paypal will throw order id is missing since data is undefined.

Solution

/commerce_paypal/src/Events/CheckoutOrderRequestEvent.php

Remove the use Drupal\commerce\EventBase; and change class CheckoutOrderRequestEvent extends EventBase { to class CheckoutOrderRequestEvent {

and now the button is working again. Not sure why though, maybe commerce module doesn't have the EventBase class anymore?
Anyway I hope this will help someone.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

slashsharp created an issue. See original summary.

jsacksick’s picture

Wow, this doesn't really make sense, sorry for reporting, haven't tried myself to reproduce yet.

Care to share the Drupal version you're running? (And the Commerce core version while you're at it?)

slashsharp’s picture

No worries, maybe something is wrong somewhere with my setup.
Drupal 9.5.3, Commerce 8.x-2.33+5-dev

a.milkovsky’s picture

We have experienced the same issue. In addition we can see a js error "Paypal Response "Expected an Order ID to be passed".

As @slashsharp noted, the error happens in the messages.add(data.responseJSON.message, options); line, where data is a string with order id and not an object.

This promise was added in #3303443: Enhance Exception Handling on Ajax calls. I am not sure why data does not contain responseJSON in this case.

The next patch removed this promise and fixes the payment process.

Roman2014’s picture

Issue tags: +commerce_paypal
StatusFileSize
new644 bytes
jsacksick’s picture

I'm a bit confused by this now... So there's both a JS error and the error with the event class?
Remove the use Drupal\commerce\EventBase; and change class CheckoutOrderRequestEvent extends EventBase { to class CheckoutOrderRequestEvent

tomtech’s picture

Assigned: Unassigned » tomtech
Status: Needs review » Needs work

The promise referenced is the error handler of the Ajax callback to retrieve the order id.

It is not causing this issue, but attempting to handle it. It displays the error message, if one was returned and reloads the page if the response code is 403 (access denied) so that the user can log in again.

A patch to remove the error handler is not the solution here.

I've re-tested, and the handler generally works as expected, though we can add more safety around it.

If the popup window opens and closes, the root cause is that the order id was not available.

The most common reason for this issue is if the session has gone away or the user has logged out.

The most common case is a user gets to the checkout step with the PayPal buttons, does something else (gets a cup of coffee?), then the session times out, then they click the button, and the Ajax callback returns an error.

It takes some patience to wait for the timeout to occur. :)

A couple ways to reproduce this more quickly is:
with an authenticated user:

  1. go to the page with the PayPal buttons
  2. open another tab on the site
  3. log out from the site on the other tab
  4. on the checkout tab, click the PayPal button

You should be presented with the login page, and after you sign in, you should be back on the checkout step again.

with an anonymous user:

  1. go to the page with the PayPal buttons
  2. go to the database and truncate the session table (Only in a dev environment, of course!)
  3. on the checkout tab, click the PayPal button

Since this was an anonymous user, you will most likely end up on an empty cart page.

We are aware of one specific case that would cause data to be a string, but that only occurs if you are using a version of jQuery before 1.8. (Promises on then() were not implemented until jQuery 1.8)

I'll follow up with a patch that adds more safety to the js, but you really should be getting an object for data in the error handling. If you can identify a reproducible case, we can certainly look into it and troubleshoot!

tomtech’s picture

Status: Needs work » Needs review
StatusFileSize
new0 bytes

Attached patch adds more safety around the data on the error handler, and tries to gracefully handle an unexpected payload.

a.milkovsky’s picture

I'm a bit confused by this now... So there's both a JS error and the error with the event class?

@jsacksick #6, the event class change did not help me. The error came from js. I am still not happy with the solution, as it works unstable. That's why we decided to deactivate this payment type for now. I plan to get back to it again and debug a bit more.

@TomTech your patch #8 is empty.

tomtech’s picture

Well...let's. try that again with a non-empty patch. :)

anybody’s picture

@tomtech you're still assigned, plans to finish this? Perhaps proceed with a MR?
Or are you awaiting review by @jsacksick for #10 first?

BTW I think we had a similar issue in the past and I think the reason was PayPal-side. Either you haven't opted into PayPal Checkout or maybe PayPal dynamically detected that the Checkout functionality doesn't fit for this client?

anybody’s picture

Assigned: tomtech » Unassigned

No reply from @tomtech :(

rakesh.regar made their first commit to this issue’s fork.

grevil’s picture

Status: Needs review » Reviewed & tested by the community

@rakesh.regar provided @tomtech's patch as an MR.

Changes LGTM and makes the JS a bit more safe. Unsure if it will fix the original issue, as there aren't clear steps to reproduce (other the ones from @tomtech).

The only thing is, that in the case "data.status" is "403", the added message will quickly disappear through location.reload(). Other than that, it looks fine!

Let's hear feedback from others.

damienmckenna made their first commit to this issue’s fork.

damienmckenna’s picture

Issue tags: -

I updated the MR to fix two minor issues.

tbkot made their first commit to this issue’s fork.

jsacksick’s picture

Status: Reviewed & tested by the community » Fixed

I merged, and also pushed the same change to 2.x. The merge request takes time too merge for whatever reason...

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • jsacksick committed a85a5e9f on 2.x
    fix: #3342644 Paypal Smart Button automatically closed while loading
    
    By...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.