PayPal Payment Gateway Integration (In-Context Checkout) in ASP.NET MVC

Views: 1204
Comments: 11
Like/Unlike: 0
Posted On: 06-Feb-2016 08:24 

Share:   fb twitter linkedin
Rahul M...
Moderator
138 Points
14 Posts

Introduction

PayPal is a web-based billing platform that provides api for online payment. In this article we will try to learn how to integrate in-context checkout in ASP.NET MVC application. It consists two part first creating developer sandbox account (for merchant and buyer) and second is using this sandbox account we integrate the PayPal Payment gateway. In this article we will concentrate on only on second part. Let's see how can we integrate it.
After integration you will see the following screens:

What is In-Context Checkout

In-Context checkout is a express checkout in which user can login to the paypal without leaving the current website. So, you can provide better experience to the user without leaving the website.

Requirement

You have to create developer account (Sandbox test account) and so that you can use API credential  UserName, Password and Signature in the integration. ASP.NET MVC 5.0

How to Integate in-context checkout

  1. API Credential
  2. Create PayPalSettings class
  3. Create PayPal model class (core implementation)
  4. Create Cart Controller and respected views

i) API Credential

Add the follwing key into the web.config as:

<add key="PayPal:Sandbox" value="True" />
<add key="PayPal:Username" value="<UserName from mechant account>" />
<add key="PayPal:Password" value="<Password from merchange account>" />
<add key="PayPal:Signature" value="<signature from merchant account>" />
<add key="PayPal:ReturnUrl" value="https://localhost:1588/Cart/CheckoutReview" />
<add key="PayPal:CancelUrl" value="https://localhost:1588/Cart/CheckoutReview" />
<add key="PayPal:MerchantAccountID" value="<MechantaccountID from merchant account" />
<!--sandbox/production-->
<add key="PayPal:Environment" value="sandbox" />

In above returnurl and cancelurl change account to your port and put the api credential here.


ii) Create PayPalSettings class

It is use to get access the setting from the config file. create class as:

using System;
using System.Configuration;
using System.ComponentModel;
using System.Globalization;
namespace MvcApplication1.Models
public class PayPalSettings
public static string ApiDomain
get
return Setting<bool>("PayPal:Sandbox") ? "api-3t.sandbox.paypal.com":"api-3t.paypal.com";
}
}
 
public static string CgiDomain
get
return Setting<bool>("PayPal:Sandbox") ? "www.sandbox.paypal.com" : "www.paypal.com";
}
}
 
public static string Signature
get
return Setting<string>("PayPal:Signature");
}
}
 
public static string Username
get
return Setting<string>("PayPal:Username");
}
}
 
public static string Password
get
return Setting<string>("PayPal:Password");
}
}
 
public static string ReturnUrl
get
return Setting<string>("PayPal:ReturnUrl");
}
}
 
public static string CancelUrl
get
return Setting<string>("PayPal:CancelUrl");
}
}
 
public static string MerchantAccountID
get
return Setting<string>("PayPal:MerchantAccountID");
}
}
 
public static string Environment
get
return Setting<string>("PayPal:Environment");
}
}
 
private static T Setting<T>(string name)
string value = ConfigurationManager.AppSettings[name]; 
if (value == null)
throw new Exception(String.Format("Could not find setting '{0}',", name));
return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture);
}
}
}

 


iii) Create PayPal model class (core implementation)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.Specialized;
using System.Net;
using System.IO;
using System.Globalization;
using System.Text;
namespace MvcApplication1.Models
public class PayPal
public static PayPalRedirect ExpressCheckout(PayPalOrder order)
NameValueCollection values = new NameValueCollection();
values["METHOD"] = "SetExpressCheckout";
values["RETURNURL"] = PayPalSettings.ReturnUrl;
values["CANCELURL"] = PayPalSettings.CancelUrl;
values["PAYMENTACTION"] = "SALE";
values["CURRENCYCODE"] = "USD";
values["BUTTONSOURCE"] = "PP-ECWizard";
values["USER"] = PayPalSettings.Username;
values["PWD"] = PayPalSettings.Password;
values["SIGNATURE"] = PayPalSettings.Signature;
values["SUBJECT"] = "";
values["VERSION"] = "93";
values["BRANDNAME"] = "BRANDNAME1";
values["AMT"] = order.Amount.ToString();
values = Submit(values); 
 
string ack = values["ACK"].ToLower();
 
if (ack == "success" || ack == "successwithwarning")
return new PayPalRedirect
{
Token = values["TOKEN"],
Url =String.Format(https://{0}/cgi-bin/webscr?cmd=_express-checkout&token={1}, PayPalSettings.CgiDomain, values["TOKEN"])
};
else
throw new Exception(values["L_LONGMESSAGE0"]);
}
}
 
private static NameValueCollection Submit(NameValueCollection values)
{
 string data = String.Join("&", values.Cast<string>().Select(key =>String.Format("{0}={1}", key, values[key]))); 
ServicePointManager.Expect100Continue = true; 
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3; 
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(String.Format("https://{0}/nvp", PayPalSettings.ApiDomain));
request.Method ="POST";
request.KeepAlive =false;
 
byte[] byteArray = Encoding.UTF8.GetBytes(data);
request.ContentType ="application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
 
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
 
using (StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream()))
return HttpUtility.ParseQueryString(reader.ReadToEnd());
}
}
 
public static bool GetCheckoutDetails(string token, ref string PayerID, ref string retMsg)
NameValueCollection values = new NameValueCollection();
values["METHOD"] = "GetExpressCheckoutDetails";
values["TOKEN"] = token;
values["USER"] = PayPalSettings.Username;
values["PWD"] = PayPalSettings.Password;
values["SIGNATURE"] = PayPalSettings.Signature;
values["SUBJECT"] = "";
values["VERSION"] = "93";
values = Submit(values); 
 
string ack = values["ACK"].ToLower();
 
if (ack == "success" || ack == "successwithwarning")
{
PayerID = values["PayerID"]; 
return true;
else
{
retMsg ="ErrorCode=" + values["L_ERRORCODE0"] + "&" +
"Desc=" + values["L_SHORTMESSAGE0"] + "&" + 
"Desc2=" + values["L_LONGMESSAGE0"];
 
return false;
}
}
 
public static bool DoCheckoutPayment(string finalPaymentAmount, string token, string PayerID, ref string retMsg)
NameValueCollection values = new NameValueCollection();
values["METHOD"] = "DoExpressCheckoutPayment";
values["TOKEN"] = token;
values["PAYERID"] = PayerID;
values["PAYMENTREQUEST_0_AMT"] = finalPaymentAmount;
values["PAYMENTREQUEST_0_CURRENCYCODE"] = "USD";
values["PAYMENTREQUEST_0_PAYMENTACTION"] = "Sale";
values["USER"] = PayPalSettings.Username;
values["PWD"] = PayPalSettings.Password;
values["SIGNATURE"] = PayPalSettings.Signature;
values["SUBJECT"] = "";
values["VERSION"] = "93";
values = Submit(values); 
 
string ack = values["ACK"].ToLower();
 
if (ack == "success" || ack == "successwithwarning")
{
retMsg = values["PAYMENTINFO_0_TRANSACTIONID"].ToString(); ; 
return true;
else
{
retMsg ="ErrorCode=" + values["L_ERRORCODE0"] + "&" + 
"Desc=" + values["L_SHORTMESSAGE0"] + "&" + 
"Desc2=" + values["L_LONGMESSAGE0"]; 
return false;
}
}
}
 
public class PayPalOrder
public decimal? Amount { get; set; } 
public string OrderId { get; set; } 
public string ReturnUrl { get; set; } 
public string CancelUrl { get; set; }
}
 
public class PayPalRedirect
{
 public string Url { get; set; } 
public string Token { get; set; }
}
}

 
iv) Create Cart Controller and respected views 

Cart Controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
public class CartController : Controller
{
[HttpGet] 
public JsonResult PayPaltoken()
string strGUID = (Session["TicketLockedId"] != null ? Session["TicketLockedId"].ToString() : ""); 
PayPalOrder objPay = new PayPalOrder();
objPay.Amount = 10;
objPay.OrderId ="OT122"; 
PayPalRedirect redirect = PayPal.ExpressCheckout(objPay); 
return Json(redirect.Token, JsonRequestBehavior.AllowGet);
}
 
public ActionResult ProductOrder()
return View();
}
 
public ActionResult CheckoutReview(string token, string PayerID)
string retMsg = ""; 
string PayerID1 = ""; 
PayPal.GetCheckoutDetails(token, ref PayerID1, ref retMsg);
ViewData["ReturnMessage"] = retMsg;
ViewData["token"] = token;
ViewData["PayerID"] = PayerID1; 
return View();
}
 
public ActionResult DoCheckoutPayment(string token, string PayerID)
string retMsg = ""; 
PayPal.DoCheckoutPayment("10", token, PayerID, ref retMsg);
ViewData["ReturnMessage"] = retMsg; 
return View();
}
}
}

 ProductOrder view:

@{
ViewBag.Title ="ProductOrder";
Layout ="~/Views/Shared/_Layout.cshtml";
}
<script src="//www.paypalobjects.com/api/checkout.js" async></script>
<h2>ProductOrder</h2>
@using (Html.BeginForm())
<button name="btPaypal" id="btPaypal" type="button">Express Check Out</button>
}
<script type="text/javascript">
window.paypalCheckoutReady =function () {
paypal.checkout.setup("@MvcApplication1.Models.PayPalSettings.MerchantAccountID", {
environment:'@MvcApplication1.Models.PayPalSettings.Environment',
click:function (event) {
event.preventDefault();
paypal.checkout.initXO();
$.support.cors =true;
$.ajax({
type:"GET",
async:true,
crossDomain:true, 
//Load the minibrowser with the redirection url in the success handler
success:function (token) { 
var url = paypal.checkout.urlPrefix + token; 
//Loading Mini browser with redirect url, true for async AJAX calls
paypal.checkout.startFlow(url);
},
error:function (responseData, textStatus, errorThrown) {
alert("Something going wrong "); 
//Gracefully Close the minibrowser in case of AJAX errors
paypal.checkout.closeFlow();
}
});
},
button: ['btPaypal']
});
}
</script>

CheckoutReview View:

@{
ViewBag.Title ="CheckoutReview";
Layout ="~/Views/Shared/_Layout.cshtml";
}
<h2>CheckoutReview</h2>
@ViewData["ReturnMessage"]
<a href="@Url.Action("DoCheckoutPayment","Cart",new {token=ViewData["token"],PayerID=ViewData["PayerID"] })">Confirm Payment</a>

DoCheckoutPayment:

@{
ViewBag.Title ="DoCheckoutPayment";
Layout ="~/Views/Shared/_Layout.cshtml";
}
<h2>DoCheckoutPayment</h2>
@ViewData["ReturnMessage"]

_Layout View:

<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8" /> 
<meta name="viewport" content="width=device-width" /> 
<title>@ViewBag.Title</title> 
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
</head>
<body>
@RenderBody()
</body>
</html>

Debug and test the application

Now your test application is ready to test in-context checkout. Now run visual studio in debug mode. open the url /Cart/ProductOrder. You can see the following screen as:

Now click on the Express Checkout button. A popup window open as:

Put the buyer account credential here and click continue. Now you can see the next window review window as:

Now you can cofirm to final payment. After confirm button click final payment will be done. Now you can check the test account for respected change.

Conclusion

In the above discusion we try to understand how to integrate in-context checkout in ASP.NET MVC. I hope it will help you.

 

11 Comments

Priya
helpful for me...

Ahmed
Hi Rahul, I'm trying to work through this example. Your code isn't compiling in the PayPal class.

Ahmed
The error is at if (ack == "success" || ack == "successwithwarning") { return new PayPalRedirect { Token = values["TOKEN"], Url =String.Format(https://{0}/cgi-bin/webscr?cmd=_express-checkout&token={1}, PayPalSettings.CgiDomain, values["TOKEN"]) }; }

Ahmed
}; expected )

Ahmed
Please assist

Ahmed
I fixed my issue but now I'm getting the following error message when it tries to run the $.support.cors = true;

Ahmed
Error Message: 0x800a138f - JavaScript runtime error: Unable to get property 'support' of undefined or null reference

Ahmed
Fixed my issue. How can one close the paypal window and return to the "ReturnURL" in the main window?

Ahmed
after the customer has closed or paid?

Rahul Maurya
hi Ahmed, I think you have fixed all issued. You can put a link button to the payment completion view page 'DoCheckoutPayment' to go whatever want to go.

Rahul Maurya
The config key 'PayPal:CancelUrl' work when some error in Paypal box initialization or user cancel or close the box
  
banner

Blog

Active User (2)

 Log In to Chat