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