is HTTP 200 response actually necessary for IPN paypal protocol? - php

I'm going to implement the IPN protocol in my website, using php.
Paypal documentation note that the protocol goes as follows:
The user clicks the button.
Paypal posts my IPN listener an IPN message.
My listener has to send an empty HTTP 200 OK response.
My listener has to send the message gotten from paypal (with a preceding string) back to paypal.
Paypal sends my listener a "VERIFIED" or "INVALID" response.
Can anyone explain why the protocol demands this [3] step?
Why can't it be fulfilled just with the [4]th step?
Also, I noticed that in another chapter of paypal documantation, they skip this [3]rd step themselves (see their implementation). So I wonder, is it really necessary??

The 200 OK response will happen automatically as long as your IPN script completes successfully. This let's the PayPal server that it did indeed complete.
If PayPal's IPN server gets something other than 200 OK back from your web server it will assume your script failed and will place that IPN in a que to be re-sent. It will resend after 30 seconds, then 60 seconds, then 120 seconds, etc. until it gets that 200 OK.
This is why sometimes people end up with duplicate IPN's. If you've got something at the very bottom of your script, for example, that's failing, but all of your email notifications, database updates, etc. actually did work prior to that point, you'd end up seeing those things happen again and again because PayPal kept re-sending the IPN. This can be very messy, of course, so you want to make sure that's not happening.
Again, though, the response code gets sent back to PayPal from your web server automatically. It's not something you actually have to do within your code.

Related

PayPal IPN simulator returning "INVALID" but I've followed the rules

So I have a PHP service that's only job is to accept PayPal IPN connections. I'm using PSR7 $request->getBody()->getContents() to get the following from PayPal IPN simulator request.
payment_type=echeck&payment_date=Tue%20Jun%2007%202016%2012%3A56%3A47%20GMT+0100%20%28BST%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer#paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John%20Smith&address_country=United%20States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San%20Jose&address_street=123%20any%20street&business=seller#paypalsandbox.com&receiver_email=seller#paypalsandbox.com&receiver_id=seller#paypalsandbox.com&residence_country=US&item_name=something&item_number=AK-1234&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&txn_type=web_accept&txn_id=787223012&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31AfBnnvbsi0E9urbgYYn51fFWPj23
So when I post this back using Guzzle 6 POSTing to https://www.sandbox.paypal.com/cgi-bin/webscr using the following body.
cmd=_notify-validate&payment_type=echeck&payment_date=Tue%20Jun%2007%202016%2012%3A56%3A47%20GMT+0100%20%28BST%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer#paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John%20Smith&address_country=United%20States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San%20Jose&address_street=123%20any%20street&business=seller#paypalsandbox.com&receiver_email=seller#paypalsandbox.com&receiver_id=seller#paypalsandbox.com&residence_country=US&item_name=something&item_number=AK-1234&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&txn_type=web_accept&txn_id=787223012&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31AfBnnvbsi0E9urbgYYn51fFWPj23
I get INVALID for a response. I don't know if it coming from a different IP address to the server that handles the SSL termination is the issue or if I'm just going mad.
I've ran a diff on PayPal's simulator request body to the body I send back without the cmd variable and there is no difference.
It would seem the new IPN Simulator interface is using javascript Dates in the payment_date field. If you set this manually to something like today it works OK. Whether this is an encoding/decoding issue on the IPN Simulator side, or in your IPN listener, I am not sure.
We have been using the IPN simulator for the last few days, and are getting intermittent INVALID messages returned on the validation request.
Waiting a few minutes, or just pressing the "Send IPN" message a few times seems to work.
We have seen a request return an INVALID, and moments later the same request returns VERIFIED. Quite annoying.
The PayPal transaction validation always returns INVALID if the IPN comes from the IPN simulator, but I found a workaround. If the IPN will come from a real transaction, it works fine. Here is how I did.
Go to PayPal Developer and Login
Create a sandbox account (if you already have a sandbox account, ignore these 2 steps)
Now go to https://www.sandbox.paypal.com and login
Then visit button management and create a button
Don't forget to set the IPN notification URL for your sandbox acccount
Now make a real tracaction from the button you created in the sandbox account
It works flawlessly
For the record, I have been having this issue with Paypals IPN Simulator, and found that the solution is typical of Paypal:
The Issue: A correctly formatted IPN test run on the Paypal IPN Simulator returns INVALID when all checks show it should be correct.
Solution:
1) The simulator ALWAYS runs on the "sandbox" environment. I was using it to check on a "LIVE" payment sites feedback and took hours to discover that your IPN needs to be set to sandbox mode. This is not mentioned on the Paypal Simulator and appears to be hardcoded and "assumed" by Paypal.
2) the Payment_Date field in the IPN Simulator is invalid and not accepted when returned to Paypal, so clear this field or set this field to null when submitting IPN Simulator runs.
3) Sometimes, strangely, Paypal IPN Simulator will tell you
IPN was not sent, and the handshake was not verified. Please review your information.
Even Though the simulated transaction is fully processed by my IPN listener script and returns VERIFIED. Always Check your own feedback script rather than the crap Paypal decides to tell you.
A combination of the above issues has lost several hours of my life. Stripe is far, far better to code with.

Paypal ION different servers

so I got a guy to code this IPN feature for my website.
Basically a user pays thought the main site then it forwards the ipn stuff to another server and that server sends ipn payment to paypal. For some reason it keeps saying "retrying" under the paypal IPN history. Is paypal blocking this and does the payment have to be made from the same server? Thanks hopefully this makes sense!
IPN does not happen until after any transaction has occurred, so what you're saying here doesn't really make sense. There's no way IPN would be sending any payment to PayPal. PayPal simply POSTs transaction data to your IPN URL after the transaction has taken place.
That said, if you're seeing "retrying" in your IPN History that means your IPN script is not completing successfully, and as such, is not returning a 200 result code back to PayPal's server. You need to troubleshoot your IPN script to figure out what's failing and get it fixed.
Your web server logs should provide the information you need. If you look there you should see a log of when your IPN URL was hit and it should also provide the result including any errors that were generated from the request to that script.
I like to create a simple HTML form with the action set to my IPN URL and then include hidden fields that match the fields/values that I would expect to get from IPN. This way you can load that in a browser and submit it directly so that you can see the result on screen which can help with troubleshooting and debugging.
Keep in mind that when testing that way, though, the data is not coming from PayPal's servers, so it will not verify. You'll need to make sure your script is setup to handle this accordingly for testing purposes.

Paypal IPN not calling Issue

I am having some problem regarding Paypal IPN not getting fired on one of my server. Below is the scenario.
1) I have two sites site A(old) is on server X and site B(new) on server Y.Both the sites having identical Paypal express checkout form submission and IPN code.
2) Site A is running smoothly with paypal express checkout form submission and IPN is get fired correctly.
3) But with Site B, though our form gets submitted correctly and payment is successful, IPN is not getting fired.
More information :
I checked Paypal`s business A/c for any of functionality that may needed to add IP/domain where IPN is located.
I have also checked with Paypal support where they says that from 25 March 2014 they have told to add Paypal`s API related IP address to our servers firewalls. We had done with adding those IP address but still this is not working.
URL : https://ppmts.custhelp.com/app/answers/detail/a_id/14/related/1/session/L2F2LzEvdGltZS8xNDAxMTcyODkwL3NpZC9VbENEUWhWbA%3D%3D
Hope following information is sufficient for you. Please suggest if any one of us have some solution to overcome.
Thanks in advance.
Unfortunately, there's not much issue specific information for me to work with, so lets make this an IPN Troubleshooting Guide for future reference :)
Check the IPN feature status for the given account -
https://www.paypal.com/cgi-bin/customerprofileweb?cmd=_profile-ipn-notify (login to your account first, then follow the link to be taken to the IPN Settings)
Alternative:
Login to PayPal.com
Open Profile --> My Selling Preferences
Find the "Instant payment notifications" option
There are four states IPN can be in:
Enabled --> If you're prompted to choose your settings, IPN is
enabled and IPNs will be sent if a notify URL is passed in the
checkout request.
Enabled with Default URL Set --> If a "Notification URL" is displayed and "Message delivery" is set to enabled, the default URL will be used every time you do not specify a different IPN URL in the checkout request (e.g. eBay transactions will be sent to the default URL because eBay's Express Checkout Integration does not pass a notify URL)
Disabled --> You never set the default URL, but IPN URL passed in your transactions has been throwing too many errors. You should see the empty Address field and the option "Do not receive IPN messages (Disabled)" being checked.
Disabled with Default URL Set --> a default IPN URL was configured at some point in time, but due to failures on the default URL or on the dynamic URLs, the IPN feature has been disabled. You will see the URL and "Message Delivery = Disabled"
Why does PayPal disable IPN delivery?
PayPal expects your server to respond with a HTTP-200 OK message. If we receive a different response code, a retry mechanism is set in motion.
The IPN message is sent a total of 16 times with increasing time frames between each attempt. If the errors for one URL reach a certain threshold, IPN is disabled automatically. You will receive an e-mail message to the main e-mail address listed on the PayPal Account, that warns you of an impending deactivation
If IPN is enabled, check the status of the last IPN messages under https://www.paypal.com/cgi-bin/webscr?cmd=%5fdisplay%2dipns%2dhistory&nav=0%2e3%2e4
It'll show you the last HTTP Response Codes your server is sending back and you can filter for failed / retrying messages.
Check http://en.wikipedia.org/wiki/List_of_HTTP_status_codes to see what the status means.
If there is not HTTP Response code, there's a connection issue on a lower level.
Most frequently caused by:
Firewalls
SSL Connectivity Problems (try using HTTP)
Black Hole Routing
If you feel that everything is configured correctly, check out https://ppmts.custhelp.com/app/answers/detail/a_id/733
If the IPN messages are marked as "SENT" (HTTP 200 Received), the next step in IPN processing is posting the data back to PayPal for validation. You can either enable logging within the script (dump the HTTP request and response in a file on the server) - or you can contact PayPal MTS ( https://www.paypal.com/mts ) and ask what's visible on the PayPal Side.
A good test to check the connectivity to paypal is to run the following command on the webserver itself:
curl -d "cmd=_notify-validate" -v https://www.paypal.com/cgi-bin/webscr
If you see that the POST has reached PayPal, but PayPal responds with INVALID for all messages:
Check your code, https://github.com/paypal/ipn-code-samples is a good source of samples
If PayPal responds with INVALID to some messages, you're likely running into an encoding issue. You'd best set your Character Encoding settings under https://www.paypal.com/cgi-bin/customerprofileweb?cmd=_profile-language-encoding - set them to UTF8 for the best results.
If PayPal Responds with VERIFIED, but your script doesn't continue processing after validating the payment, make sure you run a TRIM() (or the equivalents in the language being used) to remove whitespace, line feeds and CRLF
What happens afterwards is up to the IPN script you may run into errors while connecting to a database, parsing the IPN message for certain data or some coding errors.
In short: If the IPN message has been received, posted back and verified, everything else happens in your own code on your server and you'd have to start digging through log files (or make sure logs are being created, that's always a good idea) to find out what's going on. If the problem is reproducible, it is always a good idea to check what happens with one of the sample scripts (which include logging)
Hope this helps tackling IPN issues head on - any questions regarding IPN? Contact paypal.com/mts if you want to investigate what's happening on the paypal side.

Paypal IPN continuously hits my IPN page w/the same transaction

I just moved my server to a new host, and obviously changed the DNS for my paypal ipn page.
For some reason paypal keeps hitting my page about every 30 seconds with the same transactions over and over again.
So of course its verified then stored in the database as duplicate records.
Has anyone had this problem? Or know how to fix?
Make sure that your browser is returning 200 OK status to paypal.
Either way, you should store IPN tracking IDs (ipn_track_id) in your database and check for duplicates. This is the only guaranteed way to solve your problem.
According to PayPal's IPN documntation:
Your listener must respond to each message, whether or not you intend
to do anything with it. If you do not respond, PayPal assumes that the
message was not received and resends the message. PayPal continues to
resend the message periodically until your listener sends the
correct message back, although the interval between resent
messages increases each time. The message can be resent for up to four
days.
This resend algorithm can lead to situations in which PayPal
resends the IPN message while you are sending back the original
message. In this case, you should send your response again, to cover
the possibility that PayPal did not actually receive your response the
first time. You should also ensure that you do not process the
transaction associated with the message twice.
IMPORTANT: PayPal
expects to receive a response to an IPN message within 30 seconds.
Your listener should not perform time-consuming operations, such as
creating a process, before responding to the IPN message.
So a) is your script properly responding and b) is the notify_url parameter from your transaction different with your DNS change?

Test Paypal IPN in the Sandbox

I am writing a script to handle the paypal IPN, so when someone buys something via paypal it will send them an email and write some info into a database.
I am using the Instant Payment Notification simulator, and it is sending my email ok but i would like it to actually re-direct to my php page, so i can test my error checking etc. When you submit it does call the page but i would like to actually be re-directed to it.
Anyone know if this is possible, or if there is anything i can do to 'fake' this process
Cheers
Luke
Well, you can just test your IPN by using a temporary Payment Data Transfer page. Read this page for more information about this.
So basically after your payment has been done it redirects you to that success page and does everything. So you can use the success page as a test version of your future IPN page. After your script is working exactly the way you want, you can use the code on that page by simply copy-pasting it into your IPN page and deleting that test PDT page.
Another way is to catch the entire output of your IPN page and mail it to you. Or store it somewhere. To do this, make use of PHP's output buffering.
I hope that makes sense to you...
I usually use micahcarrick Paypal IPN class for Paypal IPN.In this class you can see
success case in switch case statement, There you can redirect to your success page.
Actually, Paypal IPN will return response to us. you can see the action parameter in return url. using this you can find is payment is success or cancel or any error during payment.
Hope it helps,Thanks
Paypal IPN messages are Server to Server Messages for asynchronously receiving messages from Paypal regarding transactions. The HTTP Client used by Paypal to deliver IPN message to your server may not support redirect requests. As these HTTP requests are not coming from users browsers' output from your Php script is irrelevant. If you want to do any extended processing you have to incorporate that into your IPN Handler.

Categories