I have an ipn listener that update my transactions (from pending to completed) and my contracts payments from finished to paid. This is perfect! I has also a return page... From PayPal to my site... This page show "thanks" and "button to allow download their last paid online contract" (paid with PayPal). My problem is that.... Ipn listener sometimes comes 3 seconds after my return page is shown to the the user....
In my return page in this case. Has the transaction and contract unpaid... And when ipn listener catch the results... Then this transaction and contract change to paid status. But ipn listener is executed at back-end. In my server. And my return page was shown 3 o 2 seconds before to my user. What can I do?
Should I add a timer (a delay) in my return page waiting until ipn updates my transaction and contract status? And then, show to the user a button "you can download your last paid contract!". Or better I should forget this step. And in my return page always without wait show to user "thanks for your payment". "you can download your last paid contract!"
I also have my return page wait for the IPN notification to come into my server, and you can definitely make that work if you do it right.
Initially, the return page polls on a field in my back-end database that the IPN handler updates. Then, when the return page sees that field update, the customer gets his 'here are the items you paid for' button.
I also have a one minute timeout on this process. When that expires (although I can't remember the last time that actually happened), I display a catch-all error message ('There was a problem processing your transaction') and invite the customer to contact me for help.
I also tell them that their license key (which is what they are buying, in my case) might be on its way by email, since, usually, it is. IPN notifications can sometimes take a little while to arrive for some reason but my IPN handler sends out a confirmation email as a backup so they will get that in due course. That usually sorts things out, I rarely need to get directly involved.
If PayPal puts the transaction on hold, it doesn't seem to ever forward the customer to the return page (I have certainly never seen that happen). Instead, I assume it lets the customer know that he must wait for the funds to clear and leaves it at that.
An IPN notification does get sent however when the transaction eventually clears, and then you can have your handler send that email.
Lest this sounds like a lot of work, you should be sending an email from your IPN handler anyway since customers like to have a record of their purchases. Once you put that mechanism in place, the rest is easy.
Note: Watch out for IPN transactions flagged as 'echeque'. The funds haven't cleared yet, you will get another notification when they do. Then you can send them their contract by email. If memory serves,this does forward them to your return page so you have to handle that by letting them know that they must wait. In practise, this doesn't seem to happen very often.
Suggestion: have your scripts send you an email when something unexpected happens. This has saved my bacon more than once when PayPal have changed the names of the fields passed to the IPN handler for no obvious reason.
Summary: This is a practical, experience-based write-up of the way my website works, and it works well. I hope readers of this post find it helpful, despite the mysterious downvotes.