Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Create a Modern Extension to Your Online Business with a Public API : Page 2

More and more online retailers and other technology companies are finding ways to market and extend their businesses using Web services. Don't let the boat pass you by. Learn how to create a simple API to launch your own affiliate network.

Constructing an Affiliate Sign Up Service
You need to set up your Web site to host the affiliate sign-up service and the associated Web forms to facilitate sign up. This is where you invite potential affiliates to sign up, get an affiliate ID, and start trading using your Web services-based API. To create the database, you can use the SQL scripts that are available in the download.

You'll need some code that takes data in and writes it to the database, getting an automatically generated ID back from SQL Server. This code is shown below. The workspace also contains the definition for a class called AffiliateClass, which encapsulates the data for an affiliate. In the code below, an instance of this class called affThis is used.

int nReturn = 0; sqlConnection2.Open(); sqlInsertCommand1.Parameters["@Name"].Value=affThis.UserName; sqlInsertCommand1.Parameters["@Description"].Value= affThis.UserDescription; sqlInsertCommand1.Parameters["@Address1"].Value=affThis.Address1; sqlInsertCommand1.Parameters["@Address2"].Value=affThis.Address2; sqlInsertCommand1.Parameters["@City"].Value=affThis.City; sqlInsertCommand1.Parameters["@State"].Value=affThis.State; sqlInsertCommand1.Parameters["@Country"].Value=affThis.Country; SqlDataReader r = sqlInsertCommand1.ExecuteReader(); if(r.Read()) nReturn = Convert.ToInt16(r["AffiliateID"].ToString()); else nReturn = 0; sqlConnection2.Close(); return nReturn;

Using Visual Studio.NET it is simple to construct a Web Form that allows the user to enter data and then call the Web service using the entered values. To begin, you have to create a reference to the Web service. In this case, the form, the service, and the database all run on the same development machine. Figure 1 shows how you would add a reference to the Web service that handles the data entry (mentioned above). This generates a Web services proxy that you can use in your Web Form code to pass the data to the Web service.

HostSVC.AffiliateClass affThis = new HostSVC.AffiliateClass(); affThis.UserName = txtName.Text; affThis.UserDescription = txtDescription.Text; affThis.Address1=txtAddress1.Text; affThis.Address2=txtAddress2.Text; affThis.City=txtCity.Text; affThis.Country=txtCountry.Text; affThis.State=txtState.Text; HostSVC.API theAPI = new HostSVC.API(); int nID = theAPI.NewAffiliate(affThis); if(nID==0) { lblStatus.Text = "Update Rejected. Please hit REFRESH and try again"; } else { lblStatus.Text = "Update Successful, your AffiliateID is :" + nID; }

Author's Note: In a production system you should have extensive data validation to prevent SQL injection attacks as well as comprehensive error handling. Both have been omitted in this tutorial for the sake of clarity.

In a production system, you would want to send an email confirmation sent to the affiliate after sign up, but for the sake of brevity, this system just displays the confirmation on screen, along with the new ID that has been assigned to this affiliate.

Constructing a Sales Interface API
Now that your affiliate has an ID, they need to know what they can sell. They do this by calling the Catalog Query Web service, which gives them a list of all products currently in stock (Quantity > 0). You could make this a little more sophisticated by breaking your products down into different categories and building the API accept a category parameter. For the sake of simplicity, that is omitted here, and all products that are in stock are returned.

The Web Method below returns all the current inventory:

string strConnectionString = "integrated security=SSPI; data source=(local);persist security info=True; initial catalog=AffilliatePOC"; SqlConnection con = new SqlConnection(strConnectionString); int nSize = 0; string sql = @"SELECT COUNT(*) from Products Where Quantity>0"; SqlCommand sqlCountProducts = new SqlCommand(sql,con); con.Open(); nSize = Convert.ToInt16(sqlCountProducts.ExecuteScalar().ToString()); ProductClass[] pReturn = new ProductClass[nSize]; int nIndex = 0; sql = "Select * from Products Where Quantity>0"; SqlCommand sqlSelectProducts = new SqlCommand(sql,con); SqlDataReader r = sqlSelectProducts.ExecuteReader(); while(r.Read()) { pReturn[nIndex] = new ProductClass(); pReturn[nIndex].ID = Convert.ToInt16(r["ProductID"]); pReturn[nIndex].Description = r["Description"].ToString(); pReturn[nIndex].ImageURL = r["ImageURL"].ToString(); pReturn[nIndex].Price = Convert.ToInt16(r["Price"]); pReturn[nIndex].Quantity = Convert.ToInt16(r["Quantity"]); pReturn[nIndex].Weight = Convert.ToInt16(r["Weight"]); nIndex++; } con.Close(); return pReturn;

This code uses a ProductClass helper class, which encapsulates the data points associated with a product and is directly analogous to the fields on the Product table in the database.

At this point, your affiliate has to do a little work to consume the service: Using this Web service endpoint, they could use Visual Studio.NET (or equivalent) to generate a proxy to your Web service by adding a Web services reference (see Figure 1). It does this by looking at the WSDL for the Web service and parsing it to get the names of the methods and their signatures (the parameters that they accept and return), and generating C# source code for a class that has the same methods with the same signatures. You can then talk to the proxy class, which talks to the Web service on your behalf.

Figure 1. Picture This: The screenshot shows the dialog in Visual Studio.NET for adding a reference to your Web services API from the affiliate point of view.
They can then build a user interface that consumes this proxy to render the available products. The getProducts() method (as you can see in Figure 1) returns an Array of type ProductClass. You can do whatever you like with this array, but in the download you will see the BuildXML function that creates an XML document out of this array. This XML document is then loaded into a DataSet, which can be bound to a Repeater control.

HostSVC.AffAPI theAPI = new HostSVC.AffAPI(); pList = theAPI.getProducts(); XmlDocument xmlDoc = BuildXML(); DataSet dstVals = RenderData(xmlDoc); Repeater1.DataSource = dstVals; Repeater1.DataBind();

The repeater control is hosted on an ASPX page and generates a table entry for each item in the recordset. In addition, the repeater adds a button control to the table, which allows the user to 'Buy' the item in the table.

The ASP.NET markup is shown here:

<asp:Repeater id="Repeater1" runat="server"> <ItemTemplate> <tr> <td><font face="Verdana" size="2"> <%# DataBinder.Eval(Container.DataItem, "Description") %> </font></td> <td><font face="Verdana" size="2"> <%# DataBinder.Eval(Container.DataItem, "Quantity") %> </font></td> <td> <asp:Button id="Buy" CommandName="BuyIt" runat="server" Text="Buy" /> </td> </tr> </ItemTemplate> </asp:Repeater>

Figure 2 shows an example of the page that would result from calling the API that exposes your product list.

When the user clicks the Buy button, the system needs to check if the item is still in stock (stock levels may have changed since the Catalog Query was run). This is done using the checkStock method on the Web service API, and assuming that the product is still in stock, then the specifics of the order are gathered and passed to the API for realization:

private void Repeater1_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e) { // Hard coding 'my' affiliate ID // In a real system this would be determined differently. int nAffiliateID = 5; int n = e.Item.ItemIndex; int nProductID = pList[n].ID; HostSVC.AffAPI theAPI = new HostSVC.AffAPI(); HostSVC.Customer theCustomer = new HostSVC.Customer(); theCustomer = getCustomerDetails(); if (theAPI.CheckStock(nProductID)) { theAPI.MakePurchase(nAffiliateID,nProductID,theCustomer); } else { // Display some kind of out of stock notification } }

Figure 2. Making a Sale: The ASPX page shown is a simple example of a Web page that consumes the API that exposes your product inventory and allows an end user to make a purchase request.
In a real world scenario, you may have a sign-in screen prior to getting to the purchase, so you'll have your customer details cached. Alternatively, if you don't have any customer details cached, you could direct them to a screen where they have to be entered. In the download, the getCustomerDetails function simulates this by returning a hard-coded customer.

Back on your site, the Web service API has to handle this order request. You should check and charge the customer's credit card before touching the database. In this article, I've assumed you've done that piece; and the next step is to update the database. This involves four steps:

  1. Getting the quantity available for each specific product.
  2. Reducing the quantity by the number purchased (in the example this is hard-coded to '1'), and then updating the inventory database with the new quantity.
  3. Updating the transactions table with the details of the sale, including the affiliate ID, so you can track which affiliate sold what.
  4. Shipping the product to the customer. (In an ideal case this would be a sub-step of step 2, as the inventory shouldn't be reduced until it has shipped.)
The code for this is shown here:

string strConnectionString = "integrated security=SSPI; data source=(local);persist security info=True; initial catalog=AffilliatePOC"; SqlConnection con = new SqlConnection(strConnectionString); // First find out the quantity of product ID string sql = "Select QUANTITY from Products where ProductID=@ID"; SqlCommand sqlCheckQuantity = new SqlCommand(sql,con); sqlCheckQuantity.Parameters.Add("@ID",nProductID); con.Open(); int x=Convert.ToInt16(sqlCheckQuantity.ExecuteScalar()); // Then update the products to 1 less than this int nNewQuantity = x-1; sql = "UPDATE Products Set Quantity=@NewVal WHERE ProductID=@ID"; SqlCommand sqlUpdateQuantity = new SqlCommand(sql,con); sqlUpdateQuantity.Parameters.Add("@ID",nProductID); sqlUpdateQuantity.Parameters.Add("@NewVal",nNewQuantity); sqlUpdateQuantity.ExecuteNonQuery(); // Then insert a new record of this purchase for this affiliate sql = "INSERT INTO TRANS (ProductID, AffiliateID, Quantity) Values(@ProductID, @AffiliateID, 1)"; SqlCommand sqlInsertTrans = new SqlCommand(sql,con); sqlInsertTrans.Parameters.Add("@ProductID", nProductID); sqlInsertTrans.Parameters.Add("@AffiliateID", nAffiliateID); sqlInsertTrans.ExecuteNonQuery(); con.Close();

In a real world scenario you would then construct a shipping order that is passed to your shipping system, and the shipping system would do the reduction at fulfillment. For completeness, I've included it in the method above.

Next Steps
This article has gone over the skeletal details for what it would take to construct an API that wraps the systems of a simple e-commerce store with a Web service, and then exposes that Web service as an API for consumption by affiliates. It also gave a brief example of how an affiliate could construct a branded Web site that consumes your API. To make it a production system, you would need to work from this infrastructure, adding code and functionality that consider how your internal systems work.

Perhaps most importantly you would need to consider how to secure your API against spoofing or tampering. The nice thing about doing it as a Web service is that there are already a number of Web services standards to help you. Steps that you can take are:

  • Obtaining a certificate to publish your Web service on https instead of http.
  • Using WS-Security and WSE 2.0 to encrypt your SOAP messages.
  • Using XML Signature and providing an API to validate that your SOAP messages are coming from a valid affiliate.
In this article I gave you a whirlwind tour for constructing a multi-tier system with a Web services-based API that serves as the back end for an open affiliate sales program. While the sample application takes a number of short cuts for the sake of demonstration, it wouldn't take much to enhance it. In fact, extending this API could be a fun and fascinating process, and one that will pay off in both higher sales and more exposure of your goods and services.

Regardless of how you choose to extend this framework, it is a good demonstration of the issues that you will face when developing multi-tier, loosely coupled systems. With a bit of effort, you can turn your online store into the next Amazon, Paypal or eBay with an army of affiliates doing your marketing for you!

Laurence Moroney is a freelance enterprise architect who specializes in designing and implementing service-oriented applications and environments using .NET, J2EE, or (preferably) both. He has authored books on .NET and Web services security, and more than 30 professional articles. A former Wall Street architect, and security analyst, he also dabbles in journalism, reporting for professional sports. You can find his blog at http://www.philotic.com/blog.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date