I want to integrate Paypal Instant Payment Notifications (Paypal IPN) into my ASP.NET website. The website is in development mode and it runs on localhost.
Following this tutorial (https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNTesting/#local) I created a script that simulates a IPN notification. This IPN notification hits the IPN handler of my website.
However, when my IPN handler reposts the information back to Paypal sandbox, Paypal always returns INVALID. I guess this is expected because Paypal did not send the original IPN message.
However, I want to test the code that will run when IPN message is verified by Paypal. Currently I have no way to do it. Paypal docs say that I should put the code that runs when message is verified into the block that runs when message is invalid.
That is
if(response == "VERIFIED")
{
//put any code here in the else if block below
}
else if(response == "INVALID")
{
}
This technique appears very unclean and incomplete to me. I will have to change my code when I deploy to live server.
Is there a better way to test IPN using localhost?
There is a great tool for this: https://ngrok.com/.
Ngrok allows "secure intospected tunnels into localhost". Basically you deploy ngrok, and then a URL like '48210d19.ngrok.com' will point to your localhost. You use that URL for testing your IPNs.
That snippet you've shown is the correct way to do it. I'm not sure why you would think you have to change anything when you go live..??
What I like to do is just set a $verified parameter within that to true/false accordingly.
if(response == "VERIFIED")
{
$verified = true;
}
else if(response == "INVALID")
{
$verified = false;
}
From that point on in your script you can use if($verified) to handle certain tasks. Any code that you want to happen when a successful call takes place should go inside verified code blocks, and any code you want to run if it's not verified should go inside else blocks, or maybe a if(!$verified) block.
I typically just do the same thing for all IPN's, but I have a field in my database to store the status of the IPN. That way in my own reporting or web apps I can easily separate the verified and unverified data, and processing them however I want to.
As the docs say, when you're testing with a local form like that, the data is not coming from PayPal so those will always be unverified. If you want to fully test actual data from PayPal you can do that in the sandbox, too, using the IPN Simulator available in your PayPal developer account or by setting up IPN in your sandbox seller account and actually processing a payment.
Of course, you'll need to make sure your IPN script is configured to handle both sandbox and live transactions, but assuming it is you would get a verified IPN in those tests since the data actually did come from PayPal's sandbox server.
If your development environment uses Vagrant, then it takes only a few simple steps to use vagrant sharing which makes your vagrant virtual accessible publically (i.e. temporarily, for demo purposes, etc.), and allows PayPal to send IPNs to your dev site.
Sign up for a free Atlas account at https://atlas.hashicorp.com.
Log in as follows:
(trunk)jason#canoe:~/my/project$ vagrant share
(you will be prompted for email & password)
Start sharing:
(trunk)jason#canoe:~/my/project$ vagrant share
==> default: Detecting network information for machine...
default: Local machine address: 192.168.22.10
default: Local HTTP port: 80
default: Local HTTPS port: disabled
==> default: Checking authentication and authorization...
==> default: Creating Vagrant Share session...
default: Share will be at: delinquent-puppy-5196
==> default: Your Vagrant Share is running! Name: delinquent-puppy- 5196
==> default: URL: http://delinquent-puppy-5196.vagrantshare.com
You need to take care to set your IPN url (notify_url variable in your paypal form) to the HTTP HOST header passed from the browser. How you get this header depends on your framework; it is often callend SERVER_NAME or HOST_NAME.
Related
I spent the last day and a half researching this problem to no avail. I found many similar problems, but none that exactly address my issue. I am attempting to integrate Payflow Pro with transparent redirect, but cannot successfully complete a transaction. I am using the test environment with a test Payflow Gateway account.
I can successfully retrieve a secure token by posting the following from my test server to https://pilot-payflowpro.paypal.com:
PARTNER=[hidden]&VENDOR=[hidden]&USER=[hidden]&PWD=[hidden]&TRXTYPE=S&TENDER=C&CREATESECURETOKEN=Y&SECURETOKENID=20180916085333999&URLMETHOD=POST&SILENTTRAN=TRUE&AMT=2&BILLTOFIRSTNAME=John&BILLTOLASTNAME=Doe&BILLTOADDRESS=123TestDr.&BILLTOCITY=Testcity&BILLTOSTATE=TN&BILLTOZIP=55511&BILLTOEMAIL=johndoe#test.com&USER1=3&USER2=&USER3=0&USER4=2
to which I receive the following response:
RESULT=0&SECURETOKEN=[hidden]&SECURETOKENID=20180916085333999&RESPMSG=Approved
NOTE: I have configured a Return URL using PayPal Manager, which is why RETURNURL is not included in the secure token request. However, I also have tried with RETURNURL specified, and I have obtained the same end result.
I use the results from the secure token request to create a cc collection form. I input test credit card details using acct# 5105105105105100, then post the following from the browser directly to https://pilot-payflowlink.paypal.com:
fund_id=3&ACCT=5105105105105100&CVV2=555&EXPMONTH=01&EXPYEAR=20&EXPDATE=0120&SECURETOKENID=20180916085333581&SECURETOKEN=[hidden]&feeTokenID=20180916085333999&feeToken=[hidden]
The response is properly redirected to the Hosted Page error URL I have specified in my Payflow Manager Service Settings. My problem is that I do not understand why it is redirecting to the error url with the following message:
RESPMSG=Failed to connect to host Input Server Uri = https://pilot-payflowpro.paypal.com:443
NOTE: The value above is only one part of the response sent to the error page. The rest of the return values include information from my original secure token request, which I would assume could only be returned if a successful connection had been established with the link in the error message??
To clearly state the problem:
I have already successfully connected from my test server to the link specified in the error message, when first I obtained the secure token.
The post that results in the error message was sent from the browser (in this case, on the same physical box as my test server) to https://pilot-payflowlink.paypal.com, which is not the URL specified in the error message.
Finally, the error seemingly occurs during the Payflow process - to my understanding, there should not be a call from my server or the browser to the link in the error message at this point during the process. I mention this specifically to address the many search results I found relating this particular error message to PayPal's requirement for TLS1.2, which is already properly configured on my server (I should mention for the sake of completeness, I do still have TLS1.0 enabled on my test server, but cannot disable it for unrelated reasons. Nonetheless, I was able to successfully connect to obtain a secure token, and my server passes PayPal's own TLS test at https://tlstest.paypal.com/).
I should mention that I also have tried to complete this same transaction on our production server, still using test credentials and test endpoints at PayPal, with exactly the same results. The test server is also set up for TLS1.2 with TLS1.0 enabled, and also passes PayPal's test.
This problem may be the one that pushes me full-on into insanity, so any help really would be appreciated!!
Disabling TLS1.0 has helped others with this issue. If you keep having problems, contact PayPal's support
For anyone who might find this question and be similarly frustrated, I want to share that I was able to solve the problem by creating a new Payflow Gateway test account.
I spent a great deal of time on trial and error solutions with no success, and PayPal Merchant Technical Services was able to duplicate the problem but was also unable to find a solution. Finally, after simplifying my test app as much as possible (two bare-bones HTML forms filled in and submitted manually), I came to the conclusion that there might be something wrong with my test account. Upon creating a new account with new credentials, then inserting them back into my original code, everything worked perfectly.
As of this morning, PayPal MTS is continuing to research the problem, since others have reported similar issues.
For others with similar problems, it is worth noting that I am now able to complete transactions while TLS 1.0 remains enabled.
I tried finding an answer here but can not.
I've been using this code to process PayPal IPN for over a decade! Now, as of July 2018 it no longer works!
https://github.com/paypal/ipn-code-samples/blob/master/asp/paypal_ipn.asp
The only thing I know that is different recently is that PayPal required my domain to use TLS 1.2. I asked my hosting company to make sure that it now uses that, and they made some change to make sure. Ever since then, the listener I have set up does not process the IPN correctly. The code always falls into this IF:
if (objHttp.status <> 200 ) then
And never falls into this ELSEIF the way it used to when it was working fine:
elseif (objHttp.responseText = "VERIFIED") then
I'm not even sure how to troubleshoot this at this point. Is it something about the TLS 1.2? How can I make sure my hosting company set that up correctly?
Does my listener have to be located at an HTTPS url on my site? (Right now it is on HTTP).
Thanks.
In February, I got an email notice from Paypal that IPN would no longer validate successfully via an HTTP callback, and would further require HTTPS/SSL to validate. Update your script to connect this way, and it will probably fix it.
This PHP example should give a reasonable example.
Line 142:
" $fp = fsockopen("ssl://www.paypal.com",443,$err_num,$err_str,30);"
I had similar issues previously when connecting to Paypal on port 80.
I have a Business Site and am using Sandbox to try to get PDT to work.
I set up return URL in selling preferences and turned PDT ON - but my Sandbox buyers do not get returned to the site.
There are warnings that if you do not format the return url properly then it will not work, but I cannot find any instruction as to what that format is. I am not sure if I specify the page I want to return to or just the root address which PayPal will something to.
I want to use it with an https, but I have also tried and failed with a different http site that I have.
Can you suggest what I might have forgotten to do?
It would be great if you could help me get started on this fairly fundamental point!
We have multiple sites that uses PayPal standard with PDT and IPN callbacks, when I switch this to sandbox mode things don't work but works outside of the sandbox. Try connecting to the live urls and see if that works, you can always refund payments if they go through.
In the posting url you can specify &return=XXX where XXX is the url encoded url back to your site
[This will override the setting within PayPal which is handy if you have multiple sites using the same PayPal account]
You can also specify the IPN (which should also be implemented) using ¬ify_url=
I got an auto-return to work in the sandbox!
Not quite sure what I did BUT it might have been that I set up PDT and IPN in the sandbox site, instead of just in the live site.
thanks for replies. I am not out of the woods yet, but I now live in hope.
A client of ours want's to handle PayPal transactions via SagePay,
I've got the initial request working to set up the transaction and redirect off to PayPal via:
https://test.sagepay.com/Simulator/VSPDirectGateway.asp
But this doesn't seem to work for "COMPLETE"-ing the transaction, in test mode you'd use:
https://test.sagepay.com/gateway/service/complete.vsp
or in production:
https://live.sagepay.com/gateway/service/complete.vsp
But how would I complete the request in the simulator? the first URL doesn't seem to work -
You have sent a TxType of COMPLETE which is not recognised.
Neither does https://test.sagepay.com/Simulator/VSPServerGateway.asp?Service=VendorCompleteTx -
Server Simulator reqires a Service Name as part of it's URL. e.g. VSPServerGateway.asp?Service=VendorRegisterTx. This service tells Server which tasks to perform.
Have you tried this one? https://test.sagepay.com/Simulator/paypalcomplete.asp
Let me know.
I'm developing a site for a client, and he wants people to be able to buy licenses/support contracts via PayPal. What I'm stumped on is how I can make the payments secure. My current idea is to generate a random string using MD5 or whatever, plug this into a database, and send it along with the rest of the PayPal button code. When the payment is completed, the user is redirected to a PHP page where there is code to update their information in the database. The only thing stopping a hacker giving themselves a license/whatever without paying is the random hash, which can be found out using a sniffer of some sort, and plugged into the POST data returned by the PayPal code.
So. My question is this: How do I execute custom PHP code only on a successful PayPal payment, without leaving any loopholes open for the more evil users of the interwebs?
I think you should use a Payment Gateway such as PayFlow
if you're on the website ready to pay, there maybe a session already with your user logged in?
in this scenario, when the user returns back to the website, you can check you have a particular session variable and if it exists, you do the following
1) check your session, do you have a user logged in? should still be logged in if you just visited paypal a few minutes ago.
2) does the session contain your sale_id?
3) if no, dump the user on the home page, remember to header("Location..."); die("DEAD"). the die() part is important
4) if yes, check the sale_id was paid, the notify url should have caught the POSTED payment data, if valid, allow them to update the data
5) if yes, but not valid, allow them to repay using another method, this means to redirect them to another page to attempt to pay again, but don't let them access the "change details" page, the only way you get there, is by strictly validating the payment was successful.
how does that work for you ?