Thursday, June 27, 2019

Episerver CMS Content/Block Type Property Delete

When you work on Episerver site, some times, you have an experience that removed properties from content type or block type are still displayed on the CMS.
In the code, you have already removed them. But still, properties are showed in the CMS.
You wonder how you can remove deleted properties from content type or block.

You can easily remove those properties from the cms as following.

1.0 Logging to the cms.

2.0 Go to CMS-->Admin-->Content  Types.
All the content types and related properties are listed here.

3.0 You can see the missing tag as in the image.












4.0 Click on the property and Delete it.


Thursday, October 18, 2018

GIT Branches

Found good article
https://nvie.com/posts/a-successful-git-branching-model/

Wednesday, May 24, 2017

How to Use Excel to Create SQL Query String

Have you ever faced some situations where your database table's data are get updated or changed?

You have a backup database. You know you can use a backup database table to update the previous table data. But it takes more time to write update statement for each row.

You can use excel file to do that task easily as follow.

1.0 Generate the script from backup database. For example, I need to update 'is billable' columns of administrator table.
I write this query to get back up data.

SELECT aid,aisBillable FROM Administrator



2.0 Copy and Paste those query result into new excel file.



3.0  Use below SQL update function in the first row of the excel sheet as in the below image.
SQL:
="UPDATE Administrator set aisBillable ="&B2&" WHERE aid="&A2



4.0 Drag the first row to bottom rows. Then SQL 'Update' statement is updated as in the image.



5.0 You can copy those update queries and run on the SQL server to get updated table data.




Summary
Without writing an update/delete queries for each row, you can use excel functionality to make a job easier.







Sunday, May 14, 2017

Dot Net Bulk Insert

I have a project to get read CSV files and pushed those data to SQL table. CSV file contains more than 5000 records.

It is not good practice to insert record one by one SQL table due to it is a time-consuming process.

To optimize the process, Dot net has an ‘SQLBulkCopy’ feature to insert data at once to target table.

I like to share my experience how I used above feature.

1.0   I have read a CSV file and put them to object list.

2.0   For a bulk update, you need to convert object list to a data table.

Code for converting object list to the data table.
   public static DataTable ToDataTable<T>(List<T> items)
   {            DataTable dataTable = new DataTable(typeof(T).Name);
             //Get all the properties            PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo prop in Props)
            {                //Defining type of data column gives proper data table
                var type = (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.PropertyType);
                //Setting column names as Property names                dataTable.Columns.Add(prop.Name, type);            }            foreach (T item in items)
            {                var values = new object[Props.Length];
                for (int i = 0; i < Props.Length; i++)
                {                    //inserting property values to datatable rows                    values[i] = Props[i].GetValue(item, null);
                }                dataTable.Rows.Add(values); 
 }     
     //put a breakpoint here and check datatable 
return dataTable;
 }

2.1 You can call above method as below.

  DataTable dt = new DataTable("MyTable");
  dt = BaseDao.ToDataTable<T>(items);


3.0   After you need to specify the destination table. if source table and destination table’s column fields a are not match then you need to specify mapping columns.

4.0   Completed code is below.

protected override void BulkInsertData<T>(List<T> items)
 {  string connectionString = BaseDao.ConnectionString;
             DataTable dt = new DataTable("MyTable");
            dt = BaseDao.ToDataTable<T>(items);
  using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString))
  {
 
bulkCopy.BulkCopyTimeout = 660;   


bulkCopy.DestinationTableName = "Workday_Employee";


// Set up the column mappings by name.                SqlBulkCopyColumnMapping mapID = new SqlBulkCopyColumnMapping("Employee_ID", "Workday_Id");bulkCopy.ColumnMappings.Add(mapID);    
SqlBulkCopyColumnMapping mapID1 = new SqlBulkCopyColumnMapping("User_Name", "Username");bulkCopy.ColumnMappings.Add(mapID1);     
bulkCopy.WriteToServer(dt);
      bulkCopy.Close();         
}


Summary


Monday, April 3, 2017

URL Redirections - ASP.NET Sites



If your site is hosted on IIS server , you can  do the re-directions as below.

1.0 Add URLs as below to web config file . 

 
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

 <location path="home/about-us/meet-the-team/stephanie-brennan">
      <system.webServer>
        <httpRedirect enabled="true" destination="https://www.ibuynew.com.au/home/about-us/meet-the-team" httpResponseStatus="Permanent" exactDestination="true" />
      </system.webServer>
    </location>
 <location path="home/about-us/meet-the-team/nicholas-de-la-paz">
      <system.webServer>
        <httpRedirect enabled="true" destination="https://www.ibuynew.com.au/home/about-us/meet-the-team" httpResponseStatus="Permanent" exactDestination="true" />
      </system.webServer>
    </location>

</configuration>

2.0 Make sure to remove back slash, after the path property.
 Otherwise site won't work.
 <location path="home/about-us/meet-the-team/stephanie-brennan">





Tuesday, June 14, 2016

Minify and bundle CSS and JavaScript files for Kentico 7

Site performance can be checked through this site.  https://developers.google.com/speed/pagespeed, Some times it suggests us to bundle the CSS/ java scripts files.
But we cannot able to bundle CSS files in Kentico 7. When we tried to use dot net framework(4.5 and upper) features, Kentico gives DLL issues.
There are many solutions for PHP sites. But for asp net sites few solutions in the web. Among them, solution found in below site.
It has these DLLs.
 








1.0 Copy above highlighted DLLs to project bin
2.0 CMS master page –> edit layout page
add below codes to bundle the CSS files .
Make sure to use , <asp:placeholder>. Otherwise rendering issues will occurs in Kentico.

<%@ Import Namespace=”SquishIt.Framework” %>
<asp:PlaceHolder   runat=”server”>
<%= Bundle.Css()
.Add(“~/app_themes/ibuynew/style/viewport_1500.css”)
.Add(“~/app_themes/ibuynew/style/viewport_1280.css”)
.Add(“~/app_themes/ibuynew/style/viewport_1020.css”)
.Add(“~/app_themes/ibuynew/style/viewport_760.css”)
.Add(“~/app_themes/ibuynew/style/viewport_480.css”)
.Add(“~/app_themes/ibuynew/style/viewport_320.css”)
.Add(“~/app_themes/ibuynew/style/jquery.selectbox.css”)
.Add(“~/app_themes/ibuynew/style/colorbox.css”)
.Add(“~/app_themes/ibuynew/style/jquery.mCustomScrollbar.css”)
.Add(“~/app_themes/ibuynew/style/marketo.css”)
.Render(“~/app_themes/ibuynew/style/combined_#.css”)
%>
</asp:PlaceHolder>

Like wise you can add Js files to get bundle.

<asp:PlaceHolder   runat=”server”>
<%= Bundle.JavaScript()
.Add(“~/cmsscripts/ibuynew/socialmedia.js”)
.Add(“~/cmsscripts/ibuynew/ajax.js”)
.Add(“~/cmsscripts/jquery/jquery-core.js”)
.Add(“~/cmsscripts/jquery/jquery-cookie.js”)
.Add(“~/cmsscripts/jquery/jquery-tools.js”)
.Add(“~/cmsscripts/ibuynew/jquery.carouFredSel-6.2.0-packed.js”)
.Add(“~/cmsscripts/ibuynew/jquery.mCustomScrollbar.concat.min.js”)
.Add(“~/cmsscripts/ibuynew/jquery.ba-throttle-debounce.min.js”)
.Add(“~/cmsscripts/ibuynew/jquery.selectbox-0.2.js”)
.Add(“~/cmsscripts/ibuynew/css3-mediaqueries.js”)
.Add(“~/cmsscripts/ibuynew/jquery.colorbox-min.js”)
.Add(“~/cmsscripts/ibuynew/jquery.mCustomScrollbar.concat.min.js”)
.Add(“~/cmsscripts/ibuynew/form.js”)
.Add(“~/cmsscripts/ibuynew/common.js”)
.Render(“~/cmsscripts/ibuynew/combined_#.js”)
%>
</asp:PlaceHolder>

 Finally you can remove relevant CSS from kentico header.

Wednesday, November 11, 2015

Build Dot Net Project Without Installing Visual Studio By Using MS Build


Some situations we need to build dot net projects without installing visual studio in particular servers. To help such situations, we can use msbuild.exe. Following sections will explain using BAT file, how we can build the project.

1.0 set dot net framework path to environment variable.

To enable msbuild.exe in Command Prompt, you simply have to add .net framework path in the  environment variable of the machine.
You can access the environment variables by right clicking on 'Computer', click 'properties' and click 'Advanced system settings' on the left navigation bar. On the next dialog bog click 'Environment variables,' scroll down to 'PATH' and edit it to include your path to the framework (don't forget a ';' after the last entry in here.
For reference my path was C:\Windows\Microsoft.NET\Framework\v4.0.30319.

2.0 Bat file code
Open a note pad. Copy and paste below code and save extension as bat. Ex deploy.bat
Under  bat file code ,you need to give dot net project’s solution file path or project file path after ‘msbuild.exe’ depend on the requirement  as below.
‘pathMSBuild’ is denote dot net framework path
Code :

set pathMSBuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\"
@echo off
cls
cd %pathMSBuild%
msbuild.exe "D:\Netstarter -projects test R and  D\NIGEL\nigel\codePool\NigelSolution\NigelSolution.sln" /p:configuration=debug

pause



3.0 Every time you click BAT file , project will build in particular server location.

Wednesday, September 10, 2014

Create JIRA Issue through JIRA API

JIRA API supports REST JSON format.
Here I show C # code  to call JIRA API and  how we can create an issue  through that API

Code : 

using System.Net;
using System.IO;

Event code 

string postUrl = "https://netstarter.jira.com/rest/api/latest/issue";

var httpWebRequest = (HttpWebRequest)WebRequest.Create(postUrl);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";        
httpWebRequest.Headers["Authorization"] = "Basic " +       Convert.ToBase64String(Encoding.Default.GetBytes("USERNAME:PASSWORD"));

using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
                string json = @"{""fields"":{""project"":{""key"": ""JAPI""},""summary"": ""REST EXAMPLE"",""description"": ""Creating an issue via REST API 2"",""issuetype"": {""name"": ""Bug""}}}";

                streamWriter.Write(json);
                streamWriter.Flush();
                streamWriter.Close();

                var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                {
                    var result = streamReader.ReadToEnd();
                }
}


References:
JIRA API Documentation 






Wednesday, May 21, 2014

PayPal Payment Gateway Integration

There are lot of web sites which explain how we can integrate PayPal payment gateway with  our web site. Sometimes those explanations make  confuses us and it is difficult to think what is  the good method .
In this article I explain some reliable secure method to integrate PayPal with our site. I have used PayPal API credentials method for integrating process.

First you need to create a sandbox account from this URL. After that you have to create two accounts for business and personal. These accounts help us to test future transactions.



You can use personal account’s dummy test credit card details to perform the test transactions through sandbox.
There is a tab called “API credentials” in business account sections. These credentials (signature, username, and password) are used to call to PayPal payment gateway from our site.



As a  second step, you can generate appropriate code files through this URL.




Above Integration wizard gives this NVPAPICaller class file. Add that file your  project. Check Appendix 1 ,bottom of the article for code of NVPAPICaller class. we use that class file's method for calling Paypal payment gateway.

I have written code in PayPal button’s  click event (Check out page ) as in  Appendix 2 . 



Once user click Paypal button , user is redirected to Paypal site as below image.



Appendix 2's  PayPal button’s  click event code explanation:
This code is used to set our API  details of our Paypal account.

NVPAPICaller test = new NVPAPICaller(OrganizationDetails.PaypalAPIUsername,OrganizationDetails.PaypalAPIPassword,OrganizationDetails.PaypalAPISignature);

Through this code we send request to Paypal with our payment details.

ret = test.MarkExpressCheckout(amt, shipToName, shipToStreet, shipToStreet2,
                                shipToCity, shipToState, shipToZip, shipToCountryCode,ref token, ref retMsg);


If Paypal respond is success ,  then user is directed to Paypal site. Mean while Paypal sends us a token. We need to keep it in session variable. That will be used in next step. 

if (ret)
{
          Session["token"] = token;
          Response.Redirect(retMsg);
}
else
{
         Response.Redirect("APIError.aspx?" + retMsg);
}

Successfully paid payments are redirected to Thank you page of our site. We can set success and unsuccessful URL in our method which is in  the class called NVPAPICaller(Appendix 1). Check Appendix 3 code of it.

string returnURL = ConfigurationManager.AppSettings["SuccessURL"].ToString();
string cancelURL = ConfigurationManager.AppSettings["FailedURL"].ToString();

NVPCodec encoder = new NVPCodec();
encoder["METHOD"] = "SetExpressCheckout";
encoder["RETURNURL"] = returnURL;
encoder["CANCELURL"] = cancelURL;
encoder["AMT"] = amt;
encoder["PAYMENTACTION"] = "Sale";
encoder["CURRENCYCODE"] = "AUD";
       

Appendix 4's  Thank you page code explanation:

In  our site's thank you page, I have written code to confirm payment. For that we have to use “token” which used in previous page.Thank you page full code can be seen in Appendix 4.

string token = Session["token"].ToString();
bool ret = test.GetShippingDetails(token, ref payerId, ref shippingAddress, ref retMsg);


Above method return payer id. Payer id and token  is used to confirm the payment as below.

ret = test.ConfirmPayment(finalPaymentAmount, token, payerId, ref decoder, ref retMsg);


Successfully payments  are returned transaction id and other useful informations.

Session["PaypalTransactionID"] = decoder["TRANSACTIONID"];


I would think this article help you to integrate Paypal payment gateway with your site.



Appendix 1 
C# code for NVPAPICaller class:

using System;
using System.Collections;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Data;
using System.Configuration;
using System.Web;

/// <summary>
/// Summary description for NVPAPICaller
/// </summary>
public class NVPAPICaller
{
    public NVPAPICaller(string PaypalAPIUserName, string
        PaypalAPIPassword, string PaypaAPISignature)
    {
        APIUsername = PaypalAPIUserName;
        APIPassword = PaypalAPIPassword;
        APISignature = PaypaAPISignature;
    }
    //private static readonly ILog log = LogManager.GetLogger(typeof(NVPAPICaller));
      
    private string pendpointurl = "https://api-3t.paypal.com/nvp";
    private const string CVV2 = "CVV2";

    //Flag that determines the PayPal environment (live or sandbox)
    private const bool bSandbox =true;
   

  
    private const string SIGNATURE = "SIGNATURE";
    private const string PWD = "PWD";
    private const string ACCT = "ACCT";

    //Replace <API_USERNAME> with your API Username
    //Replace <API_PASSWORD> with your API Password
    //Replace <API_SIGNATURE> with your Signature
    public string APIUsername ;
    private string APIPassword;
    private string APISignature ;
    private string Subject = "";
       private string BNCode = "PP-ECWizard";

    //HttpWebRequest Timeout specified in milliseconds
    private const int Timeout = 5000;
    private static readonly string[] SECURED_NVPS = new string[] { ACCT, CVV2, SIGNATURE, PWD };


    /// <summary>
    /// Sets the API Credentials
    /// </summary>
    /// <param name="Userid"></param>
    /// <param name="Pwd"></param>
    /// <param name="Signature"></param>
    /// <returns></returns>
    public void SetCredentials(string Userid, string Pwd, string Signature)
    {
        APIUsername = Userid;
        APIPassword = Pwd;
        APISignature = Signature;
    }

    /// <summary>
    /// ShortcutExpressCheckout: The method that calls SetExpressCheckout API
    /// </summary>
    /// <param name="amt"></param>
    /// <param ref name="token"></param>
    /// <param ref name="retMsg"></param>
    /// <returns></returns>
    public bool ShortcutExpressCheckout(string amt, ref string token, ref string retMsg)
    {
              string host = "www.paypal.com";
              if (bSandbox)
              {
                     pendpointurl = "https://api-3t.sandbox.paypal.com/nvp";
                     host = "www.sandbox.paypal.com";
              }

        string returnURL = ConfigurationManager.AppSettings["SuccessURL"].ToString();
        string cancelURL = ConfigurationManager.AppSettings["FailedURL"].ToString();

        NVPCodec encoder = new NVPCodec();
        encoder["METHOD"] = "SetExpressCheckout";
        encoder["RETURNURL"] = returnURL;
        encoder["CANCELURL"] = cancelURL;
        encoder["Amt"] = amt;
        //encoder["PAYMENTACTION"] = "Sale";
        //encoder["CURRENCYCODE"] = "USD";
       // encoder["PAYMENTREQUEST_0_AMT"] = amt;
     //   encoder["PAYMENTREQUEST_0_CURRENCYCODE"] = "AUD";
     //   encoder["PAYMENTREQUEST_0_DESC"] = "dsds dss";
        encoder["CURRENCYCODE"] = "AUD";
       // encoder["SOLUTIONTYPE"] = "Sole";

        string pStrrequestforNvp = encoder.Encode();
        string pStresponsenvp = HttpCall(pStrrequestforNvp);

        NVPCodec decoder = new NVPCodec();
        decoder.Decode(pStresponsenvp);

        string strAck = decoder["ACK"].ToLower();
        if (strAck != null && (strAck == "success" || strAck == "successwithwarning"))
        {
            token = decoder["TOKEN"];

            string ECURL = "https://" + host + "/cgi-bin/webscr?cmd=_express-checkout" + "&token=" + token + "&useraction=commit";

            retMsg = ECURL;
            return true;
        }
        else
        {
            retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" +
                "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" +
                "Desc2=" + decoder["L_LONGMESSAGE0"];

            return false;
        }
    }

    /// <summary>
    /// MarkExpressCheckout: The method that calls SetExpressCheckout API, invoked from the
    /// Billing Page EC placement
    /// </summary>
    /// <param name="amt"></param>
    /// <param ref name="token"></param>
    /// <param ref name="retMsg"></param>
    /// <returns></returns>
    public bool MarkExpressCheckout(string amt,
                        string shipToName, string shipToStreet, string shipToStreet2,
                        string shipToCity, string shipToState, string shipToZip,
                        string shipToCountryCode,ref string token, ref string retMsg)
    {
              string host = "www.paypal.com";
              if (bSandbox)
              {
                     pendpointurl = "https://api-3t.sandbox.paypal.com/nvp";
                     host = "www.sandbox.paypal.com";
              }

         string returnURL = ConfigurationManager.AppSettings["SuccessURL"].ToString();
        string cancelURL = ConfigurationManager.AppSettings["FailedURL"].ToString();

        NVPCodec encoder = new NVPCodec();
        encoder["METHOD"] = "SetExpressCheckout";
        encoder["RETURNURL"] = returnURL;
        encoder["CANCELURL"] = cancelURL;
        encoder["AMT"] = amt;
        encoder["PAYMENTACTION"] = "Sale";
        encoder["CURRENCYCODE"] = "AUD";
       // encoder["DESC"] = "Payment";

        encoder["VERSION"] = "52";

        //Optional Shipping Address entered on the merchant site
        encoder["SHIPTONAME"] = shipToName;
        encoder["SHIPTOSTREET"] = shipToStreet;
        encoder["SHIPTOSTREET2"] = shipToStreet2;
        encoder["SHIPTOCITY"] = shipToCity;
        encoder["SHIPTOSTATE"] = shipToState;
        encoder["SHIPTOZIP"] = shipToZip;
        encoder["SHIPTOCOUNTRYCODE"] = shipToCountryCode;
      

        string pStrrequestforNvp = encoder.Encode();
        string pStresponsenvp = HttpCall(pStrrequestforNvp);

        NVPCodec decoder = new NVPCodec();
        decoder.Decode(pStresponsenvp);

        string strAck = decoder["ACK"].ToLower();
        if (strAck != null && (strAck == "success" || strAck == "successwithwarning"))
        {
         
            token = decoder["TOKEN"];

            string ECURL = "https://" + host + "/cgi-bin/webscr?cmd=_express-checkout" + "&token=" + token + "&useraction=commit";

            retMsg = ECURL;
            return true;
        }
        else
        {
            retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" +
                "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" +
                "Desc2=" + decoder["L_LONGMESSAGE0"];

            return false;
        }
    }



    /// <summary>
    /// GetShippingDetails: The method that calls SetExpressCheckout API, invoked from the
    /// Billing Page EC placement
    /// </summary>
    /// <param name="token"></param>
    /// <param ref name="retMsg"></param>
    /// <returns></returns>
    public bool GetShippingDetails(string token, ref string PayerId, ref string ShippingAddress, ref string retMsg)
    {

              if (bSandbox)
              {
                     pendpointurl = "https://api-3t.sandbox.paypal.com/nvp";
              }
             
        NVPCodec encoder = new NVPCodec();
        encoder["METHOD"] = "GetExpressCheckoutDetails";
        encoder["TOKEN"] = token;
      

        string pStrrequestforNvp = encoder.Encode();
        string pStresponsenvp = HttpCall( pStrrequestforNvp );

        NVPCodec decoder = new NVPCodec();
        decoder.Decode( pStresponsenvp );

        string strAck = decoder["ACK"].ToLower();
        if (strAck != null && (strAck == "success" || strAck == "successwithwarning"))
        {
            ShippingAddress = "<table><tr>";
            ShippingAddress += "<td> First Name </td><td>" + decoder["FIRSTNAME"] + "</td></tr>";
            ShippingAddress += "<td> Last Name </td><td>" + decoder["LASTNAME"] + "</td></tr>";
            ShippingAddress += "<td colspan='2'> Shipping Address</td></tr>";
            ShippingAddress += "<td> Name </td><td>" + decoder["PAYMENTREQUEST_0_SHIPTONAME"] + "</td></tr>";
            ShippingAddress += "<td> Street1 </td><td>" + decoder["PAYMENTREQUEST_0_SHIPTOSTREET"] + "</td></tr>";
            ShippingAddress += "<td> Street2 </td><td>" + decoder["PAYMENTREQUEST_0_SHIPTOSTREET2"] + "</td></tr>";
            ShippingAddress += "<td> City </td><td>" + decoder["PAYMENTREQUEST_0_SHIPTOCITY"] + "</td></tr>";
            ShippingAddress += "<td> State </td><td>" + decoder["PAYMENTREQUEST_0_SHIPTOSTATE"] + "</td></tr>";
            ShippingAddress += "<td> Zip </td><td>" + decoder["PAYMENTREQUEST_0_SHIPTOZIP"] + "</td>";
            ShippingAddress += "</tr>";

            PayerId = decoder["PAYERID"].ToString();
            return true;
        }
        else
        {
            retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" +
                "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" +
                "Desc2=" + decoder["L_LONGMESSAGE0"];

            return false;
        }
    }


    /// <summary>
    /// ConfirmPayment: The method that calls SetExpressCheckout API, invoked from the
    /// Billing Page EC placement
    /// </summary>
    /// <param name="token"></param>
    /// <param ref name="retMsg"></param>
    /// <returns></returns>
    public bool ConfirmPayment(string finalPaymentAmount, string token, string PayerId, ref NVPCodec decoder, ref string retMsg )
    {
              if (bSandbox)
              {
                     pendpointurl = "https://api-3t.sandbox.paypal.com/nvp";
              }
             
        NVPCodec encoder = new NVPCodec();
        encoder["METHOD"] = "DoExpressCheckoutPayment";
        encoder["TOKEN"] = token;
        encoder["PAYMENTACTION"] = "Sale";
       // encoder["PAYMENTREQUEST_0_PAYMENTACTION"] = "Sale";
        encoder["PAYERID"] = PayerId;
        encoder["AMT"] = finalPaymentAmount;
       // encoder["PAYMENTREQUEST_0_AMT"] = finalPaymentAmount;
              //encoder["PAYMENTREQUEST_0_CURRENCYCODE"] = "AUD";
        encoder["CURRENCYCODE"] = "AUD";

        string pStrrequestforNvp = encoder.Encode();
        string pStresponsenvp = HttpCall(pStrrequestforNvp);

        decoder = new NVPCodec();
        decoder.Decode(pStresponsenvp);

        string strAck = decoder["ACK"].ToLower();
        if (strAck != null && (strAck == "success" || strAck == "successwithwarning"))
        {
                  return true;
        }
        else
        {
            retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" +
                "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" +
                "Desc2=" + decoder["L_LONGMESSAGE0"];

            return false;
        }
    }


    /// <summary>
    /// HttpCall: The main method that is used for all API calls
    /// </summary>
    /// <param name="NvpRequest"></param>
    /// <returns></returns>
    public string HttpCall(string NvpRequest) //CallNvpServer
    {
        string url = pendpointurl;

        //To Add the credentials from the profile
        string strPost = NvpRequest + "&" + buildCredentialsNVPString();
              strPost = strPost + "&BUTTONSOURCE=" + HttpUtility.UrlEncode( BNCode );

        HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
        objRequest.Timeout = Timeout;
        objRequest.Method = "POST";
        objRequest.ContentLength = strPost.Length;

        try
        {
            using (StreamWriter myWriter = new StreamWriter(objRequest.GetRequestStream()))
            {
                myWriter.Write(strPost);
            }
        }
        catch (Exception e)
        {
            /*
            if (log.IsFatalEnabled)
            {
                log.Fatal(e.Message, this);
            }*/
        }

        //Retrieve the Response returned from the NVP API call to PayPal
        HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
        string result;
        using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
        {
            result = sr.ReadToEnd();
        }

        //Logging the response of the transaction
        /* if (log.IsInfoEnabled)
         {
             log.Info("Result :" +
                       " Elapsed Time : " + (DateTime.Now - startDate).Milliseconds + " ms" +
                      result);
         }
         */
        return result;
    }

    /// <summary>
    /// Credentials added to the NVP string
    /// </summary>
    /// <param name="profile"></param>
    /// <returns></returns>
    private string buildCredentialsNVPString()
    {
        NVPCodec codec = new NVPCodec();

        if (!IsEmpty(APIUsername))
            codec["USER"] = APIUsername;

        if (!IsEmpty(APIPassword))
            codec[PWD] = APIPassword;

        if (!IsEmpty(APISignature))
            codec[SIGNATURE] = APISignature;

        if (!IsEmpty(Subject))
            codec["SUBJECT"] = Subject;

        codec["VERSION"] = "2.3";

        return codec.Encode();
    }

    /// <summary>
    /// Returns if a string is empty or null
    /// </summary>
    /// <param name="s">the string</param>
    /// <returns>true if the string is not null and is not empty or just whitespace</returns>
    public static bool IsEmpty(string s)
    {
        return s == null || s.Trim() == string.Empty;
    }
}


public sealed class NVPCodec : NameValueCollection
{
    private const string AMPERSAND = "&";
    private const string EQUALS = "=";
    private static readonly char[] AMPERSAND_CHAR_ARRAY = AMPERSAND.ToCharArray();
    private static readonly char[] EQUALS_CHAR_ARRAY = EQUALS.ToCharArray();

    /// <summary>
    /// Returns the built NVP string of all name/value pairs in the Hashtable
    /// </summary>
    /// <returns></returns>
    public string Encode()
    {
        StringBuilder sb = new StringBuilder();
        bool firstPair = true;
        foreach (string kv in AllKeys)
        {
            string name = HttpUtility.UrlEncode(kv);
            string value = HttpUtility.UrlEncode(this[kv]);
            if (!firstPair)
            {
                sb.Append(AMPERSAND);
            }
            sb.Append(name).Append(EQUALS).Append(value);
            firstPair = false;
        }
        return sb.ToString();
    }

    /// <summary>
    /// Decoding the string
    /// </summary>
    /// <param name="nvpstring"></param>
    public void Decode(string nvpstring)
    {
        Clear();
        foreach (string nvp in nvpstring.Split(AMPERSAND_CHAR_ARRAY))
        {
            string[] tokens = nvp.Split(EQUALS_CHAR_ARRAY);
            if (tokens.Length >= 2)
            {
                string name = HttpUtility.UrlDecode(tokens[0]);
                string value = HttpUtility.UrlDecode(tokens[1]);
                Add(name, value);
            }
        }
    }


    #region Array methods
    public void Add(string name, string value, int index)
    {
        this.Add(GetArrayName(index, name), value);
    }

    public void Remove(string arrayName, int index)
    {
        this.Remove(GetArrayName(index, arrayName));
    }

    /// <summary>
    ///
    /// </summary>
    public string this[string name, int index]
    {
        get
        {
            return this[GetArrayName(index, name)];
        }
        set
        {
            this[GetArrayName(index, name)] = value;
        }
    }

    private static string GetArrayName(int index, string name)
    {
        if (index < 0)
        {
            throw new ArgumentOutOfRangeException("index", "index can not be negative : " + index);
        }
        return name + index;
    }
    #endregion
}



  

Appendix 2 
Checkout page:

  #region Paypal paymentGatway events and methods

        protected void imgpaypal_Click(object sender, ImageClickEventArgs e)
        {
            PaypalCall();    
        }

        public void PaypalCall()
        {

            NVPAPICaller test = new NVPAPICaller(OrganizationDetails.PaypalAPIUsername,OrganizationDetails.PaypalAPIPassword,OrganizationDetails.PaypalAPISignature);
            string retMsg = "";
            string token = "";
            SaveDatailinClass();

           
           decimal total = (from shoppingitem in shoppingCartCollection
                                 select shoppingitem.UnitPrice).Sum();

           if (total >= 10000)
           {
               total = total + total *0.02M;
           }
           HttpContext.Current.Session["payment_amt"] = total;
            bool ret;
           
            if (Session["payment_amt"] != null)
            {
              
                string amt = Session["payment_amt"].ToString();

                //Optional Shipping Address entered on the merchant site
                string shipToName = ShopperDetails.FirstName;
                string shipToStreet =ShopperDetails.Address1;
                string shipToStreet2 = ShopperDetails.Address1;
                string shipToCity = ShopperDetails.City;
                string shipToState = ShopperDetails.State;
                string shipToZip = ShopperDetails.Zip;
                string shipToCountryCode = ShopperDetails.Country;

                ret = test.MarkExpressCheckout(amt, shipToName, shipToStreet, shipToStreet2,
                                shipToCity, shipToState, shipToZip, shipToCountryCode,
                                ref token, ref retMsg);
                if (ret)
                {
                    Session["token"] = token;
                    Response.Redirect(retMsg);
                }
                else
                {
                    Response.Redirect("APIError.aspx?" + retMsg);
                }
            }
            else
            {
                Response.Redirect("APIError.aspx?ErrorCode=AmtMissing");
            }

        }




Appendix 3 

public bool MarkExpressCheckout(string amt,
                        string shipToName, string shipToStreet, string shipToStreet2,
                        string shipToCity, string shipToState, string shipToZip,
                        string shipToCountryCode,ref string token, ref string retMsg)
    {
              string host = "www.paypal.com";
              if (bSandbox)
              {
                     pendpointurl = "https://api-3t.sandbox.paypal.com/nvp";
                     host = "www.sandbox.paypal.com";
              }

         string returnURL = ConfigurationManager.AppSettings["SuccessURL"].ToString();
        string cancelURL = ConfigurationManager.AppSettings["FailedURL"].ToString();

        NVPCodec encoder = new NVPCodec();
        encoder["METHOD"] = "SetExpressCheckout";
        encoder["RETURNURL"] = returnURL;
        encoder["CANCELURL"] = cancelURL;
        encoder["AMT"] = amt;
        encoder["PAYMENTACTION"] = "Sale";
        encoder["CURRENCYCODE"] = "AUD";
       // encoder["DESC"] = "Payment";

        encoder["VERSION"] = "52";

        //Optional Shipping Address entered on the merchant site
        encoder["SHIPTONAME"] = shipToName;
        encoder["SHIPTOSTREET"] = shipToStreet;
        encoder["SHIPTOSTREET2"] = shipToStreet2;
        encoder["SHIPTOCITY"] = shipToCity;
        encoder["SHIPTOSTATE"] = shipToState;
        encoder["SHIPTOZIP"] = shipToZip;
        encoder["SHIPTOCOUNTRYCODE"] = shipToCountryCode;
      

        string pStrrequestforNvp = encoder.Encode();
        string pStresponsenvp = HttpCall(pStrrequestforNvp);

        NVPCodec decoder = new NVPCodec();
        decoder.Decode(pStresponsenvp);

        string strAck = decoder["ACK"].ToLower();
        if (strAck != null && (strAck == "success" || strAck == "successwithwarning"))
        {
         
            token = decoder["TOKEN"];

            string ECURL = "https://" + host + "/cgi-bin/webscr?cmd=_express-checkout" + "&token=" + token + "&useraction=commit";

            retMsg = ECURL;
            return true;
        }
        else
        {
            retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" +
                "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" +
                "Desc2=" + decoder["L_LONGMESSAGE0"];

            return false;
        }
    }




Appendix 4 
Thank you page:


     protected void Page_Load(object sender, EventArgs e)
     {

            NVPAPICaller test = new NVPAPICaller(OrganizationDetails.PaypalAPIUsername, OrganizationDetails.PaypalAPIPassword, OrganizationDetails.PaypalAPISignature);
         
            string payerId = "";
            string shippingAddress = "";
            string retMsg = "";
            NVPCodec decoder = null;
            string finalPaymentAmount = Session["payment_amt"].ToString();

            string token = Session["token"].ToString();

            bool ret = test.GetShippingDetails(token, ref payerId, ref shippingAddress, ref retMsg);
            if (ret)
            {
                Session["payerId"] = payerId;


              //  Response.Write(shippingAddress);

                ret = test.ConfirmPayment(finalPaymentAmount, token, payerId, ref decoder, ref retMsg);
                if (ret)
                {
                    // Unique transaction ID of the payment. Note:  If the PaymentAction of the request was Authorization or Order, this value is your AuthorizationID for use with the Authorization & Capture APIs.
                    Session["PaypalTransactionID"] = decoder["TRANSACTIONID"];

                    imgLogo.ImageUrl = OrganizationDetails.LogoPath;
                    litLogoText.Text = string.Format("<div class='{0}'>{1}</div>", OrganizationDetails.LogoTextCSSClass, OrganizationDetails.LogoText);
                    litSubject.Text = OrganizationDetails.LogoSubjectText;

                    StringBuilder mytext = new StringBuilder();
                    mytext.Append(string.Format("<div class='{0}'>{1}</div>", OrganizationDetails.LogoTextCSSClass, "Thank you for your payment."));
                    mytext.Append(string.Format("</br><p> Your Paypal Transaction ID  : {0} </p>", Session["PaypalTransactionID"].ToString()));

                    litBody.Text = mytext.ToString();

                    checkout checkoutpage = new checkout();
                    checkoutpage.SendEmailToAdmin();
                    checkoutpage.SendEmailToClient();
                   
                }
                else
                {
                    Response.Redirect("APIError.aspx?" + retMsg);
                }

            }
            else
            {
                Response.Redirect("APIError.aspx?" + retMsg);
            }
        }