PayPal IPN Listener on my website has started throwing a Guid error when someone pays me on Ebay - asp.net

Below is my IPN Listener which has always worked fine on my website for customer PayPal payments. It sets up orders for my site in the Guid format (32 digits with 4 dashes). However, I use the same PayPal account for my Ebay selling and I have just sold an item which when paid for, caused the following error:
System.FormatException
Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
In the IPN history the Payment Status is COMPLETED but the HTTP Response Code is 500 and Delivery Status is 'Retrying'. I'm getting email warnings from PayPal about this, which worry me as I need IPN for my website.
I have checked the Ebay transaction and 'Custom' is EBAY_ENSDX00001030330553110 so I'm guessing my IPN code doesn't like that. Is there a way I can keep Ebay transactions away from my IPN Listener within PayPal? Or is there a way I can edit my IPN code below to deal with a custom ID which isn't in the 32 digit format?
IPN Listener..
Imports System.Net
Imports System.IO
Imports System.Net.Cache
Partial Class IPNListener
Inherits System.Web.UI.Page
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
'Post back to either sandbox or live
'Dim strSandbox As String = "https://www.sandbox.paypal.com/cgi-bin/webscr"
Dim strLive As String = "https://ipnpb.paypal.com/cgi-bin/webscr"
'SSL Error Code
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Dim req As HttpWebRequest = CType(WebRequest.Create(strLive), HttpWebRequest)
'Set values for the request back
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
Dim Param() As Byte = Request.BinaryRead(HttpContext.Current.Request.ContentLength)
Dim strRequest As String = Encoding.ASCII.GetString(Param)
strRequest = strRequest + "&cmd=_notify-validate"
req.ContentLength = strRequest.Length
'Send the request to PayPal and get the response
Dim streamOut As StreamWriter = New StreamWriter(req.GetRequestStream(), Encoding.ASCII)
streamOut.Write(strRequest)
streamOut.Close()
Dim streamIn As StreamReader = New StreamReader(req.GetResponse().GetResponseStream())
Dim strResponse As String = streamIn.ReadToEnd()
streamIn.Close()
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(strRequest)
'Insert the paypal response
Dim order As New orders
order.InsertPaypalResponse(qscoll("txn_id"), qscoll("custom"), strRequest)
If strResponse = "VERIFIED" Then
order.UpdateOrderFromPaypal(qscoll("custom"), qscoll("txn_id"), qscoll("payment_status"))
ElseIf strResponse = "INVALID" Then
'log for manual investigation
order.UpdateOrderFromPaypal(qscoll("custom"), qscoll("txn_id"), qscoll("payment_status"))
Else
'Response wasn't VERIFIED or INVALID, log for manual investigation
order.UpdateOrderFromPaypal(qscoll("custom"), qscoll("txn_id"), "ERROR")
End If
End Sub
End Class

In the case of an EBAY transaction, you can simply skip over the verification and exit successfully, since you don't need to do anything with it.
All PayPal needs you to do is return HTTP 200, so they can mark the IPN as successfully delivered. (The problem is you are currently returning HTTP 500 or similar, causing PayPal to mark the delivery as failed.)
An alternative solution is to specify your site's notify_url at your website's transaction level, as a parameter in each transaction's API setup (or HTML redirect if no API), which overrides any setting (or lack of a setting) in your PayPal account. Then in your PayPal account you can blank out the IPN listener URL, and you won't get any more IPNs for Ebay transactions.

Related

PayPal IPN Listener - HTTP Response Code 500

This error keeps happening on my website every so often. It's been working fine now for about 6 months but now decided to do it again.
I use 1&1 ionos hosting. The website uses asp.net and vb.net for the code. Its an online food delivery website which I set up myself by copying and changing some code that was written for me on another website. That site still works fine and is hosted with a different company so I don't know if it's something with ionos. When a customer orders, the payment clears in my PayPal but it doesn't tell my website that its cleared because the ipn is retrying a HTTP 500 error.
VB CODE TO CALL PAYPAL
Dim paypalURLString As String = "https://www.paypal.com/cgi-bin/webscr?" ' Live
Dim paypalParameterString As New StringBuilder
paypalParameterString.Append("cmd=_xclick&")
paypalParameterString.Append("notify_url=https://bozzafodder.co.uk/IPNListener.aspx&") 'POST address for notification
paypalParameterString.Append("bn=SlikkDesign_BuyNow_WPS_GB&")
paypalParameterString.Append("amount=" & session("total") + 1 + session("deliveryCharge") + ddlTip.SelectedValue & "&")
paypalParameterString.Append("item_name=Food Delivery&")
paypalParameterString.Append("currency_code=GBP&")
paypalParameterString.Append("custom=" & imgBtnPaypal.CommandArgument.ToString & "&")
paypalParameterString.Append("custom=" & order.orderID.ToString & "&")
paypalParameterString.Append("business=E4RYLU66FFE3L&") 'Live
paypalParameterString.Append("paymentaction=sale&")
paypalParameterString.Append("return=https://bozzafodder.co.uk/wait.aspx?orderID=" & order.orderID.ToString & "&")
paypalParameterString.Append("cancel_return=https://bozzafodder.co.uk/placeOrder.aspx?msgID=1&")
paypalParameterString.Append("rm=2&")
paypalParameterString.Append("cbt=Return to bozzafodder.co.uk&")
Dim displayParameters As New StringBuilder
displayParameters.Append("showHostedThankyouPage=false")
Response.Redirect(paypalURLString & paypalParameterString.ToString & displayParameters.ToString)
IPN LISTENER
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
'Post back to either sandbox or live
Dim strLive As String = "https://ipnpb.paypal.com/cgi-bin/webscr"
'SSL Error Code
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Dim req As HttpWebRequest = CType(WebRequest.Create(strLive), HttpWebRequest)
'Set values for the request back
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
Dim Param() As Byte = Request.BinaryRead(HttpContext.Current.Request.ContentLength)
Dim strRequest As String = Encoding.ASCII.GetString(Param)
strRequest = strRequest + "&cmd=_notify-validate"
req.ContentLength = strRequest.Length
'Send the request to PayPal and get the response
Dim streamOut As StreamWriter = New StreamWriter(req.GetRequestStream(), Encoding.ASCII)
streamOut.Write(strRequest)
streamOut.Close()
Dim streamIn As StreamReader = New StreamReader(req.GetResponse().GetResponseStream())
Dim strResponse As String = streamIn.ReadToEnd()
streamIn.Close()
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(strRequest)
If LEN(qscoll("custom")) >= 32 Then
'Insert the paypal response
Dim order As New orders
order.InsertPaypalResponse(qscoll("txn_id"), qscoll("custom"), strRequest)
If strResponse = "VERIFIED" Then
order.UpdateOrderFromPaypal(qscoll("custom"), qscoll("txn_id"), qscoll("payment_status"))
ElseIf strResponse = "INVALID" Then
'log for manual investigation
order.UpdateOrderFromPaypal(qscoll("custom"), qscoll("txn_id"), qscoll("payment_status"))
Else
'Response wasn't VERIFIED or INVALID, log for manual investigation
order.UpdateOrderFromPaypal(qscoll("custom"), qscoll("txn_id"), "ERROR")
End If
End If
End Sub
End Class
In the attached photos you can see the errors in the PayPal IPN history. The ones that are SENT are from my other website which works fine on a different website. The IPN code is the same though, I've compared the 2.
Your IPN listener is "Unable to connect to the remote server" when attempting to verify an IPN, and so returns a 500 HTTP status.
Your IPN listener must return a 2xx HTTP status for the IPN to be marked as successfully received. PayPal will retry up to ~20 times until this happens, and then mark the IPN as failed if there is still no 2xx success response from your listener.
Since the error is "Unable to connect to the remote server", that is what you must investigate and debug within your environment (listener code and server). Why is it not able to connect to https://ipnpb.paypal.com/cgi-bin/webscr?cmd=_notify-validate ?

Classic ASP Paypal IPN Refund

Trying to troubleshoot some legacy Classic ASP Paypal IPN code. The legacy code works perfectly for Selling products. However, processing a REFUND from the Paypal account seems to be causing some issue for Paypal IPN. The IPN listener receives the Refund IPN message and processes the business logic correctly, marking the transaction Refunded. But, Paypal still marks the transaction IPN History as "Retrying" for some reason. Below is the sample code from GitHub that was used to create the IPN listener we're troubleshooting.
Does the post back to Paypal need to be different for Selling vs Refunding?
Any help is greatly appreciated. Cheers
<%#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'
str = Request.Form & "&cmd=_notify-validate"
' 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")
objHttp.open "POST", "https://www.paypal.com/cgi-bin/webscr", false
objHttp.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
objHttp.Send str
' assign posted variables to local variables
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")
' Check notification validation
if (objHttp.status <> 200 ) then
' HTTP error handling
elseif (objHttp.responseText = "VERIFIED") then
' check that Payment_status=Completed and other variables
Execute business process code, mark transaction Completed or Refunded from payment_status works successfully
elseif (objHttp.responseText = "INVALID") then
' log for manual investigation
else
' error
end if
set objHttp = nothing%>
The postback to PayPal does not influence whether an IPN is marked as successfully received. The postback step is for your own verification that the IPN is from PayPal.
For an IPN to be successfully received, the HTTP response status must be 200 OK.

PayPal IPN Listener keeps 'Retrying' HTTP Response 500

My IPN Listener has been working fine for the last 6 months. This last week though, all transactions are 'Retrying' and causing a HTTP 500 Response. I haven't changed any code in the IPN Listener and I haven't changed any settings in PayPal. I have rang PayPal and they say it's not a problem their end. My hosting company 1&1 Ionos have pretty much no idea what I'm talking about. My IPN Listener code is below. My site uses Asp.Net/VB.Net..
Imports System.Net
Imports System.IO
Imports System.Web.Util
Imports System.Data.Common
Partial Class IPNListener
Inherits System.Web.UI.Page
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
'Post back to either sandbox or live
'Dim strURL As String = "https://www.sandbox.paypal.com/cgi-bin/webscr"
Dim strURL As String = "https://www.paypal.com/cgi-bin/webscr"
Dim req As HttpWebRequest = CType(WebRequest.Create(strURL), HttpWebRequest)
'Set values for the request back
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
req.Proxy = New WebProxy("ntproxyus.lxa.perfora.net", 3128)
Dim Param() As Byte = Request.BinaryRead(HttpContext.Current.Request.ContentLength)
Dim strRequest As String = Encoding.ASCII.GetString(Param)
strRequest = strRequest + "&cmd=_notify-validate"
req.ContentLength = strRequest.Length
'Send the request to PayPal and get the response
Dim streamOut As StreamWriter = New StreamWriter(req.GetRequestStream(), Encoding.ASCII)
streamOut.Write(strRequest)
streamOut.Close()
Dim streamIn As StreamReader = New StreamReader(req.GetResponse().GetResponseStream())
Dim strResponse As String = streamIn.ReadToEnd()
streamIn.Close()
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(strRequest)
'Insert the paypal response
Dim order As New orders
order.InsertPaypalResponse(qscoll("txn_id"), qscoll("custom"), strRequest)
If strResponse = "VERIFIED" Then
order.UpdateOrderFromPaypal(qscoll("custom"), qscoll("txn_id"), qscoll("payment_status"))
ElseIf strResponse = "INVALID" Then
'log for manual investigation
order.UpdateOrderFromPaypal(qscoll("custom"), qscoll("txn_id"), qscoll("payment_status"))
Else
'Response wasn't VERIFIED or INVALID, log for manual investigation
order.UpdateOrderFromPaypal(qscoll("custom"), qscoll("txn_id"), qscoll("payment_status"))
End If
End Sub
End Class
Your IPN listener likely is having problems connecting to https://www.paypal.com/cgi-bin/webscr in order to validate the IPNs it receives, and so is refusing to process the IPN and returning an HTTP 500, causing PayPal to retry its delivery repeatedly.
For your listener to be able to connect to PayPal and validate IPNs, you need to ensure you have an updated Certificate Authority bundle / list that is able to verify the issuer of the PayPal servers' current, cryptographically secure SSL certificates.
While you are at it, update your IPN listener to use ipnpb.paypal.com rather than www.paypal.com See the current documentation: https://developer.paypal.com/docs/ipn/integration-guide/IPNImplementation/

Is there a PayPal API or setting for Tax exemptions

My company deals a lot of farm parts and many of these people have filled out a tax exemption form for the state where, as long as the product qualifies, they do not have to pay tax. The problem is, in order to be exempt from paying taxes, we have to have their exemption form in our records. My question is, how can I handle this in paypal if possible? I am using the paypal checkout where the client is redirected to PayPal's site for checkout and then returned to my site after the transaction. The client would need to have some sort of option to check a checkbox or something to say they are tax exempt and I would then also have to check the client with our records to make sure we had his paper. If the would like to claim tax exempt they would have to fill out a form and send it to us. Is there any way that paypal deals with this or is this something that would have to be done before they are redirected to PayPal for checkout.
I'm thinking a work-around could be something like, upon clicking on the add to cart button, client is prompted whether they are tax exempt or not. If they say that they are, we would remove the sales tax for that product and they would then proceed with checkout through paypal. After the transaction is made I would check to confirm that we actually have a record for that client, if not, we would notify them via email saying that we do not have a record and that sales tax would be added.
Could someone give me some advice here, I have not been able to find anything related to paypal and tax exemption of this nature and I'm just wondering if their is a way to handle this through paypal or if my work-around will do the trick?
Here is code for on add to cart button click
Dim ppHref As StringBuilder = New StringBuilder()
ppHref.Append("https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_cart")
ppHref.Append("&business=" + business)
ppHref.Append("&item_name=" + itemName)
ppHref.Append("&item_number=" + itemNumber)
ppHref.Append("&amount=" + itemAmount)
ppHref.Append("&currency_code=" + currencyCode)
ppHref.Append("&add=" + addItem.ToString("#0"))
Response.Redirect(ppHref.ToString(), True)
Dim ReturnQaunity As String = itemAmount
GetRouteUrl("/v1/payments/orders/<Order-Id>")
And here is the code where I am trying to start getting details back from the transaction
Dim strSandbox As String = "https://www.sandbox.paypal.com/cgi-bin/webscr"
Dim strLive As String = "https://www.paypal.com/cgi-bin/webscr"
Dim req As HttpWebRequest = CType(WebRequest.Create(strSandbox), HttpWebRequest)
'Dim Param() As Byte = Request.BinaryRead(HttpContext.Current.Request.ContentLength)
'Dim strRequest2 As String = Encoding.ASCII.GetString(Param)
'strRequest2 = strRequest2 + "&cmd=_notify-validate&"
'Dim req1 As HttpWebRequest = CType(WebRequest.Create(strSandbox), HttpWebRequest)
'Set values for the request back
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
req.ContentLength = strRequest.Length
'Send the request to PayPal and get the response
Dim streamOut As StreamWriter = New StreamWriter(req.GetRequestStream(), Encoding.ASCII)
streamOut.Write(strRequest)
streamOut.Close()
Dim streamIn As StreamReader = New StreamReader(req.GetResponse().GetResponseStream())
Dim strResponse As String = streamIn.ReadToEnd()
streamIn.Close()
If Not String.IsNullOrEmpty(strResponse) Then
Dim results As New Dictionary(Of String, String)
Dim reader As New StringReader(strResponse)
Dim line As String = reader.ReadLine()
If line = "Success" Then
While True
Dim aLine As String
aLine = reader.ReadLine
If aLine IsNot Nothing Then
Dim strArr() As String
strArr = aLine.Split("=")
results.Add(strArr(0), strArr(1))
Else
Exit While
End If
End While
This code works fine for all PDT variables however I am also stuck on how to make the api calls where I can recieve PayerID and all the api variables listed in paypal. Would you be able to help me with that? How to make an API call to paypal in vb.net? or at least what I need in order to make an api call?

PayPal IPN notify-validate is returning sandbox login HTML for ASP.NET

Overview of problem:
I have implemented the IPN listener and I know that PayPal is directing to it (because of a generated text file), the correct parameters are sent through to me in the QueryString however when I append "&cmd=notify-validate" to the query string for the validation to take place and send it to PayPal, I get the following HTML response:
.
When I copy and paste that returned HTML into a blank HTML document I see the following:
Initially I thought my session had expired but when I accessed the Sandbox via my browser, I was automatically logged in. I have even tried clicking on the link in my html document to ensure I am logged in and tried processing another test IPN through the simulator in the sandbox but I keep getting this result. I just can't see what I am doing wrong and the sad thing is that it was working correctly about an hour ago :(
My IPN listener code to send and get the validation response:
Dim payPalUrl As String = PayPalPayment.PayPalURL 'This returns https://www.sandbox.paypal.com/cgi-bin/webscr
Dim req As HttpWebRequest = CType(WebRequest.Create(payPalUrl), HttpWebRequest)
'Set values for the request back
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
Dim params() As Byte = Request.BinaryRead(Request.ContentLength)
Dim ipnRequest As String = Encoding.ASCII.GetString(params)
Dim ipnPost As String = ipnRequest
ipnRequest &= "&cmd=notify-validate"
req.ContentLength = ipnRequest.Length
myUtility.AuditIPN(filename, ipnRequest)
''for proxy
'Dim proxy As New WebProxy(New System.Uri("http://url:port#"))
'req.Proxy = proxy
'Send the request to PayPal and get the response
Dim streamOut As New StreamWriter(req.GetRequestStream(), Encoding.ASCII)
streamOut.Write(ipnRequest)
streamOut.Close()
Dim streamIn As New StreamReader(req.GetResponse().GetResponseStream())
Dim ipnResponse = streamIn.ReadToEnd()
streamIn.Close()
'Rest of the code here... not necessary for this problem
Posting the payment to PayPal (if needed). NOTE: I build the form and Response.Write() it in a page. This is the form generation:
Dim form As New StringBuilder
form.AppendLine("<!DOCTYPE html>")
form.AppendLine("<html xmlns=""http://www.w3.org/1999/xhtml"">")
form.AppendLine("<head runat=""server"">")
form.AppendLine(String.Format("<title>{0} {1}</title>", "PayPal payment for", ItemName))
form.AppendLine("<link href=""../css/paypal.css"" rel=""stylesheet"" />")
form.AppendLine("</head>")
form.AppendLine("<body>")
form.AppendLine("<div class=""paypal""></div>")
form.AppendLine(String.Format("<p>Accessing PayPal to process your payment for the {0}.</p>", ItemName))
form.AppendLine("<div class=""loading""></div>")
form.AppendLine("<form id=""myform"" action=""https://www.sandbox.paypal.com/cgi-bin/webscr"" method=""post"">")
form.AppendLine("<input type=""hidden"" name=""cmd"" value=""_xclick"">")
form.AppendLine(String.Format("<input type=""hidden"" name=""business"" value=""{0}"">", BusinessEmail))
form.AppendLine(String.Format("<input type=""hidden"" name=""item_name"" value=""{0}"">", ItemName))
form.AppendLine(String.Format("<input type=""hidden"" name=""amount"" value=""{0}"">", Amount))
form.AppendLine(String.Format("<input type=""hidden"" name=""currency_code"" value=""{0}"">", Currency))
form.AppendLine(String.Format("<input type=""hidden"" name=""return"" value=""{0}"">", ReturnURL))
form.AppendLine("<input type=""hidden"" name=""button_subtype"" value=""products"">")
form.AppendLine("<input type=""hidden"" name=""bn"" value=""HHMRKWQT8NRTW:PP-BuyNowBF_P"">")
form.AppendLine("<input type=""hidden"" name=""no_note"" value=""0"">")
form.AppendLine("</form>")
form.AppendLine("<script type=""text/javascript"">")
form.AppendLine(" document.forms[""myform""].submit();")
form.AppendLine("</script>")
return form.ToString()
If I need to post anything else regarding this issue, please let me know as my brain is completely fried at the moment.
Your time and help will greatly be appreciated!
NOTE: Although my code is in VB.NET I develop in C# too, so C# sample code will definitely not be frowned upon!
Answer:
If you receive HTML in return, then the notify-validate is not correctly sent through to PayPal. It needs to be &cmd=_notify-validate (with the underscore directly after the cmd key) I must have somehow identically deleted it in my hazy stupor. My IPN listener is now successfully returning VERIFIED :)
If you receive HTML in return, then the notify-validate is not correctly sent through to PayPal. It needs to be &cmd=_notify-validate (with the underscore directly after the cmd key) I must have somehow accidentally deleted it in my hazy stupor. My IPN listener is now successfully returning VERIFIED :)

Resources