Click here to Skip to main content
13,861,876 members
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

309.4K views
7.2K downloads
84 bookmarked
Posted 30 Jan 2015
Licenced CPOL

Using Paypal Rest API with ASP.NET MVC 4

, 25 May 2015
Rate this:
Please Sign up or sign in to vote.
Integrating Paypal in ASP.NET MVC 4

Introduction

This is my first ever article on CodeProject and it's about the use of Paypal REST API for payments. It's a world of eCommerce now and everyone wants to integrate Paypal in their website for accepting payments online for either their services of products they are selling. So, this article is about the Integration of PAYPAL REST API in an ASP.NET MVC 4 Framework. I am using this framework because it is a quick way to start on any good web application. I have commented my code as much as possible, so that you can understand what actually is happening in the code. Still if you are not able to understand, then you can ask me. I won't hesitate to help, if I am available.

Background

I have been searching for a good and up to date article or tutorials for the Paypal REST API usage for many days. I found some articles but they were either not very clear to understand or were mostly based on the old paypal webstandard methods. So, I decided to do it myself and finally, I have successfully used Paypal REST API in my projects for the payments and I am sharing that. I am not a PRO in web applications and I started a year ago only on websites and web apps. So, I am sorry if I missed anything.

I am using documentation references from paypal website here here.

PAYPAL REST API can be used for both payments using paypal or payments using the credit cards.

Pre-Requisites

  1. We need a facilitator Paypal account API credentials to be used in the web application.
  2. We need a buyer account. (You can get these accounts by registering on Paypal Developer website here https://developer.paypal.com for Free. So, Just register on the paypal developer website and create the test accounts to be used for testing purpose.)
  3. We also need Paypal SDK for .NET from here https://github.com/paypal/PayPal-NET-SDK or you can alternatively install from NuGet Package Manager (Recommended).
  4. A little knowledge is required to start with Visual Studio MVC 4 based project

For testing Paypal provides a Sandbox, where we can perform dummy transactions through our application.

Using the Code

Let's start.

So, first of all, open the Visual Studio IDE (I am using Visual Studio 2012) and create an ASP.NET MVC 4 project.

Now we need to install the PAYPAL SDK for .NET in our project. Let NuGet install it for you. This way, it is easier to add the SDK libraries to the project and is a recommended way especially for beginners.

So, Goto Tools -> Library Package Manager -> Package Manager Console. It will open a command console in the Visual Studio.

To add the Paypal SDK libraries in your project, use this command in the console:

Install-Package Paypal

Also, add log4net libraries using this command below using the same method as above. It is used by paypal libraries for logging.

Install-Package log4net

If the reference to the libraries are not automatically added, then you can add references to the DLLs manually by right clicking on the References in your project in Solution Explorer and Choosing Add Reference. Just browse the assembly and Select it. These are the assemblies which need to be referenced.

  • PayPal.dll
  • Newtonsoft.Json.dll
  • log4net.dll

Basically, the SDK uses json to communicate with the Paypal API that is why it installs the latest version of newtonsoft.json library. It installed version 6.xx.xx on my machine.

Now, we need to setup our web.config file with the configurations to be used.

So, open the web.config file and add the configurations as shown below.

Under the <configuration> tag in the web.config file, put these settings in. Notice that we have mode set to sandbox in the paypal settings. And then, you need to configure your paypal facilitator account details inside here i.e., clientID and clientSecret key. Get these from your developer paypal account. (If you don't have a paypal developer account, then you need to register for an account first on the paypal developer website here https://developer.paypal.com and create a facilitator/vendor account).

Then, from the settings of that account, you can get this clientID and clientSecret and enter them here under the paypal settings tag.

<configSections>
  <section name="paypal" type="PayPal.SDKConfigHandler, PayPal" />
  <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>

<!-- PayPal SDK settings -->
<paypal>
  <settings>
    <add name="mode" value="sandbox"/>
    <add name="connectionTimeout" value="360000"/>
    <add name="requestRetries" value="1"/>
    <add name="clientId" value="your client ID of paypal account"/>
    <add name="clientSecret" value="your client secret key of paypal account"/>
  </settings>
</paypal>

<!-- log4net settings -->
<log4net>
  <appender name="FileAppender" type="log4net.Appender.FileAppender">
    <file value="my_app.log"/>
    <appendToFile value="true"/>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date
      [%thread] %-5level %logger [%property{NDC}] %message%newline"/>
    </layout>
  </appender>
  <root>
    <level value="DEBUG"/>
    <appender-ref ref="FileAppender"/>
  </root>
</log4net>

<appSettings>
  <add key="PayPalLogger" value="PayPal.Log.Log4netLogger"/>
</appSettings>

<system.web>
 <trust level="High" />
</system.web>

Second, we are ready to write the C# code to make the calls to the paypal API now after adding the needed SDK libraries and adding their references in it.

So, first of all, add a controller in the controllers namespace and give any name you like to this controller. I gave PaypalController.cs.

When you add a controller, there is a default Action Index created by the IDE for you. You need to add a new Action named PaymentWithCreditCard.

Steps that are performed in the controller are listed below:

  1. Create Payment object with all the items and billing details
  2. Get access token using the GetApiContext call
  3. Call function Create of the payment class

Add the action PaymentWithCreditCard to this controller as below:

public ActionResult PaymentWithCreditCard()
{
            //create and item for which you are taking payment
            //if you need to add more items in the list
            //Then you will need to create multiple item objects or use some loop to instantiate object
            Item item = new Item();
            item.name = "Demo Item";
            item.currency = "USD";
            item.price = "5";
            item.quantity = "1";
            item.sku = "sku";

            //Now make a List of Item and add the above item to it
            //you can create as many items as you want and add to this list
            List<Item> itms = new List<Item>();
            itms.Add(item);
            ItemList itemList = new ItemList();
            itemList.items = itms;

            //Address for the payment
            Address billingAddress = new Address();
            billingAddress.city = "NewYork";
            billingAddress.country_code = "US";
            billingAddress.line1 = "23rd street kew gardens";
            billingAddress.postal_code = "43210";
            billingAddress.state = "NY";


            //Now Create an object of credit card and add above details to it
            //Please replace your credit card details over here which you got from paypal
            CreditCard crdtCard = new CreditCard();
            crdtCard.billing_address = billingAddress;
            crdtCard.cvv2 = "874";  //card cvv2 number
            crdtCard.expire_month = 1; //card expire date
            crdtCard.expire_year = 2020; //card expire year
            crdtCard.first_name = "Aman";
            crdtCard.last_name = "Thakur";
            crdtCard.number = "1234567890123456"; //enter your credit card number here
            crdtCard.type = "visa"; //credit card type here paypal allows 4 types

            // Specify details of your payment amount.
            Details details = new Details();
            details.shipping = "1";
            details.subtotal = "5";
            details.tax = "1";

            // Specify your total payment amount and assign the details object
            Amount amnt = new Amount();
            amnt.currency = "USD";
            // Total = shipping tax + subtotal.
            amnt.total = "7";
            amnt.details = details;

            // Now make a transaction object and assign the Amount object
            Transaction tran = new Transaction();
            tran.amount = amnt;
            tran.description = "Description about the payment amount.";
            tran.item_list = itemList;
            tran.invoice_number = "your invoice number which you are generating";

            // Now, we have to make a list of transaction and add the transactions object
            // to this list. You can create one or more object as per your requirements

            List<Transaction> transactions = new List<Transaction>();
            transactions.Add(tran);

            // Now we need to specify the FundingInstrument of the Payer
            // for credit card payments, set the CreditCard which we made above

            FundingInstrument fundInstrument = new FundingInstrument();
            fundInstrument.credit_card = crdtCard;

            // The Payment creation API requires a list of FundingIntrument

            List<FundingInstrument> fundingInstrumentList = new List<FundingInstrument>();
            fundingInstrumentList.Add(fundInstrument);

            // Now create Payer object and assign the fundinginstrument list to the object
            Payer payr = new Payer();
            payr.funding_instruments = fundingInstrumentList;
            payr.payment_method = "credit_card";

            // finally create the payment object and assign the payer object & transaction list to it
            Payment pymnt = new Payment();
            pymnt.intent = "sale";
            pymnt.payer = payr;
            pymnt.transactions = transactions;

            try
            {
               //getting context from the paypal
               //basically we are sending the clientID and clientSecret key in this function
               //to the get the context from the paypal API to make the payment
               //for which we have created the object above.

               //Basically, apiContext object has a accesstoken which is sent by the paypal
               //to authenticate the payment to facilitator account.
               //An access token could be an alphanumeric string

                APIContext apiContext = Configuration.GetAPIContext();

               //Create is a Payment class function which actually sends the payment details
               //to the paypal API for the payment. The function is passed with the ApiContext
               //which we received above.

                Payment createdPayment = pymnt.Create(apiContext);

               //if the createdPayment.state is "approved" it means the payment was successful else not

               if(createdPayment.state.ToLower() != "approved")
               {
                     return View("FailureView");
               }
            }
            catch (PayPal.PayPalException ex)
            {
                Logger.Log("Error: "+ex.Message);
                return View("FailureView");
            }

            return View("SuccessView");
}

The above controller tries to make a direct payment with a credit card from your website. You can see there are multiple lists objects created above and assigned for the payment. This is the necessary data required by paypal to make the payment using Credit Cards.

Code for the configuration class which is used in the above controller action. You need to make this class in the namespace which you want. I am adding it in Models. Usually in Models namespace, we keep those classes which are used to pass data to the Views. So, you can add your new namespace as well if you want and add this class to that namespace. It's all your choice.

public static class Configuration
{
        //these variables will store the clientID and clientSecret
        //by reading them from the web.config
        public readonly static string ClientId;
        public readonly static string ClientSecret;

        static Configuration()
        {
            var config = GetConfig();
            ClientId = config["clientId"];
            ClientSecret = config["clientSecret"];
        }

        // getting properties from the web.config
        public static Dictionary<string, string> GetConfig()
        {
            return PayPal.Manager.ConfigManager.Instance.GetProperties();
        }

        private static string GetAccessToken()
        {
            // getting accesstocken from paypal                
            string accessToken = new OAuthTokenCredential
        (ClientId, ClientSecret, GetConfig()).GetAccessToken();

            return accessToken;
        }

        public static APIContext GetAPIContext()
        {
            // return apicontext object by invoking it with the accesstoken
            APIContext apiContext = new APIContext(GetAccessToken());
            apiContext.Config = GetConfig();
            return apiContext;
        }
}

Now you can try paying on your website using a test Paypal credit card. Or you can first make the PaymentWithPaypal action and try both of these at once like I am doing here.

Third, now we have already created a controller for the Credit Card payments above. It's time to create the controller for the Paypal Account payments using the Paypal REST API.

The procedure of making payments using paypal account is slightly different than making the payments using the credit cards directly.

Steps that are performed in the controller are listed below:

  1. Get the Access Token by getting the APIContext
  2. Call the function Create of Payment class with apiContext
  3. Execute Payment

Add the Action PaymentWithPaypal as below:

public ActionResult PaymentWithPaypal()
{
     //getting the apiContext as earlier
     APIContext apiContext = Configuration.GetAPIContext();

     try
     {
          string payerId = Request.Params["PayerID"];

          if (string.IsNullOrEmpty(payerId))
          {
            //this section will be executed first because PayerID doesn't exist
            //it is returned by the create function call of the payment class

            // Creating a payment
            // baseURL is the url on which paypal sendsback the data.
            // So we have provided URL of this controller only
            string baseURI = Request.Url.Scheme + "://" + Request.Url.Authority + 
                        "/Paypal/PaymentWithPayPal?";

            //guid we are generating for storing the paymentID received in session
            //after calling the create function and it is used in the payment execution

            var guid = Convert.ToString((new Random()).Next(100000));

            //CreatePayment function gives us the payment approval url
            //on which payer is redirected for paypal account payment

            var createdPayment = this.CreatePayment(apiContext, baseURI + "guid=" + guid);

            //get links returned from paypal in response to Create function call

            var links = createdPayment.links.GetEnumerator();

            string paypalRedirectUrl = null;

            while (links.MoveNext())
            {
                 Links lnk = links.Current;

                 if (lnk.rel.ToLower().Trim().Equals("approval_url"))
                 {
                       //saving the payapalredirect URL to which user will be redirected for payment
                       paypalRedirectUrl = lnk.href;
                 }
            }

            // saving the paymentID in the key guid
            Session.Add(guid, createdPayment.id);

            return Redirect(paypalRedirectUrl);
          }
          else
          {
            // This section is executed when we have received all the payments parameters

            // from the previous call to the function Create

            // Executing a payment

            var guid = Request.Params["guid"];

            var executedPayment = ExecutePayment(apiContext, payerId, Session[guid] as string);

            if(executedPayment.state.ToLower() != "approved")
            {
                 return View("FailureView");
            }
          }
     }
     catch(Exception ex)
     {
          Logger.log("Error"+ ex.Message);
          return View("FailureView");
     }

     return View("SuccessView");
}

Execute payment function used in the controller PaymentWithPaypal using a global variable named payment. It is basically using the function Execute of the Payment class of Paypal SDK.

private PayPal.Api.Payment payment;

private Payment ExecutePayment(APIContext apiContext, string payerId, string paymentId)
{
     var paymentExecution = new PaymentExecution() { payer_id = payerId };
     this.payment = new Payment() { id = paymentId };
     return this.payment.Execute(apiContext, paymentExecution);
}

CreatePayment function is used in the controller PaymentWithPaypal for making the payment. Basically, in this function, we are adding the Items for which the payment is being created.

private Payment CreatePayment(APIContext apiContext, string redirectUrl)
{

            //similar to credit card create itemlist and add item objects to it
            var itemList = new ItemList() { items = new List<Item>() };

            itemList.items.Add(new Item()
            {
                name = "Item Name",
                currency = "USD",
                price = "5",
                quantity = "1",
                sku = "sku"
            });

            var payer = new Payer() { payment_method = "paypal" };

            // Configure Redirect Urls here with RedirectUrls object
            var redirUrls = new RedirectUrls()
            {
                cancel_url = redirectUrl,
                return_url = redirectUrl
            };

            // similar as we did for credit card, do here and create details object
            var details = new Details()
            {
                tax = "1",
                shipping = "1",
                subtotal = "5"
            };

            // similar as we did for credit card, do here and create amount object
            var amount = new Amount()
            {
                currency = "USD",
                total = "7", // Total must be equal to sum of shipping, tax and subtotal.
                details = details
            };

            var transactionList = new List<Transaction>();

            transactionList.Add(new Transaction()
            {
                description = "Transaction description.",
                invoice_number = "your invoice number",
                amount = amount,
                item_list = itemList
            });

            this.payment = new Payment()
            {
                intent = "sale",
                payer = payer,
                transactions = transactionList,
                redirect_urls = redirUrls
            };

            // Create a payment using a APIContext
            return this.payment.Create(apiContext);
}

That's it. You are done with Paypal. Now, it's time to make the View Page.

Remember, we have an Index action in the Paypal Controller as I mentioned above. Now, we will make a view for that page. We will put 2 links in that page and link them to the PaymentWithCreditCard and PaymentWithPaypal actions.

  1. Pay Direct with Credit Card
  2. Pay with Paypal Account

So, right click on Index action in the code and select Add View.

In the View Code, add this Razor code as below. (Razor is the rendering engine and it responsible for rendering dynamic pages of an ASP.NET application.)

@Html.ActionLink("Pay Direct With Credit Card","PaymentWithCreditCard","Paypal")
@Html.ActionLink("Pay with Paypal Account", "PaymentWithPaypal", "Paypal")

Also, add the SuccessView and FailureView under the Paypal folder in the Views from the solution explorer. These views are returned upon the successful or failed transactions of Paypal. So, these views are used in both the actions we have made.

Now, let's test the application. Run your web application in the web browser now. And load the Paypal Index action. You just need to append the URL of the web application and add "/Paypal" at the end of that URL.

As soon as you hit enter, it will execute the Index action because Index is the default action of any controller in MVC. If you have a little knowledge about the routing in MVC, then you must know that the default route of the web application is URL/Controller/Action/id. We append Paypal to the URL because that is the controller name here we have made.

We have not provided any Action name in the URL so, it will load the default action which is INDEX and will return the View as below:

Now, click on the first option Pay Direct With Credit Card. Try using a debug breakpoint in the action PaymentWithCreditCard, if you want to understand better. Below is the accesstoken returned by Paypal for the credit card payment which will be used for creating the payment.

If you are encountering any assembly error, like in the below image:

Then, just add the namespace in your code file as "using PayPal.Api;". The errors will go away. Logger is my class which I have made for logging the exceptions. You will find the source code.

So, as soon as the transaction is finished from Paypal, you will be shown the SuccessView.

Now, let's test the payment with Paypal. Load the same URL as before. In my case, it is localhost:6016/Paypal so check yours and load. This time, select Pay with Paypal Account and put a Breakpoint in the action PaymentWithPaypal for better understanding.

As soon as the action gets the accesstoken from Paypal, the action sends the URL to Paypal on which paypal will return the data. As soon as the createpayment function is called, Paypal returns payment approval_url of the user as seen below.

Approval_url is the URL on which you need to redirect the user for paying.

As soon as the user authenticates and confirms the payment, the paypal will send the payerID and related data which we can use to execute the payment via Paypal Account and you will see the successview again.

That's it!!

If you have any queries, feel free to ask. I will help you...:)

FOR RECURRING PAYMENTS WITH PAYPAL SEE MY TIP: HERE

Points of Interest

PAYPAL REST API is more advanced than the classical methods of Paypal. It was fast learning using the REST API. So, you might enjoy integrating Paypal with REST.

History

  • 30th January, 2015: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Aman Thakur
Software Developer
India India
I am a Software developer. I mainly work on Desktop applications using .NET framework and Web Application using MVC framework.

You may also be interested in...

Pro

Comments and Discussions

 
Questionlogger Pin
Member 140820158-Dec-18 11:00
memberMember 140820158-Dec-18 11:00 
QuestionError en el servidor remoto: (401) No autorizado. Pin
Yamil Quesada 23-Oct-18 16:40
memberYamil Quesada 23-Oct-18 16:40 
GeneralBest Article Pin
Member 139770067-Sep-18 13:38
memberMember 139770067-Sep-18 13:38 
QuestionNeed your help Pin
Member 1252731716-Aug-18 20:02
memberMember 1252731716-Aug-18 20:02 
QuestionMessage Closed Pin
10-Aug-18 0:23
memberMember 1265673110-Aug-18 0:23 
QuestionBad Request Error Pin
Er. Bhavesh Patel13-Jul-18 0:41
memberEr. Bhavesh Patel13-Jul-18 0:41 
QuestionGetting data from shopping cart to createpayment ? Pin
Sigmond Gatt19-Apr-18 3:52
memberSigmond Gatt19-Apr-18 3:52 
QuestionPaymentWithCreditCard() does not work Pin
Member 1377987317-Apr-18 19:52
memberMember 1377987317-Apr-18 19:52 
Questionerror Pin
Member 137146257-Mar-18 21:03
memberMember 137146257-Mar-18 21:03 
QuestionDoes anyone know if this still works today 2018? Pin
ctallos3-Mar-18 16:14
memberctallos3-Mar-18 16:14 
QuestionExecute payment function is not working Pin
Sumit Ruhela30-Jan-18 3:47
memberSumit Ruhela30-Jan-18 3:47 
Questionpaypal sdk setting Pin
xllRyan25-Dec-17 17:39
memberxllRyan25-Dec-17 17:39 
Questionhow does your payment with credit card directly works? Pin
xllRyan25-Dec-17 17:40
memberxllRyan25-Dec-17 17:40 
QuestionThe given key was not present in the dictionary. Pin
trankietcth1326-Nov-17 18:30
membertrankietcth1326-Nov-17 18:30 
GeneralMy vote of 5 Pin
Member 134417322-Oct-17 11:52
memberMember 134417322-Oct-17 11:52 
QuestionCredit Card Information Pin
UnStable Messi24-Sep-17 3:38
memberUnStable Messi24-Sep-17 3:38 
QuestionGreat post Pin
Member 1332154126-Jul-17 1:06
memberMember 1332154126-Jul-17 1:06 
Questioni need help related to web.config file Pin
Member 1265673121-Jun-17 2:06
memberMember 1265673121-Jun-17 2:06 
Questionim facing error at Logger.Log("Error: " + ex.Message); Pin
psoms5-Jun-17 22:06
memberpsoms5-Jun-17 22:06 
QuestionFacing four Error while integrating above code Pin
Member 1322583127-May-17 2:42
memberMember 1322583127-May-17 2:42 
AnswerRe: Facing four Error while integrating above code Pin
psoms5-Jun-17 23:49
memberpsoms5-Jun-17 23:49 
BugNo Working Pin
rjmattos@yahoo.com.br12-May-17 23:39
memberrjmattos@yahoo.com.br12-May-17 23:39 
QuestionError: Could not Load file or asssembly Pin
Member 1319089611-May-17 6:16
memberMember 1319089611-May-17 6:16 
Question401{"error":"invalid_client","error_description":"Client Authentication failed"}exception Pin
Member 1295898420-Apr-17 21:37
memberMember 1295898420-Apr-17 21:37 
AnswerRe: 401{"error":"invalid_client","error_description":"Client Authentication failed"}exception Pin
mahmoud mohammed20-Aug-17 0:02
membermahmoud mohammed20-Aug-17 0:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web06 | 2.8.190214.1 | Last Updated 25 May 2015
Article Copyright 2015 by Aman Thakur
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid