If I understand your question, the race condition you describe between WordPress knowing the transaction was “complete” and the user returning to your site is the problem.
Regarding a potential solution, what about changing the way you’re approaching this such that this race condition is accepted as a real possibility rather than something that you can avoid? You do mention one of the possible Paypal status is “pending”…
Its been years since I’ve worked with Paypal, but I recall the IPN feed can sometimes lag for quite a while.
Suppose you use ajax: you could show the login page with a conditional box, or you could use an interstitial ‘transaction processing’ page that redirects to the login. Your process could thank your customer, show a throbber animation, and explain that you’re processing the transaction / waiting for payment confirmation from Paypal.
Your page can keep polling WordPress and when the user’s meta status
is “complete” you can update the user and show them the login form, and if it “failed” you can handle accordingly.
I’m not sure if you’re setting the Paypal “pending” status in the user meta, but regardless an easy way to trigger this case is by checking for the presence of the user_id
and form_id
in the request from Paypal.
In cases where IPN is updated quick and/or the user pauses before returning to your site, the ‘payment success’ case could already work seamlessly as you desire: no need to show any throbbers or anything like that.
I think ajax is the best approach. A continuous poll every couple seconds might sound like you’re generating a lot of requests, but I doubt you will have scores of users waiting to find out their transaction outcome at any one time. If you do, congratulations, you’re making lots of money 🙂
WordPress also has a Heartbeat API but the fastest this can poll is 15 seconds. Web Sockets is another approach but is probably overkill and introduces its own complexities.
Here is a tutorial that covers an example implementation: https://premium.wpmudev.org/blog/using-ajax-with-wordpress/
For a docs reference: https://developer.wordpress.org/plugins/javascript/ajax/
To have javascript check continuously every few seconds, see setInterval()
and setTimeout()
, references: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval and there’s always: https://www.w3schools.com/js/js_timing.asp
Good luck!