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¬ify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31AfBnnvbsi0E9urbgYYn51fFWPj23
So when I post this back using Guzzle 6 POST
ing 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¬ify_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.