ICICI Payment Gateway Integration in ASP.NET C#

ICICI Payment Gateway Integration in ASP.NET C#

Introduction

The purpose of this article is to show how payments processing can be organized to support reliability and security. The article is also aimed at providing you with an example of the development of a simple online payment, in order to demonstrate interaction with the First Data Payment Gateway system. You can use the code in your applications to organize interaction with this system and to process payments. The article is based on the experience of Drake Software Services and the official ICICI Payment Gateway documentation.

Payment Process

The payment process is very simple. A POST form is created with a set of hidden fields that contain information about storename(your merchant-id), currency, chargetotal(amount), language and a button to send the form. When the form is sent, the buyer goes to the First Data ICICI Merchant Services site and finishes the payment process.

Using the Code

A code of the simplest form in request.aspx

            <form method="post"  runat="server">
                        <div>
                            <label>Name<span class="text-red">*</span> </label>
                        <div>
                                <asp:TextBox id="Name" runat="server" name="billing_name" type="text"/>
                        </div>
                        </div>

                        <div>
                            <label>Mobile No<span class="text-red">*</span> </label>
                        <div>
                                <asp:TextBox runat="server" ID="MobileNo" name="billing_tel" type="number"/>
                        </div>
                        </div>

                        <div>
                            <label>Email ID<span class="text-red">*</span></label>
                        <div>
                                <asp:TextBox ID="EmailID" name="billing_email" type="email" runat="server" />
                        </div>
                        </div>

                        <div>
                            <label>Address <span class="text-red">*</span></label>
                        <div>
                                <asp:TextBox TextMode="multiline" runat="server" ID="Address" name="billing_address" Rows="2" />
                        </div>
                        </div>

                        <div>
                            <label>Zip code <span class="text-red">*</span></label>
                        <div>
                                <asp:TextBox runat="server" ID="ZipCode" name="billing_zip"/>
                        </div>
                        </div>

                        <div>
                        <label>Country <span class="text-red">*</span></label>
                        <div>
                                <asp:TextBox runat="server" ID="Country" name="billing_city" type="text" />                            
                        </div>
                        </div>  
                        
                        <div>
                        <label>State <span class="text-red">*</span></label>
                        <div>
                                <asp:TextBox runat="server" ID="State" name="billing_city" type="text" />                            
                        </div>
                        </div>   

                        <div>
                        <label>City <span class="text-red">*</span></label>
                        <div>
                                <asp:TextBox runat="server" ID="City" name="billing_city" type="text" />                            
                        </div>
                        </div>                  
                   
                        <div>
                        <label>Amount<span class="text-red">*</span> </label>
                        <div>
                                <asp:TextBox runat="server" ID="chargetotal" name="amount" type="number" />
                        </div>
                        </div>
                        <div>
                        <label>Currency <span class="text-red">*</span> </label>
                        <div>
                                <asp:DropDownList runat="server" name="CurrencyId" ID="currencycode" >
                                <asp:ListItem ></asp:ListItem>
                                <asp:ListItem Value="896">GBP</asp:ListItem>
                                <asp:ListItem Value="356">INR</asp:ListItem>                                
                                </asp:DropDownList>
                        </div>
                        </div> 
                        <div>
                            <div>
                                <input ID="btnSend" runat="server" Text="Submit" onclick="btnSend_Click">
                            </div>
                        </div>
                </form>

                <asp:Literal ID="ltrForm" runat="server" Mode="PassThrough"></asp:Literal>
                <asp:Literal ID="ltrScript" runat="server" Mode="PassThrough"></asp:Literal>

C# Code

Sending request to server in request.aspx.cs

            protected void btnSend_Click(object sender, EventArgs e)
            {   
                
                Session["name"] = Name.Text;
                Session["mobileno"] = MobileNo.Text;
                Session["emailid"] = EmailID.Text;
                Session["address"] = Address.Text;
                Session["zipcode"] = ZipCode.Text;
                Session["city"] = City.Text;
                Session["state"] = State.text;
                Session["country"] = Country.Text;
                Session["chargetotal"] = chargetotal.Text;
                Session["remarks"] = Remarks.Text;
                Session["currencycode"] = currencycode.SelectedValue; //values stored in session to save/show it later.

                string formCode = 
                            "<form id=\"{0}\" name=\"{0}\" method=\"post\" action=\"{1}\">" +
                             "<input type=\"hidden\" name=\"txntype\" value=\"sale\">" +
                             "<input type=\"hidden\" name=\"timezone\" value=\"IST\"/>" +
                             "<input type=\"hidden\" name=\"txndatetime\" value=\"{2}\"/>" +
                             "<input type=\"hidden\" name=\"hash\" value=\"{3}\"/>" +
                             "<input type=\"hidden\" name=\"storename\" value=\"{4}\" />" +
                             "<input type=\"hidden\" name=\"mode\" value=\"payonly\"/>" +
                             "<input type=\"hidden\" name=\"currency\" value=\"{5}\" />" +
                             "<input type=\"hidden\" name=\"chargetotal\" value=\"{6}\"/>" +
                             "<input type=\"hidden\" name=\"language\" value=\"en_EN\"/>" +
                             "<input type=\"hidden\" name=\"authenticateTransaction\" value=\"true\"/>" +
                             "<input type=\"hidden\" name=\"responseFailURL\" value=\"http://192.168.xx.x:80/projectname/response_fail.aspx\"/>" + //need to change as per merchant ip/url
                             "<input type=\"hidden\" name=\"responseSuccessURL\" value=\"http://192.168.xx.x:80/projectname/response_success.aspx\"/>" + //need to change as per merchant ip/url
                             "</form>";
    
                string formScript = "<script language=\"javascript\" type=\"text/javascript\">" +
                               "document.getElementById('{0}').submit();" +
                               "</script>";
    
                string formName = "form1";
                string formAction = "https://www4.ipg-online.com/connect/gateway/processing";
                string storename = this.storename.Text;
                string txndatetime = DateTime.Now.ToString(@"yyyy\:MM\:dd-HH\:mm\:ss");
                string chargetotal = this.chargetotal.Text;
                string sharedsecret = "your shared secret value"
                string currency = this.currency.SelectedValue.ToString();
                string data = storename + txndatetime + chargetotal + currency + sharedsecret;
                string hash = calculateHashFromString(new StringBuilder(data), "SHA1");
                ltrForm.Text = string.Format(formCode, formName, formAction, txndatetime, hash, storename, currency, chargetotal);
                ltrScript.Text = string.Format(formScript, formName);
            }

When the form is submitted, all the hidden set of hidden fields that contain information about storename(unique merchant-id), currency, chargetotal(amount),language, responseFailURL, responseSuccessURL are concatenated in a string formCode. Here formAction is where the user is redirected to the payment gateway to complete the transaction process, Where in storename you have to insert your unique merchant-id.

Similarly, In sharedsecret you have to enter your unique sharedsecret value which will be provided by the merchant. On form submission the literals i.e. ltrForm.Text and ltrScript.Text will send the encrypted request via using hash code to the server and user will be redirected to the https://www4.ipg-online.com/connect/gateway/processing.

Description of Parameters-

Parameter Description
txntype Indicates the type of transaction, such as sale or refund.
timezone It refers to the local time of a region or a country.
txndatetime Time and date of transaction.
hash A unique value of fixed size representing a large amount of data.
storename Your unique merchant-id.
mode Item identifier.
currency Payment currency. Eg- INR/CAD/USD.
chargetotal Order amount.
responseFailURL URL provided when transaction fails.
responseSuccessURL URL provided when transaction succeeds.
sharedsecret Unique value given with the storename/merchant-id.

Above table lists the most frequently used parameters. See the Response in response.aspx.cs for the full list of parameters.

Cryptographic hash function

Here function calculateHashFromString uses cryptographic hash function to encrypt the data values. A cryptographic hash function has the property that it is computationally infeasible to find two distinct inputs that hash to the same value. Hash functions are commonly used with digital signatures and for data integrity.

The hash is used as a unique value of fixed size representing a large amount of data. Hashes of two sets of data should match if the corresponding data also matches. Small changes to the data result in large unpredictable changes in the hash.

            public static String calculateHashFromString(StringBuilder stringValue, String hashAlgorithmName)
            {
                HashAlgorithm hashAlgorithm = HashAlgorithm.Create(hashAlgorithmName.Length == 0 ? "SHA1" : hashAlgorithmName);
        
                StringBuilder sb = new StringBuilder();
        
                byte[] stringValueBytes = Encoding.ASCII.GetBytes(stringValue.ToString());
        
                int stringValueBytesLength = stringValueBytes.Length;
        
                for (int i = 0; i < stringValueBytesLength; i++)
                {
                    sb.Append(forDigit((stringValueBytes[i] & 240) >> 4, 16));
                    sb.Append(forDigit((stringValueBytes[i] & 15), 16));
                }
        
                stringValueBytes = Encoding.ASCII.GetBytes((new StringBuilder(sb.ToString()).ToString()));
        
                hashAlgorithm.TransformFinalBlock(stringValueBytes, 0, stringValueBytes.Length);
                byte[] hash = hashAlgorithm.Hash;
                int hashLength = hash.Length;
        
                return BitConverter.ToString(hash).Replace("-", "").ToLower();
            }
  
            private static char forDigit(int digit, int radix)
            {
                int MIN_RADIX = 2, MAX_RADIX = 36;
                if ((digit >= radix) || (digit < 0))
                {
                    return '
            public static String calculateHashFromString(StringBuilder stringValue, String hashAlgorithmName)
            {
                HashAlgorithm hashAlgorithm = HashAlgorithm.Create(hashAlgorithmName.Length == 0 ? "SHA1" : hashAlgorithmName);
        
                StringBuilder sb = new StringBuilder();
        
                byte[] stringValueBytes = Encoding.ASCII.GetBytes(stringValue.ToString());
        
                int stringValueBytesLength = stringValueBytes.Length;
        
                for (int i = 0; i < stringValueBytesLength; i++)
                {
                    sb.Append(forDigit((stringValueBytes[i] & 240) >> 4, 16));
                    sb.Append(forDigit((stringValueBytes[i] & 15), 16));
                }
        
                stringValueBytes = Encoding.ASCII.GetBytes((new StringBuilder(sb.ToString()).ToString()));
        
                hashAlgorithm.TransformFinalBlock(stringValueBytes, 0, stringValueBytes.Length);
                byte[] hash = hashAlgorithm.Hash;
                int hashLength = hash.Length;
        
                return BitConverter.ToString(hash).Replace("-", "").ToLower();
            }
  
            private static char forDigit(int digit, int radix)
            {
                int MIN_RADIX = 2, MAX_RADIX = 36;
                if ((digit >= radix) || (digit < 0))
                {
                    return '\0';
                }
                if ((radix < MIN_RADIX) || (radix > MAX_RADIX))
                {
                    return '\0';
                }
                if (digit < 10)
                {
                    return (char)('0' + digit);
                }
                return (char)('a' - 10 + digit);
            }
'; } if ((radix < MIN_RADIX) || (radix > MAX_RADIX)) { return '
            public static String calculateHashFromString(StringBuilder stringValue, String hashAlgorithmName)
            {
                HashAlgorithm hashAlgorithm = HashAlgorithm.Create(hashAlgorithmName.Length == 0 ? "SHA1" : hashAlgorithmName);
        
                StringBuilder sb = new StringBuilder();
        
                byte[] stringValueBytes = Encoding.ASCII.GetBytes(stringValue.ToString());
        
                int stringValueBytesLength = stringValueBytes.Length;
        
                for (int i = 0; i < stringValueBytesLength; i++)
                {
                    sb.Append(forDigit((stringValueBytes[i] & 240) >> 4, 16));
                    sb.Append(forDigit((stringValueBytes[i] & 15), 16));
                }
        
                stringValueBytes = Encoding.ASCII.GetBytes((new StringBuilder(sb.ToString()).ToString()));
        
                hashAlgorithm.TransformFinalBlock(stringValueBytes, 0, stringValueBytes.Length);
                byte[] hash = hashAlgorithm.Hash;
                int hashLength = hash.Length;
        
                return BitConverter.ToString(hash).Replace("-", "").ToLower();
            }
  
            private static char forDigit(int digit, int radix)
            {
                int MIN_RADIX = 2, MAX_RADIX = 36;
                if ((digit >= radix) || (digit < 0))
                {
                    return '\0';
                }
                if ((radix < MIN_RADIX) || (radix > MAX_RADIX))
                {
                    return '\0';
                }
                if (digit < 10)
                {
                    return (char)('0' + digit);
                }
                return (char)('a' - 10 + digit);
            }
'; } if (digit < 10) { return (char)('0' + digit); } return (char)('a' - 10 + digit); }

Reponse From Server

To store/show information about responses to payment requests, we use the reponse.aspx.cs file having the following structure:

protected void Page_Load(object sender, EventArgs e)
            {
                try
                {
                    ResponseModel obj = new ResponseModel();
                    obj.tId = Request.Form["ipgTransactionId"];
                    obj.approvalCode = Request.Form["approval_code"];
                    obj.txndateprocessed = Request.Form["txndate_processed"];
                    obj.timezone = Request.Form["timezone"];
                    obj.responsehash = Request.Form["response_hash"];
                    obj.failrc = Request.Form["fail_rc"];
                    obj.orderId = Request.Form["oid"];
                    obj.date = Request.Form["tdate"];
                    obj.installmentsinterest = Request.Form["installments_interest"];
                    obj.cccountry = Request.Form["cccountry"];
                    obj.ccbrand = Request.Form["ccbrand"];
                    sId.Text = obj.status = Request.Form["status"];
                    obj.name = billing_name.Text = Session["name"].ToString();
                    obj.tel = billing_tel.Text = Session["mobileno"].ToString();
                    obj.email = billing_email.Text = Session["emailid"].ToString();
                    obj.address = billing_address.Text = Session["address"].ToString();
                    billing_zip.Text = Session["zipcode"].ToString();
                    obj.zip = billing_zip.Text;
                    obj.city = billing_city.Text = Session["city"].ToString();
                    obj.state = billing_state.Text = Session["state"].ToString();
                    obj.country = billing_country.Text = Session["country"].ToString();                    
                    amount.Text = Session["chargetotal"].ToString();
                    obj.amnt = Convert.ToDouble(amount.Text);
        
                    if (Request.Form["currency"] == "356")
                    {
                        currencycode.Text = "INR";
                    }
                    if (Request.Form["currency"] == "896")
                    {
                        currencycode.Text = "GBP";
                    }
                   
                    obj.cur = currencycode.Text;
                    Db(obj); //Saving values in database by passing ReponseModel class } catch { } }

Where…

  • ipgTransactionId is a unique transaction identifier
  • approval_code is boolean for payment approval
  • txndate_processed is the date and time when transaction is performed
  • timezone is the payment amount
  • response_hash is the hash code
  • oid is the order id
  • tdate is the transaction date
  • installments_interest is the interest in installments if there are any
  • name is the buyer’s name
  • mobileno is the buyer’s number
  • emailid is buyer’s email address
  • address is buyer’s address
  • zipcode is buyer’s area zip code
  • city is the buyer’s city
  • state is the buyer’s state/li>
  • country is the buyer’s country
  • currency is the buyer’s currency
  • chargetotal is the payment amount
  • status is the transaction succeeded or failed

 

To get reponse from the server, Request.Form["variable"] is used. It gets a collection of form variables. The Form property is populated when the HTTP request Content-Type value is either “application/x-www-form-urlencoded” or “multipart/form-data”.

Saving the Response in DB Using SQLite

The reponse we got from the server is in the form of model class & it is saved with SQLite database . Generally Models in asp.net are easy to use if we clear with information like where we want to display data or save input data from various domain models then always use model class.

                public void Db(ResponseModel obj)
                {
                    try
                    {
                        string localCon = "Data Source=D:\\localdirectory\\localfolder\\databasename.sqlite;Version=3;";
                        string serverCon = "Data Source=C:\\Inetpub\\vhosts\\domainname\\serverfolder\\databasename.sqlite;Version=3;";
            
                        SQLiteConnection m_dbConnection = new SQLiteConnection(serverCon);
                        m_dbConnection.Open();
            
                        string sql = "select * from ResponseDB";
            
                        SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
                        command.ExecuteNonQuery();
            
                        sql = "insert into ResponseDB (Amount, TransactionId, OrderId, Status, Name, Country, State, City, Address, TransactionDate, ApprovalCode, TransactionDateProcessed, TimeZone, ResponseHash, FailRc, InstallmentIntererst, Currency, Zip, Telephone, Email, CCCountry, CCBrand) values(" +
                                                       obj.amnt + ",'" + obj.tId + "','" + obj.orderId + "','" + obj.status + "','" + obj.name + "','" + obj.country + "','" + obj.state + "','" + obj.city + "','" + obj.address + "','" + obj.date
                                                       + "','" + obj.approvalCode + "','" + obj.txndateprocessed + "','" + obj.timezone + "','" + obj.responsehash + "','" + obj.failrc + "','" + obj.installmentsinterest + "','" + obj.cur + "','" + obj.zip + "','" + obj.tel + "','" + obj.email + "','" + obj.cccountry + "','" + obj.ccbrand + "')";
            
                        command = new SQLiteCommand(sql, m_dbConnection);
                        command.ExecuteNonQuery();
            
                        m_dbConnection.Close();
                    }
                    catch { }
                }

Here, we have two connections both for the local and server. To test it in locally we can use the localCon for testing purposes and similarly we can use the server connection i.e. serverCon when the project is live.

Response Model Class

                public class ResponseModel
                {
                    public string tId { get; set; }
                    public string orderId { get; set; }
                    public double amnt { get; set; }
                    public string status { get; set; }
                    public string name { get; set; }
                    public string country { get; set; }
                    public string state { get; set; }
                    public string city { get; set; }
                    public string address { get; set; }
                    public string date { get; set; }
                    public string cur { get; set; }
                    public string zip { get; set; }
                    public string tel { get; set; }
                    public string email { get; set; }
                    public string approvalCode { get; set; }
                    public string timezone { get; set; }
                    public string responsehash { get; set; }
                    public string failrc { get; set; }
                    public string txndateprocessed { get; set; }
                    public string cccountry { get; set; }
                    public string installmentsinterest { get; set; }
                    public string txndatetime { get; set; }
                    public string fail_reason { get; set; }
                    public string ccbrand { get; set; }
                }

Client-End Code

You can show the response values in the reponse.aspx

        <form runat="server" class="donation-form">
                
                <div>
                <label>Name</label>
                <div>
                <asp:TextBox ID="billing_name" ReadOnly="true" runat="server" data-val="true" name="billing_name" type="text" />
                </div>
                </div>

                <div>
                <label>Mobile No</label>
                <div>
                <asp:TextBox ReadOnly="true" runat="server" data-val="true" ID="billing_tel" name="billing_tel" type="number" value="" />
                </div>
                </div>

                <div>
                <label>Email ID</label>
               
                <div>
                <asp:TextBox ReadOnly="true" ID="billing_email" name="billing_email" type="email" value="" runat="server"  />
                </div>
                </div>

                <div>
                <label>Address</label>
                
                <div>
                <asp:TextBox ReadOnly="true" TextMode="multiline" runat="server" cols="20" ID="billing_address" name="billing_address" Rows="2" />
                </div>
                </div>

                <div>
                <label>Zip code</label>
                <div>
                <asp:TextBox ReadOnly="true" runat="server" ID="billing_zip" name="billing_zip" />
                </div>
                </div>

                <div>
                <label>Country</label>
                <div>
                <asp:TextBox ReadOnly="true"  runat="server" ID="billing_country" name="billing_country" type="text" />
                </div>
                </div>   

                <div>
                <label>State</label>
                <div>
                <asp:TextBox ReadOnly="true" runat="server" ID="billing_state" name="billing_state"  type="text" />
                </div>
                </div>

                <div>
                <label>City</label>
                <div>
                <asp:TextBox ReadOnly="true" runat="server" ID="billing_city" name="billing_city" type="text" value="" />
                </div>
                </div>

                <div>
                <label>Donation</label>
                <div>
                <asp:TextBox  disable="true" ReadOnly="true" runat="server" ID="DonationId" name="DonationId">
                </asp:TextBox>
                </div>
                </div>

                <div>
                <label>Amount</label>
                <div>
                <asp:TextBox ReadOnly="true" runat="server" ID="amount" name="amount" type="number" />
                </div>
                </div>

                <div>
                <label>Currency</label>
                <div>
                <asp:TextBox  disable="true" ReadOnly="true" runat="server" ID="currencycode" name="currencyCode">
                </asp:TextBox>
                </div>
                </div>

                <div>
                <label>Remarks </label>
                <div>
                <asp:TextBox ReadOnly="true" runat="server" TextMode="multiline" cols="20" ID="billing_notes" name="billing_notes" Rows="2" />
                </div>
                </div>  

                <div>
                <label>Status</label>
                <div>
                <asp:TextBox ReadOnly="true" runat="server" ID="sId" />
                </div>
                </div>                                                            
        </form>

Use of Source Code

To use the code supplied with the article, you need to have .NET Framework 4.0 or higher installed on your system. You also need to have a real or FirstData ICICI Merchant Services account. No additional requirements should be needed to open the FirstData account.