VBScript ASP and Paypal IPN problems - asp.net

Dear Mentors and Gurus,
My question is basic, it is similar to other IPN questions on here, but I have yet to see an answer related to VBScript (seems PHP is a bit lower level so more work to do to post the response properly- or so I think).
I'm using the PayPal sample code for ASP/VBScript to create a IPN listener. Using the Paypal simulator, I make a call to my script. I don't seem to be able to get a "VERIFIED" response from Paypal, always 'INVALID'. I've read a number of things on the internet (like the charset) and tried these with no progress. Answers regarding charset differences seem to be older as I don't see any place to control charset, especially via the simulator. I'm not seeing a URL Encoding issue as what is posted back is still/already encoded (the GMT + issue doesn't seem to be present as described in other IPN problems).
I post to https://www.paypal.com/cgi-bin/webscr (see code) and that gives me a handshake, but posts to sandbox (commented out) do not result in handshake. Absolutely, Paypal is communicating with my website, I have modified the code to dump out all the form values received into a text file. Just can't ever get a "VERIFIED" response.
I thought the code provided on GitHub would be 'ready to go'. What noobie thing am I missing?
<%#LANGUAGE="VBScript"%>
<%
Dim Item_name, Item_number, Payment_status, Payment_amount
Dim Txn_id, Receiver_email, Payer_email
Dim objHttp, str
' read post from PayPal system and add 'cmd'
' post back to PayPal system to validate
'set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP")
'set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP.4.0")
set objHttp = Server.CreateObject("Microsoft.XMLHTTP")
str = Request.Form & "&cmd=_notify-validate"
objHttp.open "POST", "https://www.paypal.com/cgi-bin/webscr", false
'objHttp.open "POST", "https://www.sandbox.paypal.com/cgi-bin/webscr", false
'objHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"
'objHttp.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
objHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
objHttp.Send str
' assign posted variables to local variables
'Dim responseText : responseText = objHttp.responseText
Item_name = Request.Form("item_name")
Item_number = Request.Form("item_number")
Payment_status = Request.Form("payment_status")
Payment_amount = Request.Form("mc_gross")
Payment_currency = Request.Form("mc_currency")
Txn_id = Request.Form("txn_id")
Receiver_email = Request.Form("receiver_email")
Payer_email = Request.Form("payer_email")
Dim Folderpath, fs, fPayPal, fPP, FormArray, FormStr
Set fs = CreateObject("Scripting.FileSystemObject")
Folderpath=server.mappath(".\mdb")
fPayPal=Folderpath &"\paypal.txt"
'Payer_email = "test#test.com"
Response.Write "File:" & fPayPal
Set fPP = fs.CreateTextFile(fPayPal,True)
fPP.WriteLine("PayPal")
fPP.WriteLine(str)
FormArray = Split(str, "&", -1, 1)
for each FormStr in FormArray
fPP.WriteLine(FormStr)
Next
' Check notification validation
if (objHttp.status <> 200 ) then
' HTTP error handling
'Response.Write "Error:"
fPP.WriteLine("Status <> 200")
elseif (objHttp.responseText = "VERIFIED") then
fPP.WriteLine("VERIFIED")
fPP.WriteLine(Payer_email)
' check that Payment_status=Completed
' check that Txn_id has not been previously processed
' check that Receiver_email is your Primary PayPal email
' check that Payment_amount/Payment_currency are correct
' process payment
elseif (objHttp.responseText = "INVALID") then
' log for manual investigation
' Response.Write "INVALID"
fPP.WriteLine("INVALID")
else
' Response.Write "OTHER ERROR"
fPP.WriteLine("OTHER ERROR")
end if
set objHttp = nothing
fPP.Close
Set fs=nothing
%>
Things you see commented out are things I tried or comments from the original code on github. Paypal IPN example code
Here's what the result is in paypal.txt, the file written by the code. The last line is "INVALID" which is written because the responseText is set to "INVALID" by the POST call to paypal.
PayPal
payment_type=instant&payment_date=Mon%20Apr%2003%202017%2010%3A12%3A36%20GMT-0400%20%28Eastern%20Daylight%20Time%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_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=283858647&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31A4bCrzfIB.qeXiXSypZmZAhKwWUC&cmd=_notify-validate
payment_type=instant
payment_date=Mon%20Apr%2003%202017%2010%3A12%3A36%20GMT-0400%20%28Eastern%20Daylight%20Time%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_name1=something
item_number1=AK-1234
tax=2.02
mc_currency=USD
mc_fee=0.44
mc_gross=12.34
mc_gross_1=12.34
mc_handling=2.06
mc_handling1=1.67
mc_shipping=3.02
mc_shipping1=1.02
txn_type=cart
txn_id=283858647
notify_version=2.1
custom=xyz123
invoice=abc1234
test_ipn=1
verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31A4bCrzfIB.qeXiXSypZmZAhKwWUC
cmd=_notify-validate
INVALID
This response is only available when I post to paypal. Posting to sandbox.paypal.com does not indicate a 'sent' or a 'handshake'. I am using a remote/hosted website by a service provider, so the weblogs are not available to me until 48 hours later. All the nice debug features I normally would have on my local webserver are not available (no method to sniff the raw data posted by Paypal or returned that I am aware of on the remote machine).

I found this as a statement:
When you use the PayPal IPN Simulator, the response you get will always be Invalid.
Not in the documentation from what I can tell. If someone can confirm, then this tidbit would have saved me a weekend of trial/error.
//Update
I have learned two things which I'll share with the community. The proper URLs to use in 2017 are:
objHttp.open "POST", "https://ipnpb.sandbox.paypal.com/cgi-bin/webscr", false
or for live:
objHttp.open "POST", "https://ipnpb.paypal.com/cgi-bin/webscr", false
What I believe the issue to be is that the Sandbox URL as of NOW only allows TLS 1.2 HTTPS connections (for sure you must use HTTPS and no longer HTTP). The live paypal URL will required TLS 1.2 in June 2017.
This problem occurs at the objHttp.Send str. It generates a 800c0005 500 error in your ASP as the Paypal Sandbox URL refuses the connection due to server using TLS 1.0 and Paypal requiring TLS 1.2.
As it turns out Godaddy (https://www.godaddy.com) hosting does not allow TLS 1.2 if you are an "older customer". We started windows webhosting with them in 2009. Rather than updating the server underneath our hosting to be current, as we're paying a service, they consider that we fractionally bought the 'old server' and are stuck with that. Now we need to pay to upgrade. This is despite the monthly cost for a new customer for hosting on a normal up-to-date server actually being lower than what we have now.
Please be aware community. I spent a week of time on this. You can't see the HTTPS handshake so a user is not going to know the limitations of the provider.
CONFIRMED. Worked once going onto a new (2017) server which supports TLS 1.2. Needed to start a new web-hosting because Godaddy will not update your existing account or the server software/OS underneath the website you have.

Related

HttpWebRequest received error 406 and Fiddler seems to have confused things

I am using the following code....
Dim myHttpWebRequest As HttpWebRequest = CType(WebRequest.Create(PostingUrl), HttpWebRequest)
myHttpWebRequest.Method = "POST"
myHttpWebRequest.Headers.Add("Authorization", "Bearer " & RSettings.access_token)
myHttpWebRequest.Headers.Add("Accept-Version", "2")
myHttpWebRequest.ContentType = "application/json; charset=UTF-8"
myHttpWebRequest.Accept = "application/json"
' myHttpWebRequest.Proxy = Nothing ' ** SEE NOTES ON THIS LINE **
Dim Byt As Byte() = Encoding.UTF8.GetBytes(DataString)
Using stream = myHttpWebRequest.GetRequestStream()
stream.Write(Byt, 0, Byt.Length)
End Using
Using myHttpWebResponse As HttpWebResponse = CType(myHttpWebRequest.GetResponse(), HttpWebResponse)
Using srRead As New StreamReader(myHttpWebResponse.GetResponseStream())
ListingResponse = srRead.ReadToEnd()
End Using
End Using
Where:
PostingUrl is "https://reverb.com/api/listings"
RSettings.access_token is (obviously) my access token for this API
DataString is a JSON string posting the data to the Reverb API
If I run my code from Visual Studio (localhost) it returns
The remote server returned an error: (406) Not Acceptable.
Trying to figure out why, I opened Fiddler hoping I could inspect content types and figure out the problem, but the response error changed to:
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
(I'm guessing from this error that I also have an issue with my Auth key, but that's a separate subject I think.)
After a bit of Googling and S/O pages I found two suggestions:
Tools > Fiddler Options > HTTPS and uncheck "Capture HTTPS CONNECTs"
Add the commented out line: myHttpWebRequest.Proxy = Nothing
If I make any of those changes, I get back to my Error 406 that I get without Fiddler running.
However, if I add myHttpWebRequest.Proxy = Nothing line added, I can no longer see the Tunnel to http://reverb.com:443 Log entry in Fiddler, there's no record of a request to Reverb.com so I can't inspect anything.
I'm now very confused about what I'm doing, and I guess haven't actually made any progress at all!
I still have error 406 and don't seem to be able to inspect the headers/content type issues with Fiddler as I had hoped (please explain how if I am wrong!)
Even if I do correct the 406, I think I have an authentication error.
By the way... all this is an attempt to recreate the cURL example on the Rever docs page here:
https://dev.reverb.com/docs/create-a-listing
I have also been discussing this issue here:
https://dev.reverb.com/v1.0/discuss/57bb2ca0aa8f760e004588cf
Argh... well, my confusing over Fiddler still stands but the 406 error was caused by this:
myHttpWebRequest.Headers.Add("Accept-Version", "2")
Should have been
myHttpWebRequest.Headers.Add("Accept-Version", "2.0")
How simple!!

CDOSYS : how to check if it's working?

On a client server, we have a little script that send an email at the end of an order, just before closing it.
Until yesterday everything works fine, but suddenly, the page gives a generic 500 error.
so I start from the bottom of the page find that if I put a response.end just before the .send of the cdo mail function, the page works fine:
Set iMsg = CreateObject("CDO.Message")
Set iConf = CreateObject("CDO.Configuration")
Set Flds = iConf.Fields
Flds(cdoSendUsingMethod) = cdoSendUsingPort
Flds(cdoSMTPServer) = "mail.theserver.com"
Flds(cdoSMTPServerPort) = 25
Flds(cdoSMTPAuthenticate) = cdoAnonymous '0
Flds.Update
With iMsg
Set .Configuration = iConf
.To = "mymail#mail.com"
.From = "amail#mail.gov"
.Sender = ""
.Subject = "test"
.HTMLBody = "TEST"
RESPONSE.END()
.Send
End With
On the page there are also two lines at the beginning:
<!--METADATA TYPE="typelib" UUID="CD000000-8B95-11D1-82DB-00C04FB1625D" NAME="CDO for Windows 2000 Type Library" -->
<!--METADATA TYPE="typelib" UUID="00000205-0000-0010-8000-00AA006D2EA4" NAME="ADODB Type Library" -->
Well, I’ve already done some test putting some script to send emails a little different from this one but nothing seems to work. Does anybody know a way to test the cdosys? Something that. I don't know, return the version... or a list of options... well, something that makes me know that the error is on the server (and so I could phone to them and tell "hey it's not my fault")...?
Edit:
Since the page gives only a 500 error, is there a way to makes the server returns a more specific error code? i can't access the server, but only the ftp (so only classic asp)
Edit 2: i have add this code:
on error resume next
.Send
If Err.Number <> 0 Then
Response.write(Err.Number)
response.write("<br>")
response.write(Err.description)
end if
and it gives this message:
-2147220975
Impossibile inviare il messaggio al server SMTP. Codice errore di trasporto: 0x800ccc6f. Risposta del server: 554 Your access to this mail system has been rejected due to the sending MTA's poor reputation.
Based on your error message the CDO component is working but your SMTP sever (MTA) is rejecting the message. Maybe because of the .gov domain? Regardless you have a poor SMTP reputation for spamming. You need to use a different SMTP server. If you are using the ip of the IIS server, than that IP is no longer good, and has been blacklisted by spam servers.
Mailchimp has a lot of information on mail deliverable. Take a look at it.
You can use a hosted SMTP service (mailgun, sendgrid, mandrill), all of which will block you right away if you are spamming.

Request.Form between HTTP and HTTPS pages in ASP.NET

I have a strange situation and google isn't helping me out. I have an admin site which is in simple HTTP who posts data to a different site running under HTTPS. The HTTP admin site (which I don't have direct access to) is sending the info via basic POST, and I'm trying to capture the Request.Form values in the HTTPS site. It works perfectly well in dev, due to the fact that the receiving site isn't running under SSL, but in prod, I have the Request.Form as empty. Someone could enlighten me? The basic HTTPS request code is below:
Dim nvm As NameValueCollection = Request.Form
Dim _idInscricao As String
Dim _Origem As String
litMensagem.Text = "Wait..."
If nvm.Keys.Count = 0 Then
litMensagem.Text = "Error recovering data. No keys found."
Exit Sub
End If
For Each _Key As String In nvm.Keys
If _Key.ToLower.EndsWith("idinscricao") Then
_idInscricao = nvm(_Key)
End If
If _Key.ToLower.EndsWith("origem") Then
_Origem = nvm(_Key)
End If
Next
If _idInscricao Is Nothing OrElse String.IsNullOrEmpty(_idInscricao) _
OrElse _Origem Is Nothing OrElse String.IsNullOrEmpty(_Origem) Then
litMensagem.Text = "Error recovering data."
Exit Sub
End If
I found this question because I was having the same problem, and I need to thank dana for the fiddler recommendation.
Using Fiddler, I found out what was going on. My page was on HTTPS, and the form that I was posting posted to HTTP. I couldn't figure out why my form structure on the posted page was empty.
Turns out the server couldn't find the http version of the file and did an automatic redirect to the https version, doing a GET with my form variables. They aren't available in the form scope with a GET. (FWIW, I'm using CFML.)
Once I changed the form action to post to HTTPS, everything worked like a charm.
-jason

ASP.NET & IIS 7.0 -- HTTPS Site Warmup Script

I have an ASP.NET 4.0 site on IIS 7.0 that is having first time load issues described here.
I've done some testing, and can confirm that it's only the first load of the page that is slow; every subsequent page loads normally. After googling around for this, I found a "warmup" script that can send an HTTP request the first time after the app pool is recycled, and this seems to fix the problem. BUT, I'm not sure if it will work when I force set the page to use only HTTPS/SSL?
The script I'm currently using is as follows:
Dim website1
website1 = "http://<website domain>/Auth/Login.aspx"
Function WarmUpSite(strURL)
On Error Resume Next
Dim objHTTP
Set objHTTP = CreateObject("MSXML2.XMLHTTP")
objHTTP.Open "GET", strURL, False
objHTTP.Send
If Err.Number=0 And objHTTP.Status=200 Then
Hget=strURL & " has been warmed up successfully at: "&Date()&" "&Time()
Else
Hget=strURL & " found error at: "&Date()&" "&Time()
End If
Set objHTTP = Nothing
'Section for writing into a text file
Const FOR_APPENDING = 8
strFileName = "C:\WarmUpLog.txt"
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objTS = objFS.OpenTextFile(strFileName,FOR_APPENDING)
objTS.WriteLine Hget
End Function
WarmUpSite(website1)
So my question is how I would make this work if the website I'm warming up is a login page that will be an HTTPS address, not HTTP? My apologies if this is a dumb question, I do relatively little web work.
Well, apparently it just involved changing the value of website1 to an HTTPS url.
;)

schedule webpage

I need to schedule several different pages on several different sites to be run at certain times, usually once a night. Is there any software out there to do this? it would be nice if it called the page and then recorded the response and whether the called page was successful run or not. I was using Helm on a different box and it had a nice Web Scheduler module but Helm is not an option for this machine. This is a Window Server 2008 box.
We use standard scheduled tasks that call a bat file that calls a VBS file. I know it is not the most elegant solution ever, but it consistently works.
BAT:
webrun.vbs http://website.com/page.aspx
VBS:
dim URL, oArgs
Set oArgs = WScript.Arguments
if oArgs.Count = 0 then
msgbox("Error: Must supply URL")
wscript.quit 1
end if
URL = oArgs(0)
on error resume next
Set objXML = CreateObject("MSXML2.ServerXMLHTTP")
if err then
msgbox("Error: " & err.description)
wscript.quit 1
end if
' Call the remote machine the request
objXML.open "GET", URL, False
objXML.send()
' return the response
'msgbox objXML.responSetext
' clean up
Set objXML = Nothing
The code in the VBS file is almost assuredly both overkill and underwritten, but functional none-the-less.
How about wget.exe and the task scheduler?
The code given in the upper example has some issues with the task being active during the loading of the website. The website is loading 2 minutes but the task is already done in 1 second, which brings a problem when you execute it every 5 minutes. If the website loads 10 minutes and the task is already done in 1 second it wil execute again that while I want it to wait the loading time of the website.
So what I've done is the following (this script will keep the task busy as long the website is loading):
dim URL, oArgs, objXML
Set oArgs = WScript.Arguments
URL = oArgs(0)
on error resume next
Set objXML = CreateObject("Microsoft.XMLDOM")
objXML.async = "false"
objXML.load(URL)
Set objXML = Nothing
If it's not a requirement to schedule them from the same box, have a look to Zoho's site24x7.
It is initially designed to monitor web sites but it has an option to record expected answers and compare them so you can use it for your purpose with the added security of an external site. It's not free however except for few urls.
They are other similar providers but they looked pretty good last time I searched the web on this topic.
I ended up using this script and Task Scheduler, simple and works great:
Call LogEntry()
Sub LogEntry()
'Force the script to finish on an error.
On Error Resume Next
'Declare variables
Dim objRequest
Dim URLs
URLs = Wscript.Arguments(0)
Set objRequest = CreateObject("Microsoft.XMLHTTP")
'Open the HTTP request and pass the URL to the objRequest object
objRequest.open "POST", URLs, false
'Send the HTML Request
objRequest.Send
Set objRequest = Nothing
WScript.Quit
End Sub
Then I just call it with the URL I want run as an argument:
Similar (though possibly more powerful) is netcat and its windows port
fyi - wget is GNU standard license, so I'm not sure it's usable for most commercial/proprietary systems.
I use http://scheduler.codeeffects.com. Very effective and reliable, no complains.

Resources