For my membership site, I've got the IPN handler done. My question is one of site "flow".
Here's how it goes:
User -> Landing -> SignUp -> Verify -> PayPal -> ThankYou
So here's the problem (which could just all be in my head). Let's say you've signed up and verified your account. Then you click the "Subscribe!" link and are sent to paypal - where you complete payment and get sent to the "Thank You" page.
What if the IPN doesn't arrive back to my site quickly? The subscribe link will still be there, and users may click it again thinking they've not subscribed (even though they have, it's just taking time).
If I combat this by updating their profile to say... "Activating..." when they click the "Subscribe" link, and they don't complete the PayPal process... it could be forever saying "Activating...".
Just curious, as this is my first time integrating PayPal:
How do you handle the state between the time the user clicks the subscribe link and it takes for the IPN process to complete?
Have you ever had any issues with IPN's not arriving quickly?
Your question suggests that the connection to the remote server is asynchronous (ajax)?
It's probably easier to write it in a synchronous manner, so the IPN is guaranteed to return. If it doesn't, it means that:
a) The user closed the browser after being redirected to the remote server;
b) The remote server did not respond.
Good payment gateways will redirect the user back to your site if they click maybe the "Cancel" button, but a return is never guaranteed, so you need to handle it correctly.
I would have a separate table to log the transactions for a given user; that is:
one user, many transactions
Some payment gateways allow you to define as callback to your server when a transaction is completed. That is, the connection is initiated by the gateway -- it does not run the browser, as the user can close the tab/window -- where it does a post to your callback URL, and then you update the status of the transaction.
I'm not sure if PayPal does allow for such things, but so far, I've never had issues with PayPal because I've always written it in a synchronous manner.
Of course, if asynchronous is required, then your ajax function has to have a timeout/error handler -- I recommend jQuery, of course.
I've never had any issue with IPN not arriving quickly, but then again I have never really had a huge website with a lot of users. I also didn't make any significant changes to a user account until I received the IPN.
I made a paid registration for one of my websites using the paypal API. A user would fill out their username, password, etc. and I would pass the variables to the paypal API. The data wouldn't be acted on until I did receive the IPN.
You could always associate a timestamp with a pending payment if you feel the status "Activating..." is important within a user profile. A pending payment could timeout after 10 minutes.
Related
I'm creating an android application that uses PayPal as a payment method. I have already implemented IPN in PHP but I have some questions about the PDT. From what I understood, the PDT is a notification that occurs when the user pays and returns to the merchant website. My question is, what if the user before being redirected closes the PayPal page? The user never visits the "return page" and I don't receive any immediate notification about the purchase.
I'm selling digital products, so I can't wait for the IPN to allow the user to download the product, as it could take several minutes or even hours to arrive.
What do you think I can do? Do you have any suggestions? Thanks.
PDT and IPN are ~20 years old. PDT in particular is only suitable for informational purposes, since as you mention the user may never return to the redirect page--for any number of reasons. IPN can be relied on but is an asynchronous notification and may delay as you also mention.
The best solution is to use neither of those very old things, and instead capture transactions with a v2/checkout/orders API call. This gives an immediate, synchronous notification when a transaction completes.
Create two routes, one for Create Order and one for Capture Order (first using a function that obtains an access token). These routes should return/output only JSON data (no HTML or text).
Pair those two routes with the following approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server
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!"
You should not regard or show the transaction as complete, or allow any further business action to occur, until you have actually received the money, and only the IPN tells you that.
You need to adjust what you show on your return page accordingly.
All you should really do here is thank the customer for his business and tell him that the download or the delivery or whatever it is will become available immediately PayPal has notified you of the actual transfer.
And note that it can take a lot longer than three seconds. If they chose to fund the payment from their bank account, it can take 3-5 days: and there is always the possibility of that process failing altogether due to insufficient funds.
So don't be too optimistic in designing your return page. The deal isn't done until the money is in the bank.
This page show "thanks"
Good.
and "button to allow download their last paid online contract"
Bad. That should be somewhere in 'My Account'.
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.
I maintain a PayPal integration which uses PayPal HTML Buttons and confirms payment using IPNs. This system has been in production for more than 5 years.
The system sets the cancel_return variable to a unique URL for each order. If this URL gets hit (i.e. if the customer cancels at paypal and gets sent to this URL), it first checks the session, to ensure the user hitting the URL is the same one who initiated the order, then cancels the order.
I noticed that several recent transactions have been cancelled even though the transactions at PayPal were successful.
The logs showed that customers are hitting the cancel_return URL - in some cases just after the IPN has been received, and in one case just before the IPN was received.
I found at least one way to reproduce this behaviour:
initiate the order on my site
complete the payment at paypal
return to merchant
use the back button to return to paypal
I then get a message that says "Your payment was completed. To continue shopping, please return to the merchant." One button is provided: "Return to merchant name".
Clicking this button takes the user to the cancel_return URL!!
PayPal's documentation for cancel_return says
A URL to which PayPal redirects the buyers' browsers if they cancel checkout before completing their payments. For example, specify a URL on your website that displays a "Payment Canceled" page.
Default — PayPal redirects the browser to a PayPal webpage.
My question is whether this is an intentional change by PayPal -- if so I expect it will break many sites -- or if this is a bug. I couldn't find a bug report at PayPal.
Yes, they changed the meaning of cancel_url, though they are not acknowledging this as a bug or an intentional change. This is definitely a bug in my opinion (as documented in the question above).
In addition to the steps above (reproducing using the back button), I found a customer click-trail in my server logs where the customer was sent to the cancel_url, without using the back button, soon after PayPal sent the IPN confirming their successful payment. I confirmed that the customer did not want to cancel and did nothing to intentionally cancel their order. Unfortunately I could not find a way to reproduce.
I registered at www.paypal-techsupport.com and submitted a ticket about this issue. After several exchanges, the end result I got was:
This is the information that I received from our engineer.
Its an expected behavior when the customer click on the back button, it will bring back to the cancel_url.
We would suggest you to do some modification so that the order is not being cancel when the customer go to the cancel_url.
With poor customer support like this, I will not be recommending PayPal to any of my clients in the future.
You can post it here and the PayPal folks can pick it up.....
https://www.paypal-community.com/t5/Merchant-Technical-Support/ct-p/mts
I have a SAAS web application that works through a subscription fee. If the subscription is valid everything works fine, otherwise the app goes in read-only mode until the customer renew the subscription. I've developed the payment flow with the PayPal API.
The problem is that PayPal Documentation says this:
"Although PayPal usually processes IPN messages immediately, IPN is not synchronized with actions on your website. Internet connectivity is not always 100% reliable and IPN messages can be lost or delayed. The IPN service automatically resends messages until the listener acknowledges them. The service resends messages for up to 4 days.
Because IPN is not a real-time service, your checkout flow should not wait for the IPN message before it is allowed to complete. If the checkout flow is dependent on receiving an IPN message, processing can be delayed by system load or other reasons. You should configure your checkout flow to handle a possible delay."
Unfortunately this is exactly my case: when customers renew the subscription I need to immediately activate the app so I placed all the logic right in the "notify callback" where I have to create the order, send a confirmation email, update some session variables... but I if there's a delay from PayPal IPN this is a problem!
In these days I did some test in Sandbox mode and in several cases I got an answer from IPN even 4 hours after the successful payment! This is unacceptable for my app!
Finally the question: what's the best solution for my case? It makes sense to move the application activation from "notify callback" to "success callback"? There may be problems?
Thanks
Don't use IPN for this; it's a poor fit & not designed to be inserted into synchronous user experience flows. It works fine as a way to initiate offline fulfillment, but can delay your customers if they are actively waiting for access.
You don't specify which PayPal product you are using, but each product should provide a way to immediately give you feedback that the payment has been completed. For example with Express Checkout or any API-based payment you can take action (activate/re-activate a subscription) when you receive the successful API response (the DoEC API in the case of Express Checkout).
With web-only/non-API products you can take action when the customer redirects to your return_url, using PDT to securely get information about the transaction if you need that (it can include an IPN-style key that you post back to PayPal to verify, exactly as you do with an IPN).
If you are concerned about the edge cases of someone closing their browser before it can redirect to you, or some other sort of dropped connection or programming error, you can also check & activate/fulfill upon receipt of an IPN to catch any fallout. So all customers that complete a normal payment flow are activated immediately; if they do something wonky (or your code breaks, or whatever) then the activation still happens, albeit potentially delayed by a few seconds or minutes.
I'm currently using the Paypal's PDN method of data transfer to keep all my transactions made through the Paypal shopping cart in a MySQL database of my own.
However, when Paypal redirects a customer to my handlePayment.php page, it takes about 10 seconds to do so. If the customer closed the window, the payment would still be made but the order wouldn't get posted to my database.
Is there a way where I can either:
a) speed up the redirect so it's instantaneous?
or
b) add a description under the store title in the paypal shopping cart, that says "please wait to be redirected after you complete payment?
Do both. Whichever arrives first wins, and the other gets ignored. The payloads are similar, so there's not much code to add.
If you rely solely on IPN, it might not have arrived by the time the visitor gets back to your site (especially if they click to it rather than waiting for the redirect). But if you rely solely on PDN, you get the problem you describe. So do both.