Saturday, 3 October 2009

Integrating Paypal Payment Pro (Direct Payment)

I've recently had need to integrate PayPal payments on a website, using their Payments Pro interface. It's actually very straightforward, although initally didn't appear so as the information they provide on their website and forums is rather confusing. This is primarily due to the different versions of their API that have been provided historically, plus there are a number of different techniques to access it.

All I need was a simple request to authorise a set of card details, getting back a response to allow the order to either be processed appropriately.

Pulling together with my own code a few different examples online, the Paypal documentation and some advice from their technical support led me to this function - which I'll post in the hope of helping rather than hindering someone else in the same position!


    1 private void makePayPalPayment()


    2 {


    3   //Open log file


    4   TextWriter objLogFile;


    5   objLogFile = File.AppendText(ConfigurationManager.AppSettings["PaypalLogFilePath"]);


    6   try


    7   {


    8     objLogFile.WriteLine("Paypal request commenced: " + DateTime.Now.ToString());


    9 


   10     //Get details for request   


   11     // - get paypal endpoint and authorisation details


   12     string endPoint = ConfigurationManager.AppSettings["PayPalEndPoint"];


   13     string username = ConfigurationManager.AppSettings["PayPalUserName"];


   14     string password = ConfigurationManager.AppSettings["PayPalPassword"];


   15     string signature = ConfigurationManager.AppSettings["PayPalSignature"];


   16     // - get IP of current user


   17     string ip = Request.ServerVariables["REMOTE_ADDR"];


   18     // - get customer details (from form fields)


   19     string cardType = ddlCardType.SelectedItem.Value;


   20     string cardNumber = txtCardNumber.Text;


   21     string expDate = ddlExpiryDateMonth.SelectedItem.Value + ddlExpiryDateYear.SelectedItem.Value;


   22     string securityCode = txtSecurityCode.Text;


   23     string firstName = txtFirstName.Text;


   24     string lastName = txtLastName.Text;


   25     string street = txtStreet.Text;


   26     string city = txtCity.Text;


   27     string state = txtState.Text;


   28     string zip = txtZip.Text;


   29     string countryCode = ddlCountry.SelectedItem.Value;   


   30     // - get order details (hardcoded in this example)


   31     decimal orderAmount = 10.0;


   32     string currencyCode = "GBP";


   33 


   34     //Build request


   35     StringBuilder request = new StringBuilder();


   36     request.Append("VERSION=52.0");


   37     request.Append("&USER=" + HttpUtility.UrlEncode(username));


   38     request.Append("&PWD=" + HttpUtility.UrlEncode(password));


   39     request.Append("&SIGNATURE=" + HttpUtility.UrlEncode(signature));


   40     request.Append("&METHOD=DoDirectPayment");


   41     request.Append("&PAYMENTACTION=Sale");


   42     request.Append("&AMT=" + orderAmount.ToString("F"));


   43     request.Append("&IPADDRESS=" + HttpUtility.UrlEncode(ip));


   44     request.Append("&CREDITCARDTYPE=" + HttpUtility.UrlEncode(cardType));


   45     request.Append("&ACCT=" + HttpUtility.UrlEncode(cardNumber));


   46     request.Append("&EXPDATE=" + HttpUtility.UrlEncode(expDate));


   47     request.Append("&CVV2=" + HttpUtility.UrlEncode(securityCode));


   48     request.Append("&FIRSTNAME=" + HttpUtility.UrlEncode(firstName));


   49     request.Append("&LASTNAME=" + HttpUtility.UrlEncode(lastName));


   50     request.Append("&STREET=" + HttpUtility.UrlEncode(street));


   51     request.Append("&CITY=" + HttpUtility.UrlEncode(city));


   52     request.Append("&STATE=" + HttpUtility.UrlEncode(state));


   53     request.Append("&ZIP=" + HttpUtility.UrlEncode(zip));


   54     request.Append("&INVOICEID=" + HttpUtility.UrlEncode(order.ID.ToString()));


   55     request.Append("&COUNTRYCODE=" + HttpUtility.UrlEncode(countryCode));


   56     request.Append("&CURRENCYCODE=" + HttpUtility.UrlEncode(currencyCode));


   57     objLogFile.WriteLine("Request: " + request.ToString());


   58 


   59     //Set up flags for success of operation


   60     bool success = false;


   61     string errorMessage = "";


   62 


   63     //Make Paypal request


   64     HttpWebRequest webRequest = WebRequest.Create(endPoint) as HttpWebRequest;


   65     webRequest.Method = "POST";


   66     webRequest.ContentType = "application/x-www-form-urlencoded";


   67     webRequest.ContentLength = request.Length;


   68     StreamWriter writer = new StreamWriter(webRequest.GetRequestStream());


   69     writer.Write(request.ToString());


   70     writer.Close();


   71 


   72     //Get Paypal response


   73     HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();


   74 


   75     //Check status


   76     if (webRequest.HaveResponse && (webResponse.StatusCode == HttpStatusCode.OK || webResponse.StatusCode == HttpStatusCode.Accepted))


   77     {


   78       //Response received, so parse into name value pairs for processing


   79       StreamReader reader = new StreamReader(webResponse.GetResponseStream());


   80       string responseString = reader.ReadToEnd();


   81       objLogFile.WriteLine("Response: " + responseString);


   82       reader.Close();


   83       char[] ampersand = { '&' };


   84       char[] equalsign = { '=' };


   85       string[] pairs = responseString.Split(ampersand);               


   86       for (int i = 0; i < pairs.Length; i++)


   87       {


   88         string[] pair = pairs[i].Split(equalsign);


   89         //One pair will be the acknowledgement (ACK) - if this is not set to failure we know the payment has been authorised


   90         if (pair[0].ToLower() == "ack" && HttpUtility.UrlDecode(pair[1]).ToLower() != "failure")


   91         {


   92           success = true;


   93         }


   94         //One or more messages wil be returned in the case of a failure, so build up list of messages to present to user (or developer :-))


   95         if (pair[0].Length > 13 && pair[0].Substring(0,13).ToLower() == "l_longmessage")


   96         {


   97           errorMessage += "<li>" + HttpUtility.UrlDecode(pair[1]) + "</li>";


   98         }


   99       }


  100     }


  101 


  102     //Display appropriate message to user


  103     if (success)


  104     {


  105       // *** process authorised order ***


  106     }


  107     else


  108     {


  109       lblResultMessage.Text = "Sorry, but your payment transaction cannot be proceed. Please review the following messages and try again, or select another payment method.";


  110       lblResultMessage.Text += "<ul>" + errorMessage + "</ul>";


  111     }


  112   }


  113   finally


  114   {


  115     objLogFile.WriteLine("");


  116     objLogFile.Close();


  117   }


  118 }


1 comment:

  1. I can't even begin to tell you how much this helped me. thanks so much!

    ReplyDelete