Simple way to integrate PayPal into your C# web app

The purpose of this post is to provide a crash course in PayPal integration. Simply put, if your web application is close to being released to the public and you’re looking for a fast-and-safe way to provide your customers with an option for purchasing your services, then this blog post might be what you need.

Integrating PayPal with a web application can be anywhere from amazingly simple to frustratingly complex, depending on what services you are planning to use. To this end, I’m going to illustrate a quick and easy way to integrate a PayPal Express payment system into a C# application.

For a start, you’ll need to register with PayPal. To do this, access https://sandbox.paypal.com and create a free development account. This will be your master account, with 2 additional accounts being required for testing: a test-buyer-account and a test-merchant-account. It’s important to use valid email addresses, as you might want to verify their inboxes for confirmation of payment messages.

Your master account allows you to monitor transactions between the 2 test accounts, ensuring that the payment is handled correctly. It also offers a central management console for all your test accounts. Keep in mind that you’ll have to add some “money” to the buyer’s virtual wallet (this is all test data). No money changes hands until you switch the system from sandbox to production. By that time, however, you’re on the receiving end, so that shouldn’t be a problem.

Once you have these little administrative tasks over and done with, we can get started with the actual integration. Here’s a basic check list of what we’ll need to cover in order to get the payment system up and running:

A. Understand the purchase data flow, to and from PayPal.
B. Create a PayPal control in the checkout page, and the logic behind sending and collecting data from PayPal.
C. Process the PayPal response, to acknowledge confirmation of payment for your products / receiving the 2 buyer specific tokens.
D. Pass the received tokens back to PayPal for purchase approval.
E. Simple error handling.

A. Payment flow

The basic flow is relatively simple: You pass data to PayPal via a your web app’s checkout page (such as the merchant ID that will receive the payment, product name and description, the amount, currency, tax, return URL on confirmation or cancel and so on). The buyer is then taken to the PayPal payment portal and a payment confirmation is requested.

Once payment is accepted by your customer, the PayPal portal takes the user back to the redirect URL specified in the call and sends back the transaction tokens and PayerID.

These tokens do not represent acknowledgement of payment, however. Both are returned even if the user cancels the operation, but in that case, your application distinguishes between user actions via the return URL.

If the payment is confirmed on the client side, you’ll use the 2 tokens to request the actual payment once the order has been successfully submitted on your side. This way, the system is notified that the user actually went through the correct purchase flow on your side (and this minimizes the risk of fraud, both on the vendor and buyer sides).

Now, we’ll look at how to actually insert a PayPal button in a C# application, along with the necessary steps for a successful call to the API.

To this end, we’ll use the code from a small sample project, containing the bare minimum that is needed to illustrate the process. To keep things simple, the data appended to the NVP string is hardcoded. This string is used to send the required information to the PayPal API, however you’ll want to populate the string dynamically – unless your company is selling flat rate services… at which point it’s still a bad idea to do this 🙂

So let’s see the code. Try to follow along with the explanation (and post any questions you have in a comment please)

namespace PayPal_Sample_Project
{
public partial class _Default : System.Web.UI.Page
 {
    protected void Page_Load(object sender, EventArgs e)
    {
       if (!Page.IsPostBack && !string.IsNullOrEmpty(Request.QueryString["PayerID"])) // On page load, the application searches for the PayerID.  This will be provided when returning from the PayPal portal along with a transaction token. This token is generated when the call is made and will be sent  regardless if the transaction is completed on PayPal's side or if the purchase was cancelled. It is nothing more than a tracking ID used by PayPal for a specific session.
       {
           lblPayPalSuccess.Visible = true;
           btnPayPalExpressCheckout.Visible = false;
       }
    }

   // Lets see what happens when you click the PayPal button in the page:
   protected void btnPayPalExpressCheckout_Click(object sender, EventArgs e)
   {
       string endpoint = "https://api-3t.sandbox.paypal.com/nvp";
       string redirectUrl = "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={0}";
       // This are the URLs the PayPal process uses. The endpoint URL is created using the NVP string generated below while the redirect url is where the page the user will navigate to when leaving PayPal plus the PayerID and the token the API returns when the request is made.
            
       string NVP = string.Empty;
 
       // API call method: add the desired checkout method. As I've mentioned above, we're using the express checkout.
       NVP += "METHOD=SetExpressCheckout";  
       NVP += "&VERSION=123";

       // Credentials identifying you as the merchant
       NVP += "&USER=Your_Test_Merchant_Account_User";
       NVP += "&PWD=Your_Test_Account_Password";
       NVP += "&SIGNATURE=Your_Test_Account_Signature";
 
       // Redirect from PayPal portal
       NVP += "&RETURNURL=" + Request.Url.AbsoluteUri;   // Return URL from the PayPal portal for completed payment
       NVP += "&CANCELURL=" + Request.Url.AbsoluteUri;   // Return URL from the PayPal portal for a cancelled purchase
            
       // Payment request information
       NVP += "&PAYMENTREQUEST_0_PAYMENTACTION=Sale";   // Type of transaction
       NVP += "&PAYMENTREQUEST_0_AMT=100";                 // Total payment for the transaction   
       NVP += "&PAYMENTREQUEST_0_ITEMAMT=80";             // Purchased product price
       NVP += "&PAYMENTREQUEST_0_SHIPPINGAMT=10";         // Shipping amount
       NVP += "&PAYMENTREQUEST_0_HANDLINGAMT=5";         // Handling charges
       NVP += "&PAYMENTREQUEST_0_TAXAMT=5";             // Tax amount
 
       // Products involved in the transaction
       NVP += "&L_PAYMENTREQUEST_0_NAME0=Sample Product";                // Product name
       NVP += "&L_PAYMENTREQUEST_0_DESC0=This is a sample product";    // Product description
       NVP += "&L_PAYMENTREQUEST_0_AMT0=80";                            // Product price
       NVP += "&L_PAYMENTREQUEST_0_QTY0=1";                            // Product quantity
            
       // Make the API call to the PayPal Service
       HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endpoint);
       request.Method = "POST";
       request.ContentLength = NVP.Length;
            
       string sResponse = string.Empty;
       using(StreamWriter sw = new StreamWriter(request.GetRequestStream()))
       {
           sw.Write(NVP);
       }

       HttpWebResponse response = (HttpWebResponse)request.GetResponse();
       using (StreamReader sr = new StreamReader(response.GetResponseStream()))
       {
           sResponse = sr.ReadToEnd();
       }
         
       // Receive the token for the operation and redirect the user to the generated URL for the PayPal portal
       string token = string.Empty;
       string[] splitResponse = sResponse.Split('&');
       if (splitResponse.Length> 0)
       {
           foreach (string responseField in splitResponse)
           {
               if (responseField.Contains("TOKEN"))
               {
                   token = responseField.Substring(6);
                   break;
               }
           }
 
           if (!string.IsNullOrEmpty(token))
           {
               redirectUrl = string.Format(redirectUrl, token);
               Response.Redirect(redirectUrl);
           }
       }

       // If we get here, something went wrong;
       lblError.Visible = true;            // Simple error handling :)
   }
 }
} 

Once the above flow is completed, the user will be returned to the specified return URL (having the 2 tokens, that confirm the payment, appended in the query string). With this, you get confirmation that your customer approved a payment to you, via PayPal. Up to this point, no actual money has left the buyer’s digital wallet. The only transaction that took place was that the buyer informed PayPal of his intent to pay you, and as a response, the service generated a transaction token to be used by your application (to claim payment once the order is submitted).

We took a look at how to integrate PayPal’s Express Checkout control into our C# application. At that point we were only able to send data to PayPal’a API to generate transaction tokens for future use, so now it’s time to finalize the transaction and request payment from the PayPal API.

Do you remember the accounts that you’ve setup up at the beginning? Well, you’ll want to log into your master account and check the balance, because this final call to the PayPal API is where the good stuff happens. Keeping in theme with our previous C# sample, the data that we’ll send is hardcoded into the app, in order to keep things simple.

All you have to do is to follow the comments and the C# code, and leave a reply if you feel that something needs to be more detailed 🙂

protected void btnConfirmaPayPalPurchase_Click(object sender, EventArgs e)
  {
      // First thing's first. We'll need to get the token and payer ID returned from the previous call:
      if (string.IsNullOrEmpty(Request.QueryString["token"]) || string.IsNullOrEmpty(Request.QueryString["PayerID"]))
      {
          lblError.Visible = true;
          return;
      }
          
      // Than we add the tokens to string type variables as we'll need to rebuild the NVP string
      string token = Request.QueryString["token"].ToString();
      string payerId = Request.QueryString["PayerID"].ToString();

      // Rebuilding the NVP string for the request; I've hardcoded the payment values again as this sample app does not have a database behind it.
      string NVP = string.Empty;

      NVP += "METHOD=DoExpressCheckoutPayment";
      NVP += "&VERSION=123";

      NVP += "&USER=" + _sellerUsername;
      NVP += "&PWD=" + _sellerPassword;
      NVP += "&SIGNATURE=" + _sellerSignature;

      NVP += "&TOKEN=" + token;
      NVP += "&PAYERID=" + payerId;

      NVP += "&PAYMENTREQUEST_0_PAYMENTACTION=Sale";
      NVP += "&PAYMENTREQUEST_0_AMT=100";
      NVP += "&PAYMENTREQUEST_0_ITEMAMT=80";
      NVP += "&PAYMENTREQUEST_0_SHIPPINGAMT=10";
      NVP += "&PAYMENTREQUEST_0_HANDLINGAMT=5";
      NVP += "&PAYMENTREQUEST_0_TAXAMT=5";

      // Making the API call
      string response = APICall(NVP);

      // Interpreting the response from PayPal; As a simple UI for checking the transaction, I'm displaying the transaction ID in the page on success so to make things easier when I'm checking the transaction log in PayPal's web UI.
      if (response.Contains("Success"))
      {
          string transactionId = response.Substring(response.IndexOf("PAYMENTINFO_0_TRANSACTIONID"), response.IndexOf("&", response.IndexOf("PAYMENTINFO_0_TRANSACTIONID")) - response.IndexOf("PAYMENTINFO_0_TRANSACTIONID"));
          lblPayPalPaymentSuccess.Text += transactionId;
          lblPayPalPaymentSuccess.Visible = true;
      }
      else
          lblError.Visible = true;

      btnConfirmPayPalPurchase.Visible = false;
      lblPayPalCheckoutSuccess.Visible = false;
  }

  private string APICall(string NVP)
  {
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_endpointUrl);
      request.Method = "POST";
      request.ContentLength = NVP.Length;

      string sResponse = string.Empty;
      using (StreamWriter sw = new StreamWriter(request.GetRequestStream()))
      {
          sw.Write(NVP);
      }

      HttpWebResponse response = (HttpWebResponse)request.GetResponse();
      using (StreamReader sr = new StreamReader(response.GetResponseStream()))
      {
          sResponse = sr.ReadToEnd();
      }

      return sResponse;
  }
 }
}

There you have it! PayPal is a payment system easy to implement and which can be integrated into your C# applications in no time. For the remaining time, you can get your online business rolling, working on refining your services and adding more value to your products.

While there are many payment systems out there, PayPal Express Checkout offers a great starting point for a startup business, thanks to the easy implementation and the well-known PayPal system, which is used all over the world.

Scroll to Top