Introduction
I've recently completed a project where the client wanted to allow users to buy product from his website and pay through PayPal. This was the second time I've done this and both times, it was a maddening to thing to achieve.
PayPal seems to have quite a learning curve and I felt like I was trying to find a needle in a haystack, in the dark while working on this. Needless to say, Google was invaluable here.
In this article, I'll cover linking a PayPal "Buy Now" button in your code, providing a way for the user to make payment for the product online and how you can update your database to reflect the payment once made.
Background
I'm not saying that this is how it should be done; just that it's how I did it.
We'll be using a WebClient to create a NameValueCollection that will contain the form values that PayPal needs in order to process the payment. Basically all this is, is just telling PayPal what we're trying to do, what product we're trying to do it with, and what it should do once we're done.
Once the payment is processed successfully on PayPal, we'll update our database record by using PayPal's IPN (Immediate Payment Notification) facility. Doing this is as simple as just adding a name/value pair to the data we'll be sending when the user clicks on the button.
Using the code
So all we're going to do is use an ImageButton for the user to click. The click will link into our RemotePost class and build the data to be sent.
Once the button is created in PayPal, the HTML code for the form that will do the work is generated for you. This is where you'll find the name/value pairs that we'll be sending. For faster reference, they are:
hosted_button_id=7H5976DT3M
(this is an ID generated by PayPal to identify your product)
cmd=xclick
(this tells PayPal what happened)
notify_url=http://www.this.com/PayPalIPN.ashx
The notify_url
value is a path to an HttpHandler that you'll have on your website. It's also where we'll be putting the code that you'll update your database with.
RemotePost builds up the WebClient that will actually send the data to PayPal
protected void btnPayPal_Click(Object sender, ImageClickEventArgs e)
{
string hosted_button_id = "7H5976DT";
using (RemotePost rp = new RemotePost())
{
rp.URL = "https://www.paypal.com/cgi-bin/webscr";
rp.AddInput("cmd", "_s-xclick);
rp.AddInput("hosted_button_id", hosted_button_id);
rp.AddInput("notify_url", "http: rp.AddInput("custom", Session["userid"]);
rp.Post();
}
}
That's about it for the button's code, now on to the RemotePost class we talked about...
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
public class RemotePost : IDisposable
{
private NameValueCollection Inputs = new NameValueCollection();
public string URL { get; set; }
private string Method = "post";
public void AddInput(string Name, string Value)
{
Inputs.Add(Name, Value);
}
public void Post()
{
WebClient client = new WebClient();
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
client.UploadValues(URL, Method, Inputs);
var responseArray = client.UploadValues(URL, Method, Inputs);
var response = Encoding.ASCII.GetString(responseArray);
}
public void Dispose()
{
Inputs.Clear();
URL = "";
}
}
Now for the last piece of the puzzle - the IPN Handler to update our database:
public void ProcessRequest (HttpContext context)
{
if (context.Request.Params("custom"))
{
updateUser(context.Request.Params("custom"));
}
}
private void updateUser(int UserID)
{
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.
ConnectionStrings["HerpDerpConnectionString"].ConnectionString);
string sql = "update users set paymentmade = 1 where userid = @userid";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@userid", userid);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
Response.Redirect("http://www.this.com/");
}
So basically what's happening here is that the payment has been made successfully and, because we added notify_url=http://www.this.com/PayPalIPN.ashx
to our post, when PayPal completed the transaction, it sent the post data to this HttpHandler. The handler then, in turn, updates the user's record in the database to reflect that payment has, in fact, been made.
Conclusion
I hope this was clear enough. It certainly took me a while to get everything sorted out. Thanks for reading and feel free to share your ideas on this in the comments.