How to Test and Troubleshoot PayPal IPN
One of the questions I most often see asked on forums like StackOverflow and Experts Exchange is regarding PayPal Instant Payment Notification (IPN) and how to test it thoroughly. It can be a little bit tricky because the result of the script you are running does not happen on screen. Therefore, troubleshooting and debugging can be difficult.
I’ve been following this tried and true method for developing IPN solutions for years now, and it’s allowed me to launch IPN for hundreds of clients confidently and successfully.
Step 1 - Local Testing
With an IPN script ready to go (or so I think), the first thing I like to do is run some local tests. This is done by building a very simple HTML form with hidden fields that match what you might expect to get from a particular IPN.
Use Google to find a sample of PayPal IPN data for a particular transaction type that you’d like to test. Then, build your HTML form to produce the same thing. For example, here is a basic form that would simulate a “web_accept” IPN from PayPal.
<form action="http://www.domain.com/papal/ipn-listener.php" method="POST"> <input name="mc_gross" type="hidden" value="500.00" /> <input name="custom" type="hidden" value="some custom data" /> <input name="address_status" type="hidden" value="confirmed" /> <input name="item_number1" type="hidden" value="6" /> <input name="item_number2" type="hidden" value="4" /> <input name="payer_id" type="hidden" value="FW5W7ZUC3T4KL" /> <input name="tax" type="hidden" value="0.00" /> <input name="address_street" type="hidden" value="1234 Rock Road" /> <input name="payment_date" type="hidden" value="14:55 15 Jan 07 2005 PST" /> <input name="payment_status" type="hidden" value="Completed" /> <input name="address_zip" type="hidden" value="12345" /> <input name="mc_shipping" type="hidden" value="0.00" /> <input name="mc_handling" type="hidden" value="0.00" /> <input name="first_name" type="hidden" value="Jason" /> <input name="last_name" type="hidden" value="Anderson" /> <input name="mc_fee" type="hidden" value="0.02" /> <input name="address_name" type="hidden" value="Jason Anderson" /> <input name="notify_version" type="hidden" value="1.6" /> <input name="payer_status" type="hidden" value="verified" /> <input name="business" type="hidden" value="paypal@emailaddress.com" /> <input name="address_country" type="hidden" value="United States" /> <input name="num_cart_items" type="hidden" value="2" /> <input name="mc_handling1" type="hidden" value="0.00" /> <input name="mc_handling2" type="hidden" value="0.00" /> <input name="address_city" type="hidden" value="Los Angeles" /> <input name="verify_sign" type="hidden" value="AlUbUcinRR5pIo2KwP4xjo9OxxHMAi6.s6AES.4Z6C65yv1Ob2eNqrHm" /> <input name="mc_shipping1" type="hidden" value="0.00" /> <input name="mc_shipping2" type="hidden" value="0.00" /> <input name="tax1" type="hidden" value="0.00" /> <input name="tax2" type="hidden" value="0.00" /> <input name="txn_id" type="hidden" value="TESTER" /> <input name="payment_type" type="hidden" value="instant" /> <input name="last_name=Borduin" type="hidden" /> <input name="payer_email" type="hidden" value="test@domain.com" /> <input name="item_name1" type="hidden" value="Rubber+clog" /> <input name="address_state" type="hidden" value="CA" /> <input name="payment_fee" type="hidden" value="0.02" /> <input name="item_name2" type="hidden" value="Roman sandal" /> <input name="invoice" type="hidden" value="123456" /> <input name="quantity" type="hidden" value="1" /> <input name="quantity1" type="hidden" value="1" /> <input name="receiver_id" type="hidden" value="5HRS8SCK9NSJ2" /> <input name="quantity2" type="hidden" value="1" /> <input name="txn_type" type="hidden" value="web_accept" /> <input name="mc_gross_1" type="hidden" value="0.01" /> <input name="mc_currency" type="hidden" value="USD" /> <input name="mc_gross_2" type="hidden" value="0.01" /> <input name="payment_gross" type="hidden" value="0.02" /> <input name="subscr_id" type="hidden" value="PP-1234" /> <input name="test" type="submit" value="test" /> </form>
You might use completely bogus data, or you could use data that resides in your database if you’re testing things like updating your database or sending out email notifications based on specific invoice numbers.
Notice that the action of the form is set to the URL you would configure for PayPal to hit for IPN. This way, you can load the form in a browser and submit it directly, which will display the result on screen including any errors that may occur. This can help to find any problems with the script and eliminate them early in the process.
Keep in mind that when testing this way the data is not coming from PayPal’s server. As such, the IPN verification process will come back as invalid. You may need to adjust for this in your IPN solution depending on the logic you have in place for handling verified or invalid IPN’s.
I would recommend setting up local form simulators for various types of transaction types and also test with different data that has special characters or other unique aspects to ensure you’ve covered all your bases. Once you’re able to hit your IPN script from a local simulator without failure, you’re ready for step 2.
Step 2 - PayPal IPN Simulator
PayPal provides their IPN simulator which is essentially the same thing we put together in step 1 here. The only difference is that this time the data is coming from PayPal’s sandbox server. As such, it will validate correctly with PayPal and the IPN would come back as verified if you have your IPN script configured correctly, so that’s a good thing to test for at this point. Just remember that your IPN script needs to validate against PayPal’s sandbox at this point, not their live server, so update your script accordingly.
On that note, PayPal’s sandbox server includes a parameter called “test_ipn” that will be sent with a value of 1 when the IPN comes from PayPal’s sandbox. You can check for this in your IPN script and set the PayPal URL’s for verification based on that so you don’t have to remember to switch it back and forth.
When using the simulator, you should be able to post the test and see everything that your IPN script is supposed to do happen just like an actual transaction had occurred. Once you’re happy with these results, you’re ready to move on to step 3.
Step 3 - Actual Sandbox Transaction Testing
This step could be considered optional, for the sake of thorough testing, I’ll say it’s not.
Create an account at http://developer.paypal.com if you haven’t already done so, and if that’s the case, then you’ll need to go ahead and create at least 1 sandbox seller account and 1 sandbox buyer account. These accounts act just like real PayPal accounts except they work with http://sandbox.paypal.com instead of http://www.paypal.com, and of course all the money moved around on the sandbox is fake.
Once you have these accounts created, you can setup the seller account using a Standard Button or API calls just like you would a live seller account. This allows you to fully complete a transaction from beginning to end so you can simulate the entire process as it will happen live.
You’ll use your buyer sandbox account to login and pay for the transaction, and when this happens, the PayPal sandbox will trigger the IPN the same way the live account would. Of course, you’ll need to make sure you’ve configured IPN in your sandbox seller account just like you would a live account, too, so that it functions as expected.
This is the essential part of testing in my opinion. Successful tests here will provide absolute confidence that my IPN solution is ready to rock!
Step 4 - Deployment
At this point, all you need to do is make sure your IPN script is ready for live processing and that you have IPN enabled in your live PayPal account. Then, release the hounds!
Tips for Troubleshooting PayPal IPN Failures
- Check your IPN History in your PayPal account. This will allow you to confirm whether or not PayPal is actually sending IPN’s to your listener, and if so, what response code it’s getting back from your server. A 200 OK response means it worked as expected. Anything else means it failed, and PayPal’s server would continue to re-try until it gets a 200 OK.
- Check your web server logs. Apache, IIS, etc. have their own server logs that provide the same information you would see on screen if you ran into the problem in a client/browser. If PayPal IPN history is showing that it’s sending data but a failure is occurring, your web server logs can help you diagnose the problem.
PayPal IPN for WordPress
Looking for Live Help?
Schedule a live meeting with Drew Angell, PayPal Certified Developer, and get all of your questions or concerns answered.
Featured PayPal Products and Services
-
PayPal Support
$100.00 -
PayPal for WooCommerce
FREE! -
WooCommerce Multiple PayPal Accounts Plugin
FREE! -
PayPal Shipment Tracking for WooCommerce
$49.99 -
Offers for WooCommerce
$59.99 -
WordPress PayPal Invoice Plugin
$20.00 -
PayPal Webhooks for WordPress
$79.99 -
Sale!
PayPal IPN for WordPress
Original price was: $59.99.$49.99Current price is: $49.99.
Hello, I used to receive IPN emails without an issue. Since the security upgrade, I receive the ipn email, but there is no data populated in that email. I was working with a programmer on another project and he can’t figure it out. Can you help?
Are you using one of our IPN tools/plugins? Did you follow the steps outlined in this guide to troubleshoot the issue?
Hi,
I followed all setup and configurations step for this plugin. but I am not getting any IPN records under Dashboard > Paypal IPN.
I am using paypal button in Contact form. Testing it with sandbox account. I also copied notification url from Sattings > Paypal IPN to Sandbox business account IPN settings.
I am not using any notify parameter in paypal button.
I am totally blank that what should I do now.Please help me.
It’s best to submit support requests through our help desk. Please submit a ticket here and we can get you helped out. I can tell you quickly, though, that the first thing to check would be the IPN History in PayPal to see if it shows that IPNs are indeed being sent (or not) and it will also show the HTTP response code. 200 would mean successful, but something like 404 or 500 would mean there’s a problem with the URL.
Hello, I’m new to ipn & php world of things. I downloaded your PayPal ipn for WordPress great app!! Now the question I have is how do I manually change the ipn information that PayPal sends over once I receive them via the plugin. Could you please explain step by step?
I’m not sure I fully understand what you’re trying to do. Can you please clarify?
Please how do I configure the plugin to use https://ipnpb.sandbox.paypal.com/cgi-bin/webscr instead of https://ipnpb.paypal.com/cgi-bin/websc
I’m doing sandbox testing.
If the plugin receives an IPN from the PayPal sandbox it will automatically post back to the sandbox. It does this based on the “test_ipn” parameter that gets included with sandbox IPNs.
The return to merchant button will trigger a return url we post to paypal IPN. But for the past few days paypal redirects to return url without any information (such as transaction id).
Hi Abishek,
It sounds like you’re referring to PDT, which is what sends data to your return URL. IPN is something different.
Hi, found your page from your comments on SO. I am not using your tools, but wanted to comment on your directions above.
1. Currently (since at least Aug ’17), several people, including me, get the error “IPN was not sent, and the handshake was not verified. Review your information.”, and there’s no indication what’s wrong with that. You commented on one of those SO questions to come here, but you did not seem to even verify whether this issue isn’t a general bug at Paypal right now. So, please, would you make the effort and try the IPN yourself and verify that it actually works, like now? Because without that, you comment suggests it should work when in fact it doesn’t, for anyone.
2. Contacting Paypal about this issue doesn’t seem possible any more as their Merchant Support site does not take new support requests any more, instead redirecting one to the general user’s help page which has no topics on IPN and related services as far as I can see. Not your fault, just saying: There’s currently no help with this issue to find anywhere.
3. Back to #1 – the very strange thing is that when I receive payments on my regular account, I _do_ get a call to my IPN script, and the IPN history shows that it successfully sent the payment info and received status 200. So, from that perspective, IPN works – yet, when I try the IPN sim with the same URL, it gives me that error message. This strongly suggests that the error is on Paypal’s end.
4. It would be nice if someone, maybe you, could clarify _why_ we even need to perform the verification step. My script, for instance, simply takes the IPN msg for granted (it does perform a simple reverse domain check to make sure it’s coming from paypal.com, though – I know that’s not failsafe but for my tests sufficient). Yep, even without calling back to Paypal from my IPN handler, Paypal seems to accept my status 200 response just fine for regular payment events. So, why should we do this extra verification step? Will Paypal eventually stop sending me IPNs, or is this just a protection for my own good (to make sure no one else tries to submit fake payments to me)? Since I’m dealing with low-volume, low-price, donations, I could care less if someone tries to submit take payments.
Hi Thomas,
1. I would need to see the SO thread you are referring to. The error you’re talking about sounds like it came from the IPN Simulator..?? I don’t know how I answered, so I cannot respond to what sort of effort I may or may not have put into the comment, but I typically provide the best info I can.
2. Go here, and click “Contact Support” at the bottom of the page. They also have phone support you can get to through your PayPal account.
3. Again, not sure if you’re using the Simulator, but it sounds like you must be. That very well could be an issue with PayPal’s Simulator, although it usually doesn’t happen and doesn’t happen for long if it does. Some of the other steps in this guide would help you figure that out and continue testing if the Simulator is acting up.
4. The verification step is optional, but highly recommended. It’s simply used to verify that the data actually did originate from PayPal’s server. Without that, anybody that happens to know your IPN URL could just send bogus transaction data to it in hopes that you’ll mistakenly ship them a product that isn’t paid for. So it’s just a security thing. You want to know that PayPal, not somebody else, sent that data to you. That’s what the verification does.
Actually, I’ve now solved why one may be getting the “IPN was not sent, and the handshake was not verified. Review your information.” when using the IPN Simulator. I have moved the handler to another server, which involved a URL with a shorter path, and then it worked. So, the IPN simulator is checking something about the path, and if it doesn’t like it, it gives that unhelpful error msg. Funny enough, even some random http plain text site such as https://www.macintouch.com works as the handler URL with the Simulator. So it’s clear it’s not expecting anything back other than a 200 status code.
I would have to see what URL you were trying to work with to see if I could provide a tip why that might have been happening. Yes, you can enter any URL you want into that simulator and it simply tells you whether or not it received a successful response code.
Hello, I’ve been working on the IPN and I am confused on some things.
1. After you get the “VERIFIED” string, the documents say that you have to check for other things to like if payment is complete and so forth. I’m confused as to how do I check that. I know the IPN message has all that data but I don’t know how to access the message. What variable has the message?
2. I did step 1 of your troubleshooting guide where I checked my listener locally and it ran fine as far as I know and got the “INVALID” string as you said. But following step 2 where I try to use the IPN SIMULATOR, it says: “IPN was not sent, and the handshake was not verified. Review your information.” I checked the whole history tab to see if any IPN messages were sent but the history says that no messages has been sent. Im not sure what i’m doing wrong. Any ideas?
1. The data would come to your URL as
$_POST['var']
data, so however you’re handling that sort of data in your project is how you would handle the IPN data. So if you wanted the payment status of the IPN, for example, you would use$_POST['payment_status']
. You can see all the different variables available for different IPN types here.2. IPN simulator transactions will not show up in the sandbox account IPN History. Those are not related. If you’re getting a handshake failure from IPN simulator that could mean your call back to PayPal is not correct in your IPN script. It could also just be a general PHP error. Check your web server logs right after you run that simulator test and you should see the result including any PHP error details in your server logs.
Hey Andrew, Im doing my IPN Listener in C# with ASP.NET. Not using PHP at all. Any ideas in this case? If I understood you correctly for my first doubt, the IPN is sent as a POST message. So my function should have a string parameter to take the IPN Message?
Yes, the data sent from PayPal is just like a form POST, so however you would process a form POST in .NET is the same thing you would do with PayPal IPN data.
Another question. For step 3 of testing where you do actual Sandbox testing. You say that we have to configure the IPN on the seller account like one would do in the live account. I can’t find where I can configure the sandbox account. I know how to do it live, but I can’t see how to do it for the seller account
@Josue Cortes You need to login to the Sandbox account at http://www.sandbox.paypal.com in order to set up the IPN for your sandbox account. I’ve been looking for this at the same time as you, and I just found it.
Hi,
I’m using xampp local server and i used ngrok to tunnel my server because the paypal ipn won’t accept the localhost server.
I’m finished the setup and i’m still not getting any payment notification in my paypal ipn plugin.
Can you help me with this?
Hi Patrick,
Yes, I can help you with this, but it sounds like something that would be best if we get on the phone together so I can talk you through everything. For that you’ll need to submit an order for premium support. Then we can schedule a time to talk and I can get you all situated.