AspBucket offers ASP.NET, C#, VB, Jquery, CSS, Ajax, SQL tutorials. It is the best place for programmers to learn

Sunday, 8 May 2016

How to integrate PayPal express checkout in asp.net application?

In this blog post I will discuss How to integrate PayPal express checkout in asp.net application?  PayPal is third-party payment processors that specialize in online shopping that address scalability and security. Please follow below processes to implement PayPal express checkout.

Step- 1 Create PayPal sandbox account for testing environment.



Step- 2 Add following app setting in your web config file.
  </appSettings>
   <!--Paypal Enviroment Variables-->
    <add key="IsSandbox" value="true" />
    
    <add key="PaypalEndPointURL" value="https://api-3t.paypal.com/nvp" />
    <add key="Paypalhost" value="www.paypal.com" />

    <add key="PaypalEndPointURL_SB" value="https://api-3t.sandbox.paypal.com/nvp" />
    <add key="Paypalhost_SB" value="www.sandbox.paypal.com" />
    
    <add key="PayPalAPIUsername" value="put_value" />
    <add key="PayPalAPIPassword" value="put_value" />
    <add key="PayPalAPISignature" value="put_value" />
    <add key="PayPalBNCode" value="PP-ECWizard" />
    <add key="PayPalTimeout" value="50000"/>
    <add key="PayPalreturnURL" value="put_value"/>
    <add key="PayPalcancelURL" value="put_value"/>

  </appSettings>

Step 3- Create separate class to access these App Settings constants.
 public class AppSettings
    {
       #region--PayPal Settings

        public static bool IsSandbox
        {
            get { return bool.Parse((ConfigurationManager.AppSettings["IsSandbox"] != null ? ConfigurationManager.AppSettings["IsSandbox"].ToString() : "false")); }
        }       

        public static string PaypalEndPointURL
        {
            get { return (ConfigurationManager.AppSettings["PaypalEndPointURL"] != null ? ConfigurationManager.AppSettings["PaypalEndPointURL"].ToString() : ""); }
        }

        public static string Paypalhost
        {
            get { return (ConfigurationManager.AppSettings["Paypalhost"] != null ? ConfigurationManager.AppSettings["Paypalhost"].ToString() : ""); }
        }

        public static string PaypalEndPointURL_SB
        {
            get { return (ConfigurationManager.AppSettings["PaypalEndPointURL_SB"] != null ? ConfigurationManager.AppSettings["PaypalEndPointURL_SB"].ToString() : ""); }
        }

        public static string Paypalhost_SB
        {
            get { return (ConfigurationManager.AppSettings["Paypalhost_SB"] != null ? ConfigurationManager.AppSettings["Paypalhost_SB"].ToString() : ""); }
        }              

        public static string PayPalAPIUsername
        {
            get { return (ConfigurationManager.AppSettings["PayPalAPIUsername"] != null ? ConfigurationManager.AppSettings["PayPalAPIUsername"].ToString() : ""); }
        }

        public static string PayPalAPIPassword
        {
            get { return (ConfigurationManager.AppSettings["PayPalAPIPassword"] != null ? ConfigurationManager.AppSettings["PayPalAPIPassword"].ToString() : ""); }
        }

        public static string PayPalAPISignature
        {
            get { return (ConfigurationManager.AppSettings["PayPalAPISignature"] != null ? ConfigurationManager.AppSettings["PayPalAPISignature"].ToString() : ""); }
        }

        public static string PayPalBNCode
        {
            get { return (ConfigurationManager.AppSettings["PayPalBNCode"] != null ? ConfigurationManager.AppSettings["PayPalBNCode"].ToString() : ""); }
        }

        public static int PayPalTimeout
        {
            get { return int.Parse((ConfigurationManager.AppSettings["PayPalTimeout"] != null ? ConfigurationManager.AppSettings["PayPalTimeout"].ToString() : "-1")); }
        }

        public static string PayPalreturnURL
        {
            get { return (ConfigurationManager.AppSettings["PayPalreturnURL"] != null ? ConfigurationManager.AppSettings["PayPalreturnURL"].ToString() : ""); }
        }

        public static string PayPalcancelURL
        {
            get { return (ConfigurationManager.AppSettings["PayPalcancelURL"] != null ? ConfigurationManager.AppSettings["PayPalcancelURL"].ToString() : ""); }
        }
        #endregion
 }

Step 4- Create "NVPAPICaller" Class for all PayPal functions.
public class NVPAPICaller
{
    #region--Initialization--
    //Flag that determines the PayPal environment (live or sandbox)
    private bool bSandbox = AppSettings.IsSandbox;
    private const string CVV2 = "CVV2"; //AppSettings.CVV2;

    // Live strings.
    private string pEndPointURL = AppSettings.PaypalEndPointURL;
    private string host = AppSettings.Paypalhost;

    // Sandbox strings.
    private string pEndPointURL_SB = AppSettings.PaypalEndPointURL_SB;
    private string host_SB = AppSettings.Paypalhost_SB; //"www.sandbox.paypal.com";

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

    //Replace <Your API Username> with your API Username
    //Replace <Your API Password> with your API Password
    //Replace <Your Signature> with your Signature
    public string APIUsername = AppSettings.PayPalAPIUsername;
    private string APIPassword = AppSettings.PayPalAPIPassword;
    private string APISignature = AppSettings.PayPalAPISignature;
    private string Subject = "";
    private string BNCode = AppSettings.PayPalBNCode;


    //HttpWebRequest Timeout specified in milliseconds 
    private int Timeout = AppSettings.PayPalTimeout;
    private static readonly string[] SECURED_NVPS = new string[] { ACCT, CVV2, SIGNATURE, PWD };
    #endregion

    #region--Set Credencials--
    public void SetCredentials(string Userid, string Pwd, string Signature)
    {
        APIUsername = Userid;
        APIPassword = Pwd;
        APISignature = Signature;
    }
    #endregion

    #region--Short cut Express Checkout--
    public bool ShortcutExpressCheckout(string amt,string currency_code, ref string token, ref string retMsg)
    {
        if (bSandbox)
        {
            pEndPointURL = pEndPointURL_SB;
            host = host_SB;
        }

        string returnURL = AppSettings.PayPalreturnURL;
        string cancelURL = AppSettings.PayPalcancelURL;

        NVPCodec encoder = new NVPCodec();
        encoder["METHOD"] = "SetExpressCheckout";
        encoder["RETURNURL"] = returnURL;
        encoder["CANCELURL"] = cancelURL;
        encoder["BRANDNAME"] = "IDeal Feeds Sample Application";
        encoder["PAYMENTREQUEST_0_AMT"] = amt;
        encoder["PAYMENTREQUEST_0_ITEMAMT"] = amt;
        encoder["PAYMENTREQUEST_0_PAYMENTACTION"] = "Sale";
        encoder["PAYMENTREQUEST_0_CURRENCYCODE"] = currency_code;

        // Get the Shopping Cart Products
        //using (WingtipToys.Logic.ShoppingCartActions myCartOrders = new WingtipToys.Logic.ShoppingCartActions())
        //{
        //    List<CartItem> myOrderList = myCartOrders.GetCartItems();

        //    for (int i = 0; i < myOrderList.Count; i++)
        //    {
        //        encoder["L_PAYMENTREQUEST_0_NAME" + i] = myOrderList[i].Product.ProductName.ToString();
        //        encoder["L_PAYMENTREQUEST_0_AMT" + i] = myOrderList[i].Product.UnitPrice.ToString();
        //        encoder["L_PAYMENTREQUEST_0_QTY" + i] = myOrderList[i].Quantity.ToString();
        //    }
        //}

        encoder["L_PAYMENTREQUEST_0_NAME0"] = "IDeal Feed Signup";
        encoder["L_PAYMENTREQUEST_0_AMT0"] = amt;
        encoder["L_PAYMENTREQUEST_0_QTY0"] = "1";
        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;
            retMsg = ECURL;
            return true;
        }
        else
        {
            retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" +
                "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" +
                "Desc2=" + decoder["L_LONGMESSAGE0"];
            return false;
        }
    }
    #endregion

    #region--Get Check out Details--
    public bool GetCheckoutDetails(string token, ref string PayerID, ref NVPCodec decoder, ref string retMsg)
    {
        if (bSandbox)
        {
            pEndPointURL = pEndPointURL_SB;
        }

        NVPCodec encoder = new NVPCodec();
        encoder["METHOD"] = "GetExpressCheckoutDetails";
        encoder["TOKEN"] = token;

        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"))
        {
            PayerID = decoder["PAYERID"];
            return true;
        }
        else
        {
            retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" +
                "Desc=" + decoder["L_SHORTMESSAGE0"] + "&" +
                "Desc2=" + decoder["L_LONGMESSAGE0"];

            return false;
        }
    }
    #endregion

    #region--Do Checkout Payment--
    public bool DoCheckoutPayment(string finalPaymentAmount,string currency_code, string token, string PayerID, ref NVPCodec decoder, ref string retMsg)
    {
        if (bSandbox)
        {
            pEndPointURL = pEndPointURL_SB;
        }

        NVPCodec encoder = new NVPCodec();
        encoder["METHOD"] = "DoExpressCheckoutPayment";
        encoder["TOKEN"] = token;
        encoder["PAYERID"] = PayerID;
        encoder["PAYMENTREQUEST_0_AMT"] = finalPaymentAmount;
        encoder["PAYMENTREQUEST_0_CURRENCYCODE"] = currency_code;
        encoder["PAYMENTREQUEST_0_PAYMENTACTION"] = "Sale";

        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;
        }
    }
    #endregion

    #region--HttpCall--
    public string HttpCall(string NvpRequest)
    {
        string url = pEndPointURL;

        string strPost = NvpRequest + "&" + buildCredentialsNVPString();
        strPost = strPost + "&BUTTONSOURCE=" + HttpUtility.UrlEncode(BNCode);
        //No need of shipping
        strPost = strPost + "&NOSHIPPING="+HttpUtility.UrlEncode("1");
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        // Try using Tls11 if it doesnt works for you with Tls
        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)
        {
            // No logging for this tutorial.
        }

        //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();
        }

        return result;
    }
    #endregion

    #region--build Credentials NVP String--
    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"] = "88.0";

        return codec.Encode();
    }

    public static bool IsEmpty(string s)
    {
        return s == null || s.Trim() == string.Empty;
    }
    #endregion
}

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();

    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();
    }

    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);
            }
        }
    }

    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));
    }

    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 cannot be negative : " + index);
        }
        return name + index;
    }
}

Step 5- Create "Checkout" Folder

Step 6- Create following pages inside "Checkout" Folder
CheckoutCancel.aspx
CheckoutComplete.aspx
CheckoutError.aspx
CheckoutStart.aspx

Step 7- Create "CheckOutSummary.aspx" page
Add Image button for expess-checkout


                    <div id="paypalpay" style="display: none;">
                        <div class="form-group">
                            <div class="col-sm-offset-2 col-md-6">
                                <asp:ImageButton ID="btnCheckout" runat="server" ImageUrl="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"
                                    Width="145" AlternateText="Check out with PayPal"
                                    BackColor="Transparent" BorderWidth="0" OnClick="btnCheckout_Click" />
                            </div>
                        </div>
                    </div>

Button click code
    protected void btnCheckout_Click(object sender, ImageClickEventArgs e)
    {
        var plan = SubscriptionPlans.Instance.GetIDealFeedSubscriptionPlans(SubscriptionPlanID).FirstOrDefault();
        if (plan != null)
        {
            Session["payment_amt"] = "20";
            Session["currency_code"] = "USD"; 
            Response.Redirect("~/Checkout/CheckoutStart.aspx");
        }

    }

Step 8- Implement Other Pages


(i-) CheckoutStart.aspx (.cs page)
    protected void Page_Load(object sender, EventArgs e)
    {
        NVPAPICaller payPalCaller = new NVPAPICaller();
        string retMsg = "";
        string token = "";

        if ((Session["payment_amt"] != null) && (Session["currency_code"]!=null))
        {
            string amt = Session["payment_amt"].ToString();
            string currency_code= Session["currency_code"].ToString();
            bool ret = payPalCaller.ShortcutExpressCheckout(amt,currency_code, ref token, ref retMsg);
            if (ret)
            {
                Session["token"] = token;
                Response.Redirect(retMsg);
            }
            else
            {
                Response.Redirect("CheckoutError.aspx?" + retMsg);
            }
        }
        else
        {
            Response.Redirect("CheckoutError.aspx?ErrorCode=AmtMissing");
        }
    }

(ii-)CheckoutComplete.aspx page
 <div class="container main">
        <h1><span>Checkout Complete</span></h1>
        <div role="form" class="form-horizontal">
            <div class="form-group">
                <div class="col-md-2">
                    <label class="control-label">Payment Transaction ID:</label>
                </div>
                <div class="col-md-6">
                    <label class="control-label">
                        <asp:Label ID="TransactionId" CssClass="control-label" runat="server"></asp:Label>
                    </label>
                </div>
            </div>
        </div>
        <h3>Thank You!</h3>
        <div class="col-sm-2">
            <asp:LinkButton ID="lnkRedirectToDashBoard" CssClass="btn btn-primary btn-block" PostBackUrl="~/account/dashboard" runat="server">Go To DashBoard</asp:LinkButton>
        </div>
    </div>
.cs Page
 #region--Page Load--
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            VerifyPayment();
        }
    }
    #endregion
    
    #region--Verify Payment--
    public void VerifyPayment()
    {
        NVPAPICaller payPalCaller = new NVPAPICaller();
        string retMsg = "";
        string token = "";
        string PayerID = "";
        NVPCodec decoder = new NVPCodec();
        token = Session["token"].ToString();
        string currency_code = Session["currency_code"].ToString();
        bool ret = payPalCaller.GetCheckoutDetails(token, ref PayerID, ref decoder, ref retMsg);
        if (ret)
        {
            // Verify total payment amount as set on CheckoutStart.aspx.
            try
            {
                decimal paymentAmountOnCheckout = Convert.ToDecimal(Session["payment_amt"].ToString());
                decimal paymentAmoutFromPayPal = Convert.ToDecimal(decoder["AMT"].ToString());
                if (paymentAmountOnCheckout != paymentAmoutFromPayPal)
                {
                    Response.Redirect("CheckoutError.aspx?" + "Desc=Amount%20total%20mismatch.");
                }
            }
            catch (Exception)
            {
                Response.Redirect("CheckoutError.aspx?" + "Desc=Amount%20total%20mismatch.");
            }

        }
        string finalPaymentAmount = Session["payment_amt"].ToString();
        bool res = payPalCaller.DoCheckoutPayment(finalPaymentAmount, currency_code, token, PayerID, ref decoder, ref retMsg);
        if (res)
        {
            // Retrieve PayPal confirmation value.
            string PaymentConfirmation = decoder["PAYMENTINFO_0_TRANSACTIONID"].ToString();
            TransactionId.Text = PaymentConfirmation;
           
        }
        else
        {
            Response.Redirect("CheckoutError.aspx?" + retMsg);
        }
    }
    #endregion

(iii-) CheckoutError.aspx Page

<div id="Errorcode" class="text-danger">        
  Error Code:<%=Request.QueryString.Get("ErrorCode")%><br/>
  <%=Request.QueryString.Get("Desc")%><br/>
  <%=Request.QueryString.Get("Desc2")%>            
</div>

(iv-)CheckoutCancel.aspx
<div class="container main">
        <h1><span>Checkout Cancelled</span></h1>
        <div id="DivMsg" runat="server">
        </div>     
        <h3>Your payment has been canceled.</h3>
    </div>
That's it Initially CheckoutSummary.aspx page will execute & Session Variables are set for checkout execution.

   1 comment :

  1. This is good example, I wish you had uploaded Code as well as screenshot for the same. Very good example

    ReplyDelete

  • Popular Posts
  • Comments