Hey Guys,
I am trying to set up a site so that the client can hit a buy now button and go to paypal. Then they do their thing and Paypal sends my web service the IPN. At this point my web service will proccess what needs to happen either way and then confirm with paypal that it recieved the IPN and processed it. I have actually done this before for another company but alas that was awhile ago and I cannot remember how I did it.
Before you send me to the generic links please know that I have looked them all over already. I would not be posting here if I had not. I found the following code which I thought might help (this is converted from c# into VB which is what I am using):
Code:'Now time to send the information off to paypal
Dim Action As Uri = New Uri("https://www.sandbox.paypal.com/cgi-bin/webscr") 'Testing: https://www.sandbox.paypal.com/cgi-bin/webscr , Live: https://www.paypal.com/us/cgi-bin/webscr
Dim Req As HttpWebRequest = CType(WebRequest.Create(Action), HttpWebRequest)
Dim Proxy As String = Nothing
Dim Data As String = "business={" & Business & "}&item_name={" & ItemName & "}¤cy_code={" & Currency & "}&amount={" & Amount & "}¬ify_url={" & NotifyURL & "}&return={" & ReturnURL & "}&cancel_return={" & CancelURL & "}&email={" & ClientEmail & "}&first_name={" & ClientFname & "}&last_name={" & ClientLname & "}&address1={" & ClientAddress & "}&city={" & ClientCity & "}&quantity={1}&no_shipping={1}&custom={" & SiteID & "}&cmd=_notify-validate"
Dim Buffer As Byte() = Encoding.UTF8.GetBytes(Data)
Req.Method = "POST"
Req.ContentType = "application/x-www-form-urlencoded"
Req.ContentLength = Buffer.Length
Req.Proxy = New WebProxy(Proxy, True) 'ignore for local addresses
Req.CookieContainer = New CookieContainer() 'enable cookies
Dim reqst As Stream = Req.GetRequestStream() 'add form data to request stream
reqst.Write(Buffer, 0, Buffer.Length)
reqst.Flush()
reqst.Close()
Dim Res As HttpWebResponse = Req.GetResponse()
Dim resst As Stream = Res.GetResponseStream()
Dim sr As StreamReader = New StreamReader(resst)
Dim response As String = sr.ReadToEnd()
My thinking was that When they hit their submit button and I process a bunch of things that need to happen I can just programatically send the info to paypal behind the scenes but my boss pointed out the fact that clients will need to actually visit the paypal site to do the transaction. That being the case I can easily send the client to a new page just before this happens (and then I can just insert the variables in the Data string into appropriate hidden variables instead?) and have the user hit the buy now button.
*side question*: will paypal recognize ASP.net hidden variables? ASP changes the ids you give controls by the time they reach html so I'm wondering if that would screw up the post variables for paypal.
Anyway the code above looks like its also retrieving the response, which is not what I want to happen. I would like my web service to recieve the IPN so I can have the code in 1 place. The examples I found (such as the one below) seem to be just regular ASP.net pages with an on load method that takes care of this. I want this functionality in a web service so what do I name the method to insure that paypal calls it? here is what I've found:
Code:Imports System.Net
Imports System.IO
Imports System.Text
Imports System.Web.Mail
Imports System.Collections.Specialized
Public Class SB_IPN
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
'Read in IPN POST
Dim strFormValues As String = Encoding.ASCII.GetString(Request.BinaryRead(Request.ContentLength))
Dim strNewValue
' Create the request back
Dim req As HttpWebRequest = CType(WebRequest.Create("https://www.sandbox.paypal.com/cgi-bin/webscr"), _
HttpWebRequest)
' Set values for the request back
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
strNewValue = strFormValues + "&cmd=_notify-validate"
req.ContentLength = strNewValue.Length
' Write the request back IPN strings
Dim stOut As StreamWriter = New StreamWriter(req.GetRequestStream(), _
Encoding.ASCII)
stOut.Write(strNewValue)
stOut.Close()
'send the request, read the response
Dim strResponse As HttpWebResponse = CType(req.GetResponse(), HttpWebResponse)
Dim IPNResponseStream As Stream = strResponse.GetResponseStream
Dim encode As Encoding = System.Text.Encoding.GetEncoding("utf-8")
Dim readStream As New StreamReader(IPNResponseStream, encode)
Dim read(256) As [Char]
' Reads 256 characters at a time.
Dim count As Integer = readStream.Read(read, 0, 256)
While count > 0
' Dumps the 256 characters to a string and displays the string to the console.
Dim IPNResponse As New [String](read, 0, count)
count = readStream.Read(read, 0, 256)
' if IPN response was VERIFIED..perform VERIFIED handling
'for this example - send email of raw IPN string
If IPNResponse = "VERIFIED" Then
'Do processing for valid transactions
Else
' if IPN is INVALID
'log and manually investigate
End If
End While
'tidy up, close streams
readStream.Close()
strResponse.Close()
'for debug
'Response.Write("Script ran, check your email")
End Sub
End Class
And here is what I have so Far:
Code:Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Net
Imports System.IO
Imports System.Text
Imports System.Web.Mail
Imports System.Collections.Specialized
' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
' <System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class PayPal
Inherits System.Web.Services.WebService
<WebMethod()> _
Private Sub PaymentMade()
'Put user code to initialize the page here
'Read in IPN POST
Dim strFormValues As String = Encoding.ASCII.GetString(Request.BinaryRead(Request.ContentLength))
Dim strNewValue
' Create the request back
Dim req As HttpWebRequest = CType(WebRequest.Create("https://www.sandbox.paypal.com/cgi-bin/webscr"), HttpWebRequest)
' Set values for the request back
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"
strNewValue = strFormValues + "&cmd=_notify-validate"
req.ContentLength = strNewValue.Length
' Write the request back IPN strings
Dim stOut As StreamWriter = New StreamWriter(req.GetRequestStream(), Encoding.ASCII)
stOut.Write(strNewValue)
stOut.Close()
'send the request, read the response
Dim strResponse As HttpWebResponse = CType(req.GetResponse(), HttpWebResponse)
Dim IPNResponseStream As Stream = strResponse.GetResponseStream
Dim encode As Encoding = System.Text.Encoding.GetEncoding("utf-8")
Dim readStream As New StreamReader(IPNResponseStream, encode)
Dim read(256) As [Char]
' Reads 256 characters at a time.
Dim count As Integer = readStream.Read(read, 0, 256)
While count > 0
' Dumps the 256 characters to a string and displays the string to the console.
Dim IPNResponse As New [String](read, 0, count)
count = readStream.Read(read, 0, 256)
' if IPN response was VERIFIED..perform VERIFIED handling
If IPNResponse = "VERIFIED" Then
'IPN was valid so finish processing the order
Else
' if IPN is INVALID
'log and manually investigate
End If
End While
'tidy up, close streams
readStream.Close()
strResponse.Close()
'for debug
'Response.Write("Script ran, check your email")
End Sub
End Class
To add 1 more level of complexity to this I have to implement Recurring Payments. How will this change the traditional flow of this process? Thanks in advance for any assistance.