|
Back

Using HSBC Card Payment Interface with C# and ASP.net
So you've written your ASP.net application/web site and now it needs integrating with the HSBC card payment interface in order to collect payments from customers. So you think HSBC, they're a big organisation, so they'll have some good documentation in a variety of all the most common web languages and be able to help out loads? Welcome to the world of pain! You only have to look at how other payment providers, such as Protx, which provide a really good service with loads of examples and help, to see what a poor offering HSBC make - scant documentation, no examples in the main web languages such as PHP and ASP.net, and poor support lines. And the error messages returned by the HSBC servers and just so vague. Look at all the forums out there, you won't find much positive to say about HSBC!
In order to talk to the HSBC service you must create create an "OrderHash" - HSBC provide examples of how you do this using asp but not how to do it in .net.
The sample code below shows you how to create this orderhash code in ASP.net using C#. Basically it uses late binding to the orderhash COM object (this sample uses the COM rather than Java or C versions.) You need to register the COM object using regsvr32 on the server you are using - another problem since alot of web hosts won't allow you to do that.
The example below shows you one way you can perform the HSBC integration using ASP.net, version 2005 of Visual Studio. You can download the source code here. If you have any problems with it please let me know.
1: The shopping page
In my example I have a very basic dummy shopping page called default.aspx in the example files. All this stores is the amount to be paid, the user's name and address, a unique id for the user and an unique id for the transaction.
When a user clicks on submit it passes the values entered into the form onto another page (which does the HSBC integration, more about this in a minute) user Server.Transfer using the code below. Prior to doing this server transfer you need to store all the information about your order and the customer in your database.
StringBuilder transferVars = new StringBuilder();
transferVars.Append("?OrderId=" + Server.UrlEncode(txtOrderId.Text));
transferVars.Append("&PurchaseAmount=" + Server.UrlEncode(txtPurchaseAmount.Text));
transferVars.Append("&UserId=" + Server.UrlEncode(txtUserId.Text));
transferVars.Append("&BillingFirstName=" + Server.UrlEncode(txtFirstName.Text));
transferVars.Append("&BillingLastName=" + Server.UrlEncode(txtLastName.Text));
transferVars.Append("&ShopperEmail=" + Server.UrlEncode(txtEmailAddress.Text));
transferVars.Append("&BillingAddress1=" + Server.UrlEncode(txtAddress1.Text));
transferVars.Append("&BillingAddress2=" + Server.UrlEncode(txtAddress2.Text));
transferVars.Append("&BillingCity=" + Server.UrlEncode(txtTownCity.Text));
transferVars.Append("&BillingCounty=" + Server.UrlEncode(txtCounty.Text));
transferVars.Append("&BillingPostal=" + Server.UrlEncode(txtPostCode.Text));
//originally used server transfer - doesn't work in ajax pages though
Server.Transfer("HSBCIntegrate.aspx" + transferVars.ToString());
I chose to use Server.Transfer over Response.Redirect to ensure the user cannot see in the address bar what is being passed over to the HSBC integration page.
2: The HSBC Integration Page
The HSBC integration page is a form configured in the way HSBC like it, which POSTs its data to the HSBC servers. I hid the contents of the form use CSS style="visibility:hidden". The form uses a javascript call which automatically submits itself when the page loads.
<body onload="document.form1.action='https://www.uat.cpi.netq.hsbc.com/servlet';document.form1.submit();" >
<h1>HSBC Integrate</h1><p>Redirecting to payment provider... Please wait...</p>
<form method="post" action="https://www.uat.cpi.netq.hsbc.com/servlet" id="form1" runat="server">
<div style="visibility:hidden;">
<asp:TextBox ID="OrderHash" runat="server"></asp:TextBox><br />
<asp:TextBox ID="CpiReturnUrl" runat="server"></asp:TextBox><br />
<asp:TextBox ID="OrderId" runat="server"></asp:TextBox><br />
<asp:TextBox ID="StorefrontId" runat="server"></asp:TextBox><br />
<asp:TextBox ID="TimeStamp" runat="server"></asp:TextBox><br />
<asp:TextBox ID="OrderDesc" runat="server"></asp:TextBox><br />
<asp:TextBox ID="PurchaseAmount" runat="server"></asp:TextBox><br />
<asp:TextBox ID="PurchaseCurrency" runat="server"></asp:TextBox><br />
<asp:TextBox ID="CpiDirectResultUrl" runat="server"></asp:TextBox><br />
<asp:TextBox ID="TransactionType" runat="server"></asp:TextBox><br />
<asp:TextBox ID="UserId" runat="server"></asp:TextBox><br />
<asp:TextBox ID="Mode" runat="server"></asp:TextBox><br />
<asp:TextBox ID="BillingFirstName" runat="server"></asp:TextBox><br />
<asp:TextBox ID="BillingLastName" runat="server"></asp:TextBox><br />
<asp:TextBox ID="ShopperEmail" runat="server"></asp:TextBox><br />
<asp:TextBox ID="BillingAddress1" runat="server"></asp:TextBox><br />
<asp:TextBox ID="BillingAddress2" runat="server"></asp:TextBox><br />
<asp:TextBox ID="BillingCity" runat="server"></asp:TextBox><br />
<asp:TextBox ID="BillingCounty" runat="server"></asp:TextBox><br />
<asp:TextBox ID="BillingPostal" runat="server"></asp:TextBox><br />
<asp:TextBox ID="BillingCountry" runat="server"></asp:TextBox><br />
<asp:TextBox ID="ShippingFirstName" runat="server"></asp:TextBox><br />
<asp:TextBox ID="ShippingLastName" runat="server"></asp:TextBox><br />
<asp:TextBox ID="ShippingAddress1" runat="server"></asp:TextBox><br />
<asp:TextBox ID="ShippingAddress2" runat="server"></asp:TextBox><br />
<asp:TextBox ID="ShippingCity" runat="server"></asp:TextBox><br />
<asp:TextBox ID="ShippingCounty" runat="server"></asp:TextBox><br />
<asp:TextBox ID="ShippingPostal" runat="server"></asp:TextBox><br />
<asp:TextBox ID="ShippingCountry" runat="server"></asp:TextBox><br />
</div>
</form>
</body>
In the code behind is the bit that takes the data from the shopper page and loads it into the order hash to send on to HSBC.
I've highlighted the important bit, ie the part that creates the OrderHash on your local machine, in red.
In the example below I set up lots of variables for all the information that needs to go into the orderhash. Some of it is picked up from the Server.Transfer from the previous page, some is static data.
using System.Reflection;
protected void Page_Load(object sender, EventArgs e)
{
// ps in the HSBCIntegrate.aspx you need to change the posted url
// https://www.uat.cpi.netq.hsbc.com/servlet - test server
// https://www.cpi.hsbc.com/servlet - live server
string orderId, timestamp, cpiReturnUrl, cpiDirectResultUrl, storefrontId;
string orderDesc, purchaseCurrency, transactionType, userId, mode, purchaseAmount;
string billingFirstName, billingLastName, shopperEmail, billingAddress1, billingAddress2, billingCity, billingCounty, billingPostal, billingCountry;
string shippingFirstName, shippingLastName, shippingAddress1, shippingAddress2, shippingCity, shippingCounty, shippingPostal, shippingCountry;
orderId = Server.UrlDecode(Request.QueryString["OrderId"]);// a unique order id
purchaseAmount = Server.UrlDecode(Request.QueryString["PurchaseAmount"]);
userId = Request.QueryString["UserId"];// the customer id
billingFirstName = Server.UrlDecode(Request.QueryString["BillingFirstName"]);
billingLastName = Server.UrlDecode(Request.QueryString["BillingLastName"]);
shopperEmail = Server.UrlDecode(Request.QueryString["ShopperEmail"]);
billingAddress1 = Server.UrlDecode(Request.QueryString["BillingAddress1"]);
billingAddress2 = Server.UrlDecode(Request.QueryString["BillingAddress2"]);
billingCity = Server.UrlDecode(Request.QueryString["BillingCity"]);
billingCounty = Server.UrlDecode(Request.QueryString["BillingCounty"]);
billingPostal = Server.UrlDecode(Request.QueryString["BillingPostal"]);
billingCountry = "826";//826 = uk
// no shipping
shippingFirstName = billingFirstName;
shippingLastName = billingLastName;
shippingAddress1 = billingAddress1;
shippingAddress2 = billingAddress2;
shippingCity = billingCity;
shippingCounty = billingCounty;
shippingPostal = billingPostal;
shippingCountry = billingCountry;
timestamp = ConvertToUnixTimestamp(DateTime.Now.ToUniversalTime()).ToString();
cpiReturnUrl = "https://www.yoursite.com/PaymentResponseUser.aspx";//must be https address - displayed to the user after the tranasction
cpiDirectResultUrl = "https://www.yoursite.com/PaymentResponse.aspx";//must be https address - returns the result to your web app
storefrontId = ConfigurationManager.AppSettings["HSBCStoreFrontId"];
orderDesc = "Some Merchandise";
purchaseCurrency = "826";// 826 represents uk
transactionType = "Capture";// ie goods that don't need to be physically shipped
mode = "T";// test mode - P for production
//merchantData = ;// skip - its optional
// create the order hash
Type myType = Type.GetTypeFromProgID("CcCpiCOM.OrderHash");
object myObject = Activator.CreateInstance(myType);
object[] array = new Object[] { cpiReturnUrl, orderId, storefrontId,
timestamp,orderDesc,purchaseAmount,purchaseCurrency,cpiDirectResultUrl,transactionType,
userId,mode,billingFirstName, billingLastName, shopperEmail, billingAddress1, billingAddress2, billingCity,
billingCounty, billingPostal, billingCountry, shippingFirstName, shippingLastName, shippingAddress1,
shippingAddress2, shippingCity, shippingCounty, shippingPostal, shippingCountry};
object[] oParms = new Object[] { array, ConfigurationManager.AppSettings["HSBCOrderHash"] };
string orderHash = (string)myType.InvokeMember("GenerateOrderHash", BindingFlags.InvokeMethod, null, myObject, oParms);
OrderHash.Text = orderHash;
// Populate the values to the form, so they can be posted to HSBC
CpiReturnUrl.Text = cpiReturnUrl;
OrderId.Text = orderId;
StorefrontId.Text = storefrontId;
TimeStamp.Text = timestamp;
OrderDesc.Text = orderDesc;
PurchaseAmount.Text = purchaseAmount;
PurchaseCurrency.Text = purchaseCurrency;
CpiDirectResultUrl.Text = cpiDirectResultUrl;
TransactionType.Text = transactionType;
UserId.Text = userId;
Mode.Text = mode;
BillingFirstName.Text = billingFirstName;
BillingLastName.Text = billingLastName;
ShopperEmail.Text = shopperEmail;
BillingAddress1.Text = billingAddress1;
BillingAddress2.Text = billingAddress2;
BillingCity.Text = billingCity;
BillingCounty.Text = billingCounty;
BillingPostal.Text = billingPostal;
BillingCountry.Text = billingCountry;
ShippingFirstName.Text = shippingFirstName;
ShippingLastName.Text = shippingLastName;
ShippingAddress1.Text = shippingAddress1;
ShippingAddress2.Text = shippingAddress2;
ShippingCity.Text = shippingCity;
ShippingCounty.Text = shippingCounty;
ShippingPostal.Text = shippingPostal;
ShippingCountry.Text = shippingCountry;
}
private double ConvertToUnixTimestamp(DateTime date)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
TimeSpan diff = date - origin;
return Math.Floor(diff.TotalMilliseconds);
}
You need to put your orderhash and store front id in the web.config file for it to work.
Sorry my descriptions are a bit brief, I'm just a bit too busy to write something in detail. But let me know how you get on.
Back
|