+ All Categories
Home > Documents > Paypal Instruction

Paypal Instruction

Date post: 19-Jul-2016
Category:
Upload: khoa-phan
View: 91 times
Download: 22 times
Share this document with a friend
Description:
fsd
87
Index PayPal Introduction Getting Started with PayPal Setting up a Test Account Website Payments Standard (HTML) PostPayment processing AutoReturn Direct Payment (PDT) Instant Payment Notification (IPN) PayPal API Express Checkout Direct Payment (Website Payments Pro) Conclusion History Introduction PayPal is probably one of the first things that gets mentioned once you start discussion on online payments. It’s not so without reason – in 2008, PayPal moved over 60 billion dollars between accounts which is, you’ll agree, a respectable amount. And also, all trends show that this growth will continue – with huge number of new accounts (over 184 million accounts in 2008 compared to 96.2 million in 2005), with a new platform named PayPal X, and with more cool applications that involve paying (like Twitpay), you can bet that PayPal is here to stay. So, how can you join the whole PayPal Development movement? Unfortunately, I would say – not so easily. When I first started with PayPal integration - it was hard, really hard. If you wish to see what I mean, just jump to the PayPal Developer Center. There is no way you’ll easily fish out what you need from that site if you are a
Transcript
Page 1: Paypal Instruction

Index

PayPal Introduction

Getting Started with PayPal

Setting up a Test Account

Website Payments Standard (HTML)

PostPayment processing

AutoReturn

Direct Payment (PDT)

Instant Payment Notification (IPN)

PayPal API

Express Checkout

Direct Payment (Website Payments Pro)

Conclusion

History

Introduction

PayPal is probably one of the first things that gets mentioned once you start discussion on online payments. It’s not so without reason – in 2008, PayPal moved over 60 billion dollars between accounts which is, you’ll agree, a respectable amount. And also, all trends show that this growth will continue – with huge number of new accounts (over 184 million accounts in 2008 compared to 96.2 million in 2005), with a new platform named PayPal X, and with more cool applications that involve paying (like Twitpay), you can bet that PayPal is here to stay. So, how can you join the whole PayPal Development movement?

Unfortunately, I would say – not so easily. When I first started with PayPal integration - it was hard, really hard. If you wish to see what I mean, just jump to the PayPal Developer Center. There is no way you’ll easily fish out what you need from that site if you are a PayPal newbie; simply - there are too many links, too many resources, and too many mixings of important and not-so-important information. So, how should you start?

Getting Started with PayPal

To those who really want to get into PayPal, and are willing to shell out some buck, I would recommend the Pro PayPal E-Commerce book - that’s how I eventually got into understanding the concepts behind

Page 2: Paypal Instruction

PayPal integration. For those who are not so eager to pay – don’t worry, that’s why this article is here... I'll go over most of the stuff that book covers, but in a more brief and concise manner.

First and foremost - understanding what kinds of integration PayPal offers is, I would say, the most important thing in order to successfully start your development journey. A common mistake, that happened to me also, is to start at once with the PayPal API and Express Checkout. I mean it’s natural - we are developers, and when they tell us to integrate with something, the first thing we look for is the SDK & API… the PayPal API comes up as a result… we say “That’s it” to ourselves… and start working. The problem is – the majority of payment scenarios can be handled with a way simpler approach - HTML forms that are part of the Website Payments Standard.

So, without further ado, here is a classification of PayPal integrations:

Website Payments Standard (HTML)

Postpayment Processing

AutoReturn

Payment Data Transfer (PDT)

Instant Payment Notification (IPN)

PayPal API

Express Checkout

Direct Payment (Website Payments Pro)

Payflow Gateway

Items in classification are also ordered in a way I would suggest for everyone to follow. So, if you are new to PayPal – first learn all of the options that you have with the Website Payments Standard (HTML). Then, if you need to add some basic post-payment processing, see if Auto-Return or PDT will solve your problem… if not, IPN is a more robust option you have at your disposal.

The next level would involve the PayPal API and implementing the Express Checkout, which is the most flexible PayPal integration solution. And finally, if you long for the ability to directly process credit cards on your website, you’ll pay a monthly fee to PayPal and implement Direct Payment (effectively getting what is called Website Payments Pro).

The last item from our classification - the Payflow Gateway is, on the other hand, a different beast. It doesn’t “update the stack” in a way the previously mentioned technologies do. It is a solution aimed specifically at those businesses that have/want an Internet Merchant Account (IMA) and just need the payment gateway. In order to keep the article consistent, I’ll skip explaining the details of the Payflow Gateway. However, if you have any questions related to it, feel free to leave a message in the comments section and I’ll try to answer.

Page 3: Paypal Instruction

That said, let’s get to setting up a test PayPal account, and then we’ll delve deeper into describing the mentioned integrations.

Setting up a Test Account

Word of notice – you’ll want to follow this step even if you already have a live PayPal account. There are two reasons for using test accounts:

you don’t want to test and play with real money

you want to have access to different types of PayPal accounts

Personal account – most people have these; just an account that allows you to use PayPal when paying for stuff online. Theoretically, you can use a Personal account to accept money; just know that you’ll be severely constrained – there is a $500 receiving limit per month, and you are only able to accept one time payments using the Website Payments Standard (HTML). The big advantage of a Personal account is that you don’t need to pay any transaction fee when receiving money. Note, however, that if you receive more than $500 in one month, you’ll be prompted to either upgrade to a Premier/Business account or reject the payment.

Premier account – step up from a personal account; for anyone who wants to run a personal online business. This type of account has all of the integration options (accepting credit cards, recurring payments, PayPal API). However, most people skip directly from Personal to Business account as Premier account has the same transaction fees (in most cases, 2.9% + $0.30 per transaction) while lacking reporting, multi-user access, and other advanced merchant services of the Business account.

Business account – it has all of the features of the Premier account plus a few more (ability to operate under your business’s name is one of them). If you are developing a website that needs to accept payments in 99% of situations, you’ll go with this type of account.

To start, visit the PayPal Sandbox and sign-up for a new account. The process is straightforward, and most developers should have no trouble finishing it. However, here are the pictures that will help you navigate through the process:

Page 4: Paypal Instruction

Signing up for a Sandbox account

Page 5: Paypal Instruction

Filling in the details of your Sandbox account

Once done with entering the details for your Sandbox account, you'll need to check the email you provided in order to complete the registration. After that, you'll be able to login and start creating Sandbox PayPal accounts. Clicking on Test Accounts (menu on the left), and then Create Account: Preconfigured - will get you a form like the one on the image below:

Creating a Sandbox test account

Clarification of Account Type radio buttons: by selecting Buyer, you'll create a Personal account, and by selecting Seller, you'll create a Business account. For testing most integration scenarios, you'll need both accounts, so be sure to create them. Here is what you should eventually have on your screen after you click on Test Accounts:

Page 6: Paypal Instruction

Overview of your testing accounts

Checking the radio button next to any of the accounts from the list and clicking on Enter Sandbox Test Site should bring up the Sandbox PayPal site which will allow you to login and administer your account in the same way as with a regular PayPal account. The only difference is that you'll have a huge PayPal Sandbox header and text that displays the email address of your developer account. To see what I'm talking about, check the image below:

Page 7: Paypal Instruction

Administering a PayPal Sandbox account

Last but not least - in order to use your Sandbox account for testing, you need to be logged in with your developer account. If you are not logged in and you follow some payment link, you'll get the following screen:

Page 8: Paypal Instruction

Login to use the PayPal Sandbox features

Website Payments Standard (HTML)

In this section, I'll provide you with a number of examples that will show how to create your own HTML form for receiving money over PayPal. You'll see how to use different variables in order to influence payment details. Before we delve into details, let's take a look at the two most basic variables:

form's action attribute - in most cases, it should be https://www.paypal.com/cgi-bin/webscr. If you are using Sandbox for testing payments, you'll change it to https://www.sandbox.paypal.com/cgi-bin/webscr - effectively, you just insert the word sandbox into the URL (this is also true for some other integrations; e.g., the PayPal API). For upcoming examples, I won't be using the Sandbox URL because most of you would just get that "Login to use the PayPal Sandbox features" screen (look up for the image).

form's business child - I'll use [email protected] for most examples; if you copy-paste the code, you'll want to replace that with the email of your PayPal account.

Basic Payment

OK, let’s say you have an opened PayPal account and you just wish to be able to accept a $10 payment for a painting you are selling through your site. Just insert the following HTML into your page and you are set to go:

Page 9: Paypal Instruction

Collapse | Copy Code

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">

<input type="hidden" name="cmd" value="_xclick" />

<input type="hidden" name="business" value="[email protected]" />

<input type="hidden" name="item_name" value="My painting" />

<input type="hidden" name="amount" value="10.00" />

<input type="submit" value="Buy!" />

</form>

Shipping & Handling

The next thing that comes to mind is that you'll wish to add shipping and/or handling fees to your form. It's easy - just add more parameters:

Collapse | Copy Code

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">

<input type="hidden" name="cmd" value="_xclick" />

<input type="hidden" name="business" value="[email protected]" />

<input type="hidden" name="item_name" value="My painting" />

<input type="hidden" name="amount" value="10.00" />

<input type="hidden" name="shipping" value="3.00" />

<input type="hidden" name="handling" value="2.00" />

Page 10: Paypal Instruction

<input type="submit" value="Buy with additional parameters!" />

</form>

Donations & Textual Links

If you aren't selling anything but rather accepting donations for some cause - you'll just need to change the value of the cmd variable to _donations. If we combine this with a common requirement to have a hyperlink instead of a button - we get the following URL (of course, you can use this method of URL creation for other PayPal payment types):

https://www.paypal.com/cgi-bin/webscr?cmd=_donations&[email protected]&item_name=Save Polar Bears!&amount=10.00

Result:

Save Polar Bears!

Cart System

If you have a bunch of different products to offer and you just want a simple cart system without implementing anything, PayPal has you covered. Basically, you'll just play with the cmd variable while keeping the rest of the form same as for the Basic Payment. Let's see how you should do this for two products; one priced at $10 without shipping fees, and one priced at $5 with $1 shipping fee. We will also need a View Cart button:

Collapse | Copy Code

My Cart Item 1:

<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="paypal">

<input type="hidden" name="cmd" value="_cart">

<input type="hidden" name="add" value="1">

<input type="hidden" name="business" value="[email protected]">

<input type="hidden" name="item_name" value="My Cart Item 1">

<input type="hidden" name="amount" value="10.00">

Page 11: Paypal Instruction

<input type="hidden" name="shopping_url"

value="http://www.yourwebsite.com/shoppingpage.html">

<input type="hidden" name="return" value="http://www.yourwebsite.com/success.html">

<input type="hidden" name="cancel_return" value="http://www.yourwebsite.com/cancel.html">

<input type="hidden" name="bn" value="PP-ShopCartBF:x-click-but22.gif:NonHosted">

<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but22.gif" border="0"

name="submit" alt="Make payments with PayPal - it's fast, free and secure!">

<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1"

height="1">

</form>

My Cart Item 2:

<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="paypal">

<input type="hidden" name="cmd" value="_cart">

<input type="hidden" name="add" value="1">

<input type="hidden" name="business" value="[email protected]">

<input type="hidden" name="item_name" value="My Cart Item 2">

<input type="hidden" name="amount" value="5.00">

Page 12: Paypal Instruction

<input type="hidden" name="shipping" value="1.00">

<input type="hidden" name="shopping_url"

value="http://www.yourwebsite.com/shoppingpage.html">

<input type="hidden" name="return" value="http://www.yourwebsite.com/success.html">

<input type="hidden" name="cancel_return" value="http://www.yourwebsite.com/cancel.html">

<input type="hidden" name="bn" value="PP-ShopCartBF:x-click-but22.gif:NonHosted">

<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but22.gif" border="0"

name="submit" alt="Make payments with PayPal - it's fast, free and secure!">

<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1"

height="1">

</form>

View Cart:

<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="paypal">

<input type="hidden" name="cmd" value="_cart">

<input type="hidden" name="display" value="1">

<input type="hidden" name="business" value="[email protected]">

<input type="hidden" name="shopping_url"

value="http://www.yourwebsite.com/shoppingpage.html">

Page 13: Paypal Instruction

<input type="image" src="https://www.paypal.com/en_US/i/btn/view_cart_02.gif"

name="submit" alt="Make payments with PayPal - it's fast, free and secure!">

</form>

Recurring Payments

If you are selling a monthly service rather than a product, you'll be interested in the recurring payment options PayPal provides. Again, it's playing with different variables that have different meaning. Let's say you wish to set a 3 day free trial after which the user will have to pay you $10.00 per month to keep using the service. The following HTML form should do the trick:

Collapse | Copy Code

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">

<input type="hidden" name="cmd" value="_xclick-subscriptions"/>

<input type="hidden" name="business" value="[email protected]"/>

<input type="hidden" name="item_name" value="Something"/>

<input type="submit" value="Subscribe!" />

<input type="hidden" name="a1" value="0"/>

<input type="hidden" name="p1" value="3"/>

<input type="hidden" name="t1" value="D"/>

<input type="hidden" name="a3" value="10.00"/>

<input type="hidden" name="p3" value="1"/>

<input type="hidden" name="t3" value="M"/>

<input type="hidden" name="src" value="1"/>

<input type="hidden" name="srt" value="0"/>

<input type="hidden" name="sra" value="1"/>

</form>

Page 14: Paypal Instruction

HTML Variables & Resources

After reading the previous example, you may be wondering what certain variables do (a1? p1? srt?). Luckily, PayPal provides an "HTML Variables for Website Payments Standard" page on which you can read about any variable that you are interested in.

Also, another great resource (to which I wish someone pointed me when I first started with PP integration) is "skier's PayPal examples". You'll find examples for almost all payment scenarios you can think of - so instead of cluttering this article with more examples, I'll encourage you to visit that page should you wish to implement some more advanced PayPal HTML form.

PostPayment Processing

When you setup your PayPal HTML form, the first question you'll probably ask is - after user pays, can I have some post-payment processing logic? It is not so without reason; there are numerous post-payment scenarios we can think of - from sending a simple "Thank you" email to updating the site database and allowing user access to restricted resources for which he paid. Depending on your knowledge and the desired level of robustness for post-processing logic, there are three ways you can go; and the good thing is you can combine them.

AutoReturn

AutoReturn is the simplest PostPayment processing solution that you have - after the user pays, he is automatically* redirected to a specified page on your website on which you can display some confirmation text. If you carefully went through "HTML Variables for Website Payments Standard", you know that you can use a return variable to specify the AutoReturn URL in the HTML form. If you wish to have the default AutoReturn URL, follow these steps:

Log in to your Premier or Business account

Click the Profile subtab

Click the Website Payment Preferences in the Selling Preferences column

Click the On radio button next to the Auto Return label

Enter the URL where you want your users to return in the text box labeled Return URL

Click the Save button at the bottom of the page

Page 15: Paypal Instruction

Providing the AutoReturl URL in your PayPal profile

Know that if you have both AutoReturn URL in your profile and provide a return variable in your HTML form, the return variable will overwrite the profile URL value.

Now, when your return page is hit, you'll be getting variables that should allow you to customize the page display and log payment:

tx - Transaction ID

st - Payment status

amt - Payment amount

cc - Currency code

Before closing this section, one more thing. The reason why I've italicized the word "automatically" in the first sentence is: if the user uses a credit card to pay you, he won't be automatically redirected to your return URL; he'll rather need to click on the "Return to Merchant" button. If this sounds weird to you, know that you're not alone; however, because of legal issues, PayPal refused and still refuses to change the way credit card payments are handled with AutoReturn.

Payment Data Transfer (PDT)

Page 16: Paypal Instruction

After looking over the list of variables that AutoReturn provides, you probably wondered - can I get more details about the transaction that occurred? This is exactly where PDT jumps in - building on the AutoReturn functionality. For that reason, you'll need to enable both AutoReturn and then PDT in your profile; here is how to do that:

Log in to your Premier or Business account

Click the Profile sub tab

Click Website Payment Preferences in the Selling Preferences column

Click the On radio button next to the Auto Return label

Enter the URL of the script that will process the PDT HTTP request sent from PayPal

Under Payment Data Transfer, click the On radio button

Click Save.

After following these steps, you should get a PDT Identity Token that is needed for querying PayPal. If you don't copy-paste the token after clicking Save, know that you can always see it in your Website Payment Preferences:

Payment Data Transfer and Identity Token

Page 17: Paypal Instruction

Now that you have the Identity Token, you can query PayPal for more details after your return URL has been hit. Here is how things flow when utilizing PDT:

User pays and is redirected to your AutoReturn page, for example: http://www.yourdomain.com/Thanks.aspx?tx=[TransactionID].

From the code-behind of Thanks.aspx, you'll parse the tx value and make an HTTP POST to https://www.paypal.com/cgi-bin/webscr with the following parameters: cmd=_notify-synch&tx=[TransactionID]&at=[PDTIdentityToken]. (If you are using Sandbox, you'll of course make an HTTP POST to https://www.sandbox.paypal.com/cgi-bin/webscr.)

PayPal will respond to your HTTP POST in the following format:

Collapse | Copy Code

SUCCESS

first_name=Firstname

last_name=Lastname

payment_status=Completed

payer_email=firstname%40lastname.com

payment_gross=50.00

mc_currency=USD

custom=Custom+value+you+passed+with+your+HTML+form

etc.

Do whatever you wish with the data.

Here is how what was said in the previous few lines looks in C# code:

Collapse | Copy Code

protected void Page_Load(object sender, EventArgs e)

{

if (!Page.IsPostBack)

{

authToken = WebConfigurationManager.AppSettings["PDTToken"];

Page 18: Paypal Instruction

//read in txn token from querystring

txToken = Request.QueryString.Get("tx");

query = string.Format("cmd=_notify-synch&tx={0}&at={1}",

txToken, authToken);

// Create the request back

string url = WebConfigurationManager.AppSettings["PayPalSubmitUrl"];

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

// Set values for the request back

req.Method = "POST";

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

req.ContentLength = query.Length;

// Write the request back IPN strings

StreamWriter stOut = new StreamWriter(req.GetRequestStream(),

System.Text.Encoding.ASCII);

stOut.Write(query);

stOut.Close();

// Do the request to PayPal and get the response

StreamReader stIn = new StreamReader(req.GetResponse().GetResponseStream());

Page 19: Paypal Instruction

strResponse = stIn.ReadToEnd();

stIn.Close();

// sanity check

Label2.Text = strResponse;

// If response was SUCCESS, parse response string and output details

if (strResponse.StartsWith("SUCCESS"))

{

PDTHolder pdt = PDTHolder.Parse(strResponse);

Label1.Text =

string.Format("Thank you {0} {1} [{2}] for your payment of {3} {4}!",

pdt.PayerFirstName, pdt.PayerLastName,

pdt.PayerEmail, pdt.GrossTotal, pdt.Currency);

}

else

{

Label1.Text = "Oooops, something went wrong...";

}

}

}

In the code I'm attaching with the article, under the PDT directory, you'll see more classes that will help you out in following the previously mentioned flow.

And, as with AutoReturn, one notice before closing the subject - take a look at the custom variable in PayPal's response to your HTTP POST. You'll probably want to utilize this variable as it allows you to pass some information from your payment page to your post-processing page without presenting it to the

Page 20: Paypal Instruction

user. To name one use, in some of my PayPal implementations, I track the user with it - when he started payment process, and when/if he finished it.

Instant Payment Notification (IPN)

One big shortcoming of PDT is that it is a user-driven process, meaning - if the user closes the browser after performing a payment and before being redirected to your site, you'll lose the opportunity to run your post processing logic. That's why you are advised to combine the PDT with IPN for any serious integration with PayPal.

IPN is a back-end mechanism that makes HTTP POSTs to your page, notifying you of important events. It is used not only for PostPayment processing, but also for things that come after, like handling user cancelation of recurring payments.

Being a back-end technology, it is somewhat harder to implement and debug than PDT. There are a couple of things you should be aware of before starting to implement IPN:

IPN messages can be delayed sometimes. I know, I know... that beats the word "Instant" in IPN, but that's how things are.

There is a known history of problems with the IPN service; two latest incidents happened on October 2nd 2009 (2 hour delay) and on September 6th 2009 (6 hour delay).

Whenever you have problems with IPN, be sure to check the Live Status page and see if there is an incident notification before digging into debugging and changing your script. There is also a similar page for Sandbox Status.

Before being able to receive IPN messages, you'll need to activate this service; follow these steps:

Log in to your Premier or Business account

Click the Profile sub tab

Click Instant Payment Notification in the Selling Preferences column

Click the 'Edit IPN Settings' button to update your settings

Select 'Receive IPN messages' (Enabled) and enter the URL of your IPN handler

Click Save, and you should get a message that you have successfully activated IPN

Page 21: Paypal Instruction

Activating Instant Payment Notification

As with AutoReturn, you can overwrite the IPN handler URL set in the profile in individual forms by adding the notify_url variable (see the HTML Variables reference). Know that this will influence not only the initial IPN message but all future messages related to that transaction (they will all go to notify_url).

To handle IPN messages, you'll need to create an HTTP handler somewhere on your website. When a significant event occurs (e.g., user performs payment), following flow takes place:

PayPal will send an HTTP POST to your IPN handler with a number of variables.

After receiving HTTP POST and parsing it, you need to submit the complete body of the message back to https://www.paypal.com/cgi-bin/webscr (or https://www.sandbox.paypal.com/cgi-bin/webscr for a Sandbox account). When you are doing this, be sure to send a message back in the exact format in which you received it; the only thing you are allowed to do is adding cmd=_notify-validate. This is all done in order to verify that HTTP POST was authentic and sent from PayPal.

PayPal will respond with either VERIFIED or INVALID. After you receive this response, be sure to send 200 OK to prevent additional attempts from PayPal to send an IPN. If you don't close the loop with a 200 OK, PayPal will start resending IPN (starting from 4 seconds and doubling - 8 seconds, 16 seconds, 32 seconds... up to 4 days).

Here is a generic C# IPN handler (for more code, check the zip attached to the article):

Collapse | Copy Code

Page 22: Paypal Instruction

protected void Page_Load(object sender, EventArgs e)

{

string postUrl = ConfigurationManager.AppSettings["PayPalSubmitUrl"];

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(postUrl);

//Set values for the request back

req.Method = "POST";

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

byte[] param = Request.BinaryRead(HttpContext.Current.Request.ContentLength);

string strRequest = Encoding.ASCII.GetString(param);

string ipnPost = strRequest;

strRequest += "&cmd=_notify-validate";

req.ContentLength = strRequest.Length;

//for proxy

//WebProxy proxy = new WebProxy(new Uri("http://url:port#"));

//req.Proxy = proxy;

//Send the request to PayPal and get the response

StreamWriter streamOut = new StreamWriter(req.GetRequestStream(),

System.Text.Encoding.ASCII);

streamOut.Write(strRequest);

streamOut.Close();

StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream());

Page 23: Paypal Instruction

string strResponse = streamIn.ReadToEnd();

streamIn.Close();

// logging ipn messages... be sure that you give write

// permission to process executing this code

string logPathDir = ResolveUrl("Messages");

string logPath = string.Format("{0}\\{1}.txt",

Server.MapPath(logPathDir), DateTime.Now.Ticks);

File.WriteAllText(logPath, ipnPost);

//

if (strResponse == "VERIFIED")

{

//check the payment_status is Completed

//check that txn_id has not been previously processed

//check that receiver_email is your Primary PayPal email

//check that payment_amount/payment_currency are correct

//process payment

}

else if (strResponse == "INVALID")

{

//log for manual investigation

}

else

{

Page 24: Paypal Instruction

//log response/ipn data for manual investigation

}

}

If you have received an INVALID response, that could mean two things:

Someone tried to send a malicious message to your IPN handler.

Your implementation isn't perfect.

In case of a malicious message, you're on your own (log IP, take appropriate action), but for imperfect implementations, visit this IPN troubleshooting topic on PayPal Developer Forums; it is full of useful tips that should help you solve INVALID responses.

Also, before going online with your IPN handler, be sure to test it thoroughly with the Instant Payment Notification (IPN) simulator. As an IPN handler will work in the background, you'll want to test it as much as you can before going live and relying on its processing.

Another thing you'll want to visit if you are implementing IPN is ScriptGenerator2 page... it can quickly generate an IPN handler in the language of your choice. Funny thing - they are missing a generator for ASP.NET/C#; for that, check out the IPN directory in the code-archive I've attached to this article and these Code Samples.

Finally, on PayPal Developer Center, there is this nice page that lists most of the IPN and PDT variables. I'm saying most because there are some variables missing on it (check comments on this page), but the list is far beyond being useless.

PayPal API

As said in the introduction, most developers, even if they have no previous experience with PayPal, start directly with the API. Google search brings up either API Reference or the SDKs and Downloads page and then browsing through Documentation starts. I don't want to say that there is something wrong with using PayPal API for payments; I want to say that in most of the cases, it's not necessary to go down that path.

PayPal API is much more than just a mechanism for payment - if you look at the provided API Reference page, you'll see that there are lots of methods not tied directly to "user performing payment". You can use the API to browse through the history of your transactions, issue a refund, or update a recurring payments profile. So how do you start using it?

First and foremost, you'll need to enable API access in your account; follow these steps:

Log in to your Premier or Business account

Click the Profile sub tab

Page 25: Paypal Instruction

Click the API Access link under the Account Information header

Click the link that says Request API Credentials / View API Certificate

Select either API Signature or API Certificate

Step 5 from activating API Access

I recommend that you select API Signature, and the examples that follow will assume you made this choice. There is nothing wrong with selecting API Certificate; I just find it more demanding from a setup perspective.

Now that you have credentials to make API calls, how do you perform them? The approach that will work equally well with all platforms is to download the SDK, target the appropriate API endpoint, and start making HTTP calls with either Name-Value pairs or SOAP.

However, for .NET developers, I recommend a different approach. Considering that Visual Studio has an awesome WSDL parser, I urge you to just add a Web Service Reference to https://www.paypal.com/wsdl/PayPalSvc.wsdl. After a few moments, you'll have an up-to-date class ready to serve you with all the benefits of strong typing - no building of HTTP requests, no copy-pasting field names, and no cumbersome parsing of responses. You have the same thing available for Sandbox at: https://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl.

Express Checkout

Page 26: Paypal Instruction

Express Checkout is the most flexible PayPal integration solution. The user is redirected to PayPal just for authentication and confirmation that he wants to pay for your services, and after that, everything is done on your website; you'll make calls to the PayPal API in the background. The following picture describes the process (taken from this page):

Express Checkout flow

You'll add a PayPal Checkout button that invokes the SetExpressCheckout method of the PayPal API after it is clicked.

If you are invoking this method for one time payment, it'll be valid if you include only the required fields. Setting the NOSHIPPING variable to 1 is important if you are selling some online service (it'll help you skip the Shipping info page).

If you are invoking this method in order to set recurring payments, be sure to set L_BILLINGTYPE0 to RecurringPayments and L_BILLINGAGREEMENTDESCRIPTION0 to a valid description of your service.

SetExpressCheckout will return a 20 char token that will uniquely identify your transaction. This token is valid for 3 hours. After you receive it, redirect the user to https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=[TOKEN] (you can guess what the URL for Sandbox is, right?).

The user will review payment information, and if everything is OK, enter the login credentials. After this, PayPal will redirect him to the URL you specified with RETURNURL when you called SetExpressCheckout.

When your RETURNURL is hit, you need to invoke the GetExpressCheckoutDetails method and see the details of the actual transaction; verify that everything is in order.

Page 27: Paypal Instruction

Now, all that is left is to commit the transaction. Depending on what you did in step 1, there are two things that can be done.

For one time payments, you'll just invoke DoExpressCheckoutPayment and forward the appropriate variables.

For recurring payments, you'll invoke the CreateRecurringPayments method. It is required that you include the DESC field and match it to the value entered in L_BILLINGAGREEMENTDESCRIPTION0 when you called SetExpressCheckout.

In a nutshell - that's it. Again, I have provided code examples that follow the previously specified flow in the archive accompanying this article (under the API directory). If you wish, you can also use the PayPal Express Checkout Integration Wizard for generating the reference code.

Direct Payment (Website Payments Pro)

Most developers aren't aware that the PayPal platform can be used for just Credit Card processing. This part of the PayPal API is called Direct Payment, and when combined with Express Checkout (which only services customers with PayPal accounts), you get what is referred to as Website Payments Pro on the PayPal Developer Center.

To be able to call methods that are part of Direct Payment (DoDirectPayment and CreateRecurringPayments), you first need to satisfy some conditions:

Have a Business account that is based in US, UK, or Canada

Oblige that you'll implement both Express Checkout and Direct Payment on your website

Submit application for Website Payments Pro through your PayPal account and have it approved

Pay monthly fee (currently $30 per month)

After you have a Website Payments Pro account in place, calling Direct Payment methods is pretty straightforward - if in doubt, either visit the API Reference page, or look at the code attached to this article. Just know that if you try to call any Direct Payment method on an account that doesn't have Pro enabled, you'll get an error with code 10501 (this is one of the most common problems reported in the Sandbox forum).

Lastly, once you start dealing with credit cards, you'll need to take care of PCI Compliance; here is a nice forum thread that provides more information on that.

Conclusion

My hope is that this article gave you good overview of PayPal integration options. If it did that, I'll be at peace - as once you have an understanding of the concepts laid out in this article, you'll easily fetch the needed details from the provided links. Sure, there are some topics we haven't touched, like Encrypted

Page 28: Paypal Instruction

Website Payments, PayPal API Certificates, or Payflow Gateway, but I think you can tackle even that on your own once you fully understand all things written here.

If you get stuck on anything, I suggest that you first visit the PayPal Developer Community and ask your question in the appropriate forum. A number of great, knowledable developers monitor those forums, and it's highly probable that you'll receive an answer to almost any PayPal issue within an hour. I also have an account on that site (lepipele) and try to answer questions whenever I have time; so feel free to send me a private message if you drop by or run into trouble.

http://www.codeproject.com/KB/E-commerce/paypal_c_aspnet/paypal_src.zip

http://www.codeproject.com/Articles/19184/Use-of-the-PayPal-payment-system-in-ASP-NET

Page 29: Paypal Instruction

Download source (VB.NET) - 24.62 KB

Introduction

Those who create commercial sites are faced with the question, "How should it receive payments?" One of the most popular payment systems in the world is PayPal. This system is often chosen because it is reliable, simple to use and allows an account to be easily opened. To open an account, you need only have a credit card and/or an account in an American bank. One of shortcomings of the system is its severe security policy. However, practice evinces that if you follow the rules of the system carefully, then errors are very rare. The purpose of this article is to show how payments processing can be organized to support reliability and security. The article is also aimed at providing you with an example of the development of a simple online shop, in order to demonstrate interaction with the PayPal system. You can use the code in your applications to organize interaction with the PayPal system and to process payments.

The article pays special attention to the process of automatic payment verification using IPN (Instant Payment Notification). The article is based on the experience of KB_Soft Group and the official PayPal documentation.

Types of PayPal Payments

PayPal supports several types of payments:

Payments for goods in the PayPal cart. PayPal is responsible for all operations supporting the cart in this case. Unfortunately, this option does not provide the maximal flexibility that is required for implementation of some projects, so the article does not consider this option.

"One click" shopping. Goods are not put into the cart in this case. This method is also used to pay for goods in a cart that was filled without PayPal. That's why this option provides maximal flexibility and full control of a cart.

Recurring billing or subscription. PayPal provides a subscription capability which means that a definite sum will be periodically transferred from the user's account to the seller's account. The user can

Page 30: Paypal Instruction

unsubscribe anytime. The seller can specify the subscription's period and cost. He can also organize a trial period to let the user assess the quality of the services he provides. The trial period can be either paid or free.

For the reasons described above, the article will consider the second option. Subscription will not be described, in order to keep the example simple. To interact with the PayPal system, KB_Soft Group uses UserControl, which is a product internally developed for these purposes. The given example of the code that works with PayPal uses a special HTML form for requests in order to make clear the explanation of interaction with the system. PayPal also provides its own Control as a dynamic library, but unfortunately, this control functions correctly only with American locale (en-us). Besides, it does not provide full functionality to work with PayPal. Neither does it provide the flexibility required to work on some projects.

Payment Process

The payment process is very simple. A POST form is created with a set of hidden fields that contain information about an item (identifier, name, and cost) and a button to send the form. It should be noted that all prices should be expressed with two digits after the point. If an item costs $10, then its price should be expressed as "10.00". When the form is sent, the buyer goes to the PayPal site and finishes the payment process. When a real PayPal account is used, the form should be sent here. The developed example also allows you to work with the PayPal Sandbox. Use the UseSandbox parameter of web.config and the form will be sent here.

"One-click" Shopping

A code of the simplest form:

Collapse | Copy Code

<form method="post" action= "https://www.paypal.com/cgi-bin/webscr">

<input type="hidden" name="cmd" value="_xclick">

<input type="hidden" name="business" value="[email protected]">

<input type="hidden" name="item_name" value="Item name">

<input type="hidden" name="item_number" value="1234">

<input type="hidden" name="amount" value="19.95">

<input type="hidden" name="no_shipping" value="1">

<input type="submit" value="Buy Now">

</form>

Page 31: Paypal Instruction

Description of Main Parameters

Parameter Description

cmd The parameter is obligatory. It must have the _xclick value for an unencrypted request.

business The parameter is obligatory and represents the seller's e-mail.

item_numberThis parameter is an item identifier. This value will not be shown to the user; however, it will be passed to your script at the time of transaction confirmation. If you plan to use PayPal to pay for goods in a cart, then you can pass the cart's identifier in this parameter.

item_name This is a name of the item that will be shown to the user.

no_shipping

Prompt customer for shipping address. Default or 0: customer is prompted to include a shipping address. 1: customer is not asked for a shipping address. 2: customer must provide a shipping address.

returnThis is the URL where user will be redirected after the payment is successfully performed. If this parameter is not passed, the buyer remains on the PayPal site.

rm

This parameter determines the way information about successful transaction will be passed to the script that is specified in the return parameter. "1" means that no parameters will be passed. "2" means that the POST method will be used. "0" means that the GET method will be used. The parameter is "0" by default.

cancel_returnThis is the URL where the user will be redirected when he cancels the payment. If the parameter is not passed, the buyer remains on the PayPal site.

notify_urlThis is the URL where PayPal will pass information about the transaction (IPN). If the parameter is not passed, the value from the account settings will be used. If this value is not defined in the account settings, then IPN will not be used.

customThis field does not take part in the shopping process, it will be simply passed to IPN script at the time of transaction confirmation.

invoice This parameter is used to pass the invoice number. The parameter is not obligatory, but

Page 32: Paypal Instruction

Parameter Description

being passed it must be unique for every transaction.

amountThis parameter represents an amount of payment. If the parameter is not passed, the user will be allowed to enter the amount (this is used for donations).

currency_codeThis parameter represents a currency code. Possible values are "USD","EUR","GBP","YEN","CAD" etc. It is "USD" by default.

Table 1– Main parameters of the request form.

Table 1 lists the most frequently used parameters. See the PayPal documentation for the full list of parameters, which is accessible via the references at the end of the article.

IPN

IPN (Instant Payment Notification) is a PayPal technology allowing automation of payments processing. The essence of the technology lies in a special script created on the seller's server. When an event happens related to the seller's account -- for example, a payment transfer, payment cancel, subscription creation or cancel, etc. -- the PayPal server sends a POST request with transaction information to the IPN script. The script in its turn, sends a request to the PayPal server to verify the transaction.

So, the buyer has performed a payment. After a delay of up to several seconds, the PayPal server sends the request to the IPN script that is specified in the account settings or passed in the notify_url parameter. A good IPN script is the key to payments security. If you have ever heard that the sellers who use PayPal are victims of somebody's cheating, then be sure that those sellers either do not use IPN at all or have a poor IPN script.

First of all, the script must make sure that it was called by the PayPal server. For these purposes, the script generates a POST request to either here or here. It passes all of the variables it receives, without any changes, together with the cmd parameter having the _notify-validate value. As a response to the request, the script receives either VERIFIED -- meaning that the transaction was successfully verified -- or INVALID in case of an error. If the script receives INVALID, it must terminate.

Then the script must check the payment recipient since a potential intruder may change the form for the payment to be sent to his account. The payment recipient is determined by the business and receiver_email variables. Two variables are necessary because PayPal allows several e-mails to be registered for one account. The e-mail that is specified during account creation is the primary one. The receiver_email is always the primary e-mail. If a payment was sent to another additional e-mail, then the e-mail is passed in the business parameter. If business and/or receiver_email do not contain an expected value, then the script immediately terminates.

Page 33: Paypal Instruction

Then the script must check the amount and the currency of the payment. This verification is required since the potential intruder may change the payment amount in the form. In case subscription is used, the script should check all subscription parameters, i.e. what parameters are set, duration and cost of trial periods, duration and cost of the main subscription cycle, etc.

IPN for the same transaction can be sent more than once. For example, if a payment was delayed for some reason, the first IPN will be sent immediately after the payment. After the payment is performed or cancelled, the second IPN is sent. If the IPN script does not return the HTTP status equal to 200, then PayPal sends IPN again after some time. The first time it will be repeated in 10 seconds, then in 20 seconds if needed, then in 40, 80, etc. up to 24 hours. If the script does not respond in 4 days, then PayPal stops sending IPN. This can be used in order not to loose transaction information if an error occurs in the IPN script. For example, if the script fails to connect to the database where it stores transaction information, then the script can return the HTTP status equal to 500 and IPN will be repeated later. The repeated IPN will be sent the same way if the IPN script does not refers to the PayPal server to verify the transaction.

As you may see from the description of the return, rm and notify_url parameters, IPN can be passed to two scripts specified in the return and notify_url parameters. There are two differences between them:

IPN for return will be sent only once, after the payment is performed. notify_url can be called several times (see the above paragraph).

The result of the return script will be shown to the user. It should be noted that if the result contains links, the links must be absolute. The result of the notify_url script is not displayed in the browser

The received POST variables contain transaction information. The most widely used variables are the following:

Parameter Description

txn_id Unique transaction number.

payment_date Payment date in the "18:30:30 Jan 1, 2000 PST" format .

payer_email Buyer's e-mail.

business Seller's e-mail.

payer_id Unique identifier of the buyer. Those who take part in payments performed with the help of PayPal are identified by an e-mail address. However, taking into consideration the possibility of changing the e-mail, payer_id should be better used for a buyer's

Page 34: Paypal Instruction

Parameter Description

identification.

item_number Item identifier.

item_name Item name.

txn_type

Transaction type. Possible values are:web_accept - the payment was performed by clicking the "Buy Now" button.cart - the payment was performed using the built-in PayPal cart.send_money - the payment was performed using the "Send money" function.reversal - money was returned to buyer on his initiative.

payment_status

Payment state. Possible values are:Completed - transaction was successfully performed, money is transferred to seller's account. If txn_type=reversal, then the money is returned to buyer's account.Pending - payment was delayed. The delay reason is determined in the pending_reason variable. After the payment is complete, PayPal will send another notification.Failed - payment failed. This state is possible only when the payment was performed from a bank account.Denied - seller cancelled the payment. The payment is in this state when the seller cancels the payment having the Pending state before.Refunded - money is returned to the buyer. The payment is in this state when the seller cancels the payment having the Completed state before.

pending_reason Reason of payment delay. Possible values are:echeck - payment was performed with an e-checkmulti_currency - payment was performed in the currency that is specified in settings of seller's account. The payment will be completed when the seller confirms the transaction.intl - seller is not a USA dweller. The payment will be completed when the seller confirms the transaction.verify - seller's account is in the unverified state. The payment will be completed when the seller is identified.address - settings of a seller's account require the buyer to specify the delivery address, but the buyer does not specify the address. The payment will be completed after seller confirms the transaction.upgrade - the payment was performed using a credit card and the seller's account has

Page 35: Paypal Instruction

Parameter Description

the Personal status. To complete the payment, the seller should upgrade the account to Business or Premier.unilateral - seller's e-mail is not registered in the system.other - another reason. Seller needs to contact Support to know more about the reason.

payment_type

Payment type. Possible values are:echeck - payment was performed with an e-check.instant - payment was performed with a credit card or using a bank account or money from the buyer's PayPal account.

mc_gross Payment amount.

mc_feeCommission charges. The amount that is put on the seller's account is determined as mc_gross – mc_fee.

mc_currency Payment currency.

first_name Buyer's name.

last_name Buyer's last name.

address_street Street.

address_city City.

address_state State/region.

address_zip Zip Code.

address_country Country.

verify_sign Digital signature. It is used in PayPal for transaction verification.

Table 2– The most widely used variables.

An Example of IPN Processing

Page 36: Paypal Instruction

Given below is an example of a script that uses PayPal IPN. We publish this script not to provide you with a ready script that you can copy/paste, but to illustrate the general principles of working with IPN. KB_Soft Group uses much more complicated scripts to create sites using the PayPal system. This script is rather easy, but at the same time it illustrates the main principles of IPN processing.

The given code creates a simplified version of an online shop. The buyer adds goods into the cart and pays for them. After the buyer pays, a payment report is created.

All information about goods and cart contents is stored in XML files. We chose this way of information storage only for reasons of compatibility. Any user who has downloaded the code can easily adjust and test the created online shop. As for real applications, databases should be better used to store information about goods, carts, payment requests and responses to them.

To store information about goods, we use the Goods.xml file having the following structure:

Collapse | Copy Code

<Goods>

<Good id="0" name="Sample of good" price="10.99" />

</Goods>

Where...

id is a unique item identifier

name is the item name

price is the item price

To make this example simple, we did not provide the created online shop with the functionality allowing new items to be added to the merchandise catalogue. Information about new items can be manually added into the XML file if needed.

To store information about carts, we use the Carts.xml file having the following structure:

Collapse | Copy Code

<Carts>

<Cart rec_id="0" cart_id="1" item_id="0" price="10.99" quantity="1" />

</Carts>

Where...

rec_id is a unique record identifier

Page 37: Paypal Instruction

cart_id is an identifier of the cart that contains this item

id is an item identifier

price is the item price

quantity is the quantity of ordered items

As for real online shops, information about paid carts is not stored there, but is written into the order table of DB. In order to simplify the process and to let you easily track the payment results, we did not implement this capability in the given code. Besides, real online shops should register users in order to be able to identify them and create carts that can be accessed only by their users. The given example does not use registration, so it does not control the access of different users to carts. This process is simplified since the user needs only to select his cart identifier.

To store information about payment requests, we use the PaymentRequests.xml file having the following structure:

Collapse | Copy Code

<Requests>

<Request request_id="0" cart_id="1" price="10.99"

request_date="5/28/2007 1:15:18 PM" />

</Requests>

Where...

request_id is a unique request identifier

cart_id is an identifier of the cart being paid

price is the cost of goods

request_date is the date and the time when the request is created

In real online shops, information about payment requests contains an identifier of payment details from the table of payment details. To simplify the code, we did not use this.

To store information about responses to payment requests, we use the PaymentResponses.xml file having the following structure:

Collapse | Copy Code

<Responses>

<Response payment_id="0"

Page 38: Paypal Instruction

txn_id="3PP58082BD3079037"

payment_date="5/28/2007 1:22:40 PM"

payment_price="10.99"

email= [email protected]

first_name=""

last_name=""

street=""

city=""

state=""

zip=""

country=""

request_id="0"

is_success="True"

reason_fault=""

/>

</Responses>

Where...

payment_id is a unique payment identifier

txn_id is the unique number of the PayPal transaction

payment_date is the date and time when payment is performed

payment_price is the payment amount

email is the buyer's e-mail

first_name is the buyer's first name

last_name is the buyer's last name

street is the buyer's street

Page 39: Paypal Instruction

city is the buyer's city

state is the buyer's state

zip is the buyer's ZIP code

country is the buyer's country

request_id is an identifier of payment request

is_success indicates whether the payment was successfully performed

reason_fault is a possible reason of payment failure

If we use XML files to store information, we should better use the XML schema to validate the information. However, we do not perform validation in order to simplify the example.

The form of payment request that is sent to PayPal is as follows:

Collapse | Copy Code

<form id="payForm" method="post" action="<%Response.Write (URL)%>">

<input type="hidden" name="cmd" value="<%Response.Write (cmd)%>">

<input type="hidden" name="business"

value="<%Response.Write (business)%>">

<input type="hidden" name="item_name"

value="<%Response.Write (item_name)%>">

<input type="hidden" name="amount" value="<%Response.Write (amount)%>">

<input type="hidden" name="no_shipping"

value="<%Response.Write (no_shipping)%>">

<input type="hidden" name="return"

value="<%Response.Write (return_url)%>">

<input type="hidden" name="rm" value="<%Response.Write (rm)%>">

<input type="hidden" name="notify_url"

value="<%Response.Write (notify_url)%>">

<input type="hidden" name="cancel_return"

Page 40: Paypal Instruction

value="<%Response.Write (cancel_url)%>">

<input type="hidden" name="currency_code"

value="<%Response.Write (currency_code)%>">

<input type="hidden" name="custom"

value="<%Response.Write (request_id)%>">

</form>

Where...

URL is the URL to work with, depending on whether sandbox or a real PayPal account should be used

cmd is a command that is sent to PayPal

business is the seller's e-mail

item_name is the item name -- i.e. what buyer pays for -- that will be shown to user;

amount is the payment amount

no_shipping is a parameter that determines whether the delivery address should be requested

return_url is the URL that the buyer will be redirected to when payment is successfully performed

rm is a parameter that determines the way in which information about a successfully finished transaction will be sent to the script specified in the return parameter

notify_url is the URL PayPal will send information about transaction (IPN) to

cancel_url is the URL that the buyer is redirected to when he cancels payment

currency_code is the currency code

request_id is an identifier of payment request

Values of the variables are set in the PayPal.aspx.cs or the tPayPal.aspx.vb file of the source code attached to the article. See Table 1 for a more detailed description of the fields of the form.

When request_id is passed in the custom field, it allows the IPN script to restore information about the cart. If the buyer cancels payment, he is redirected to cancel_url. However, if he performs the payment, he is redirected to return_url. In the latter case, we can test interaction with PayPal, check whether the payment was performed, create a payment report and thank the buyer for the purchase. As for the given example, use the code of IPN processing in the payment_success.aspx.cs or payment_success.aspx.vb file only for testing, since real products should validate payments in the IPN script specified in the notify_url parameter for the purposes of security. The payment_success.aspx.cs or

Page 41: Paypal Instruction

payment_success.aspx.vb code was specially written to make the testing process give as much information as possible. The code contains messages that are important only on the testing stage. This information is written into a log file. The file stores not only critical errors, but also the errors that allow the site to keep on working.

In general, error messages should be properly handled, but not shown to users as exceptions. The Response.Write() construction is not a good idea too. Real sites usually create a special page where information about errors is sent. Then the information is formatted and shown to the user. For example, the user should be redirected to this page if an exception is thrown out or a page requested from the site is absent. To simplify the given example, the code writes information about most errors that occur to the log file.

The return parameter is useful because when the payment is performed, it allows the result of the verification to be shown to the user. However, the verification does not provide a 100% guarantee that the payment was really put into the seller's account. For example, if the buyer uses an e-check, then the payment will be put into the seller's account only after the check is processed in a bank that also does not provide a guarantee that the money is put into the account. That's why real online shops should use IPN and work with payment, check the payment and protocol it in the code of the IPN script. Besides, the content of the form should be encrypted before it is sent in order to avoid forgery of the payment information. That means that so-called Encrypted Website Payments should be used. If you are not going to use Encrypted Website Payments (EWP) validation, you must check the price, transaction ID, PayPal receiver email address and other data sent to you by IPN to ensure that they are correct. By examining the data, you can be sure that you are not being spoofed.

KB_Soft Group uses both EWP and validation of the parameters received from PayPal in its projects. This provides the duplicated validation check and rules out any possibility of information forgery. In order to simplify the given example of an online shop and to make it work on any PayPal account, we use only IPN. This is because if we use EWP we have to create private and public keys and upload the created public key to our account on the PayPal server. Then we would need to use the obtained identifier of certificate to encrypt the form of the request. Besides, to use EWP we need to download a public key of the PayPal system itself. This article is not aimed at describing in detail the principles of work with EPW, so you can visit the PayPal site to find detailed information on this issue instead.

The IPNHandler class' Page_Load procedure code is given below. You can find detailed information in the archives associated with the source code attached to this article.

C#

Collapse | Copy Code

private void Page_Load(object sender, EventArgs e)

{

string requestUriString;

Page 42: Paypal Instruction

CultureInfo provider = new CultureInfo("en-us");

string requestsFile = this.Server.MapPath(

"~/App_Data/PaymentRequests.xml");

requests.Clear();

if (System.IO.File.Exists(requestsFile))

{

requests.ReadXml(requestsFile);

}

else

{

Carts.CreateXml(requestsFile, "Requests");

requests.ReadXml(requestsFile);

}

string responseFile = this.Server.MapPath(

"~/App_Data/PaymentResponses.xml");

responses.Clear();

if (System.IO.File.Exists(responseFile))

{

responses.ReadXml(responseFile);

}

else

{

Carts.CreateXml(responseFile, "Responses");

responses.ReadXml(responseFile);

}

Page 43: Paypal Instruction

string strFormValues = Encoding.ASCII.GetString(

this.Request.BinaryRead(this.Request.ContentLength));

// getting the URL to work with

if (String.Compare(

ConfigurationManager.AppSettings["UseSandbox"].ToString(),

"true", false) == 0)

{

requestUriString =

"https://www.sandbox.paypal.com/cgi-bin/webscr";

}

else

{

requestUriString = "https://www.paypal.com/cgi-bin/webscr";

}

// Create the request back

HttpWebRequest request =

(HttpWebRequest)WebRequest.Create(requestUriString);

// Set values for the request back

request.Method = "POST";

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

string obj2 = strFormValues + "&cmd=_notify-validate";

request.ContentLength = obj2.Length;

Page 44: Paypal Instruction

// Write the request back IPN strings

StreamWriter writer =

new StreamWriter(request.GetRequestStream(), Encoding.ASCII);

writer.Write(RuntimeHelpers.GetObjectValue(obj2));

writer.Close();

//send the request, read the response

HttpWebResponse response = (HttpWebResponse)request.GetResponse();

Stream responseStream = response.GetResponseStream();

Encoding encoding = Encoding.GetEncoding("utf-8");

StreamReader reader = new StreamReader(responseStream, encoding);

// Reads 256 characters at a time.

char[] buffer = new char[0x101];

int length = reader.Read(buffer, 0, 0x100);

while (length > 0)

{

// Dumps the 256 characters to a string

string requestPrice;

string IPNResponse = new string(buffer, 0, length);

length = reader.Read(buffer, 0, 0x100);

try

Page 45: Paypal Instruction

{

// getting the total cost of the goods in

// cart for an identifier

// of the request stored in the "custom" variable

requestPrice =

GetRequestPrice(this.Request["custom"].ToString());

if (String.Compare(requestPrice, "", false) == 0)

{

Carts.WriteFile("Error in IPNHandler: amount = \");

reader.Close();

response.Close();

return;

}

}

catch (Exception exception)

{

Carts.WriteFile("Error in IPNHandler: " + exception.Message);

reader.Close();

response.Close();

return;

}

NumberFormatInfo info2 = new NumberFormatInfo();

info2.NumberDecimalSeparator = ".";

info2.NumberGroupSeparator = ",";

Page 46: Paypal Instruction

info2.NumberGroupSizes = new int[] { 3 };

// if the request is verified

if (String.Compare(IPNResponse, "VERIFIED", false) == 0)

{

// check the receiver's e-mail (login is user's

// identifier in PayPal)

// and the transaction type

if ((String.Compare(this.Request["receiver_email"],

this.business, false) != 0) ||

(String.Compare(this.Request["txn_type"],

"web_accept", false) != 0))

{

try

{

// parameters are not correct. Write a

// response from PayPal

// and create a record in the Log file.

this.CreatePaymentResponses(this.Request["txn_id"],

Convert.ToDecimal(

this.Request["mc_gross"], info2),

this.Request["payer_email"],

this.Request["first_name"],

this.Request["last_name"],

this.Request["address_street"],

Page 47: Paypal Instruction

this.Request["address_city"],

this.Request["address_state"],

this.Request["address_zip"],

this.Request["address_country"],

Convert.ToInt32(this.Request["custom"]), false,

"INVALID payment's parameters" +

"(receiver_email or txn_type)");

Carts.WriteFile(

"Error in IPNHandler: INVALID payment's" +

" parameters(receiver_email or txn_type)");

}

catch (Exception exception)

{

Carts.WriteFile("Error in IPNHandler: " +

exception.Message);

}

reader.Close();

response.Close();

return;

}

// check whether this request was performed

// earlier for its identifier

if (this.IsDuplicateID(this.Request["txn_id"]))

{

Page 48: Paypal Instruction

// the current request is processed. Write

// a response from PayPal

// and create a record in the Log file.

this.CreatePaymentResponses(this.Request["txn_id"],

Convert.ToDecimal(this.Request["mc_gross"], info2),

this.Request["payer_email"],

this.Request["first_name"],

this.Request["last_name"],

this.Request["address_street"],

this.Request["address_city"],

this.Request["address_state"],

this.Request["address_zip"],

this.Request["address_country"],

Convert.ToInt32(this.Request["custom"]), false,

"Duplicate txn_id found");

Carts.WriteFile(

"Error in IPNHandler: Duplicate txn_id found");

reader.Close();

response.Close();

return;

}

// the amount of payment, the status of the

// payment, and a possible reason of delay

// The fact that Getting txn_type=web_accept or

Page 49: Paypal Instruction

// txn_type=subscr_payment are got odes not mean that

// seller will receive the payment.

// That's why we check payment_status=completed. The

// single exception is when the seller's account in

// not American and pending_reason=intl

if (((String.Compare(

this.Request["mc_gross"].ToString(provider),

requestPrice, false) != 0) ||

(String.Compare(this.Request["mc_currency"],

this.currency_code, false) != 0)) ||

((String.Compare(this.Request["payment_status"],

"Completed", false) != 0) &&

(String.Compare(this.Request["pending_reason"],

"intl", false) != 0)))

{

// parameters are incorrect or the payment

// was delayed. A response from PayPal should not be

// written to DB of an XML file

// because it may lead to a failure of

// uniqueness check of the request identifier.

// Create a record in the Log file with information

// about the request.

Carts.WriteFile(

"Error in IPNHandler: INVALID payment's parameters."+

"Request: " + strFormValues);

Page 50: Paypal Instruction

reader.Close();

response.Close();

return;

}

try

{

// write a response from PayPal

this.CreatePaymentResponses(this.Request["txn_id"],

Convert.ToDecimal(this.Request["mc_gross"], info2),

this.Request["payer_email"],

this.Request["first_name"],

this.Request["last_name"],

this.Request["address_street"],

this.Request["address_city"],

this.Request["address_state"],

this.Request["address_zip"],

this.Request["address_country"],

Convert.ToInt32(this.Request["custom"]), true, "");

Carts.WriteFile(

"Success in IPNHandler: PaymentResponses created");

///////////////////////////////////////////////////

// Here we notify the person responsible for

// goods delivery that

// the payment was performed and providing

Page 51: Paypal Instruction

// him with all needed information about

// the payment. Some flags informing that

// user paid for a services can be also set here.

// For example, if user paid for registration

// on the site, then the flag should be set

// allowing the user who paid to access the site

//////////////////////////////////////////////////

}

catch (Exception exception)

{

Carts.WriteFile(

"Error in IPNHandler: " + exception.Message);

}

}

else

{

Carts.WriteFile(

"Error in IPNHandler. IPNResponse = 'INVALID'");

}

}

reader.Close();

response.Close();

}

Visual Basic

Collapse | Copy Code

Page 52: Paypal Instruction

Private Sub Page_Load(ByVal sender As System.Object,

ByVal e As System.EventArgs) Handles MyBase.Load

Dim ci As CultureInfo = New CultureInfo("en-us")

Dim requestsFile As String = Server.MapPath(

"~/App_Data/PaymentRequests.xml")

requests.Clear()

If File.Exists(requestsFile) Then

requests.ReadXml(requestsFile)

Else

KBSoft.Carts.CreateXml(requestsFile, "Requests")

requests.ReadXml(requestsFile)

End If

Dim responseFile As String = Server.MapPath(

"~/App_Data/PaymentResponses.xml")

responses.Clear()

If File.Exists(responseFile) Then

responses.ReadXml(responseFile)

Else

KBSoft.Carts.CreateXml(responseFile, "Responses")

responses.ReadXml(responseFile)

End If

Page 53: Paypal Instruction

Dim strFormValues As String = Encoding.ASCII.GetString(

Request.BinaryRead(Request.ContentLength))

Dim strNewValue

' getting the URL to work with

Dim URL As String

If AppSettings("UseSandbox").ToString = "true" Then

URL = "https://www.sandbox.paypal.com/cgi-bin/webscr"

Else

URL = "https://www.paypal.com/cgi-bin/webscr"

End If

' Create the request back

Dim req As HttpWebRequest = CType(WebRequest.Create(URL),

HttpWebRequest)

' Set values for the request back

req.Method = "POST"

req.ContentType = "application/x-www-form-urlencoded"

strNewValue = strFormValues + "&cmd=_notify-validate"

req.ContentLength = strNewValue.Length

' Write the request back IPN strings

Dim stOut As StreamWriter = New StreamWriter(

Page 54: Paypal Instruction

req.GetRequestStream(), _

Encoding.ASCII)

stOut.Write(strNewValue)

stOut.Close()

'send the request, read the response

Dim strResponse As HttpWebResponse = CType(req.GetResponse(),

HttpWebResponse)

Dim IPNResponseStream As Stream = strResponse.GetResponseStream

Dim encode As Encoding = System.Text.Encoding.GetEncoding("utf-8")

Dim readStream As New StreamReader(IPNResponseStream, encode)

Dim read(256) As [Char]

' Reads 256 characters at a time.

Dim count As Integer = readStream.Read(read, 0, 256)

While count > 0

' Dumps the 256 characters to a string

Dim IPNResponse As New [String](read, 0, count)

count = readStream.Read(read, 0, 256)

Dim amount As String

Try

' getting the total cost of the goods in cart for an

' identifier of the request stored in the "custom"

' variable

Page 55: Paypal Instruction

amount = GetRequestPrice(Request("custom").ToString)

If amount = "" Then

KBSoft.Carts.WriteFile("Error in IPNHandler: amount = """)

readStream.Close()

strResponse.Close()

Return

End If

Catch ex As Exception

KBSoft.Carts.WriteFile("Error in IPNHandler: " + ex.Message)

readStream.Close()

strResponse.Close()

Return

End Try

Dim provider As NumberFormatInfo = New NumberFormatInfo()

provider.NumberDecimalSeparator = "."

provider.NumberGroupSeparator = ","

provider.NumberGroupSizes = New Integer() {3}

' if the request is verified

If IPNResponse = "VERIFIED" Then

' check the receiver's e-mail (login is user's

' identifier in PayPal) and the transaction type

If Request("receiver_email") <> business Or Request(

Page 56: Paypal Instruction

"txn_type") <> "web_accept" Then

Try

' parameters are not correct. Write a response from

' PayPal and create a record in the Log file.

CreatePaymentResponses(Request("txn_id"),

Convert.ToDecimal(Request("mc_gross"), provider), _

Request("payer_email"), Request("first_name"),

Request("last_name"), Request("address_street"), _

Request("address_city"), Request("address_state"),

Request("address_zip"), Request("address_country"), _

Convert.ToInt32(Request("custom")), False,

"INVALID payment's parameters (

receiver_email or txn_type)")

KBSoft.Carts.WriteFile(

"Error in IPNHandler: INVALID payment's parameters"+

" (receiver_email or txn_type)")

Catch ex As Exception

KBSoft.Carts.WriteFile(

"Error in IPNHandler: " + ex.Message)

End Try

readStream.Close()

strResponse.Close()

Return

End If

' check whether this request was performed earlier for its

Page 57: Paypal Instruction

' identifier

If IsDuplicateID(Request("txn_id")) Then

' the current request is processed. Write a response from

' PayPal and create a record in the Log file.

CreatePaymentResponses(Request("txn_id"),

Convert.ToDecimal(Request("mc_gross"), provider), _

Request("payer_email"), Request("first_name"),

Request("last_name"), Request("address_street"), _

Request("address_city"), Request("address_state"),

Request("address_zip"), Request("address_country"), _

Convert.ToInt32(Request("custom")), False,

"Duplicate txn_id found")

KBSoft.Carts.WriteFile(

"Error in IPNHandler: Duplicate txn_id found")

readStream.Close()

strResponse.Close()

Return

End If

' the amount of payment, the status of the payment, and a

' possible reason of delay

' The fact that Getting txn_type=web_accept or

' txn_type=subscr_payment are got odes not mean that

' seller will receive the payment.

' That's why we check payment_status=completed. The

' single exception is when the seller's account in

Page 58: Paypal Instruction

' not American and pending_reason=intl

If Request("mc_gross").ToString(ci) <> amount Or Request(

"mc_currency") <> currency_code Or _

(Request("payment_status") <> "Completed" And Request(

"pending_reason") <> "intl") Then

' parameters are incorrect or the payment was delayed.

' A response from PayPal should not be

' written to DB of an XML file

' because it may lead to a failure of uniqueness check of

' the request identifier.

' Create a record in the Log file with information about

' the request.

KBSoft.Carts.WriteFile(

"Error in IPNHandler: INVALID payment's parameters."+

" Request: " + strFormValues)

readStream.Close()

strResponse.Close()

Return

End If

Try

' write a response from PayPal

CreatePaymentResponses(Request("txn_id"),

Convert.ToDecimal(Request("mc_gross"), provider), _

Request("payer_email"), Request("first_name"),

Page 59: Paypal Instruction

Request("last_name"), Request("address_street"), _

Request("address_city"), Request("address_state"),

Request("address_zip"), Request("address_country"), _

Convert.ToInt32(Request("custom")), True, "")

KBSoft.Carts.WriteFile(

"Success in IPNHandler: PaymentResponses created")

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

' Here we notify the person responsible for goods delivery

' that the payment was performed and providing him with

' all needed information about the payment. Some flags

' informing that user paid for a services can be also

' set here. For example, if user paid for registration

' on the site, then the flag should be set

' allowing the user who paid to access the site

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Catch ex As Exception

KBSoft.Carts.WriteFile(

"Error in IPNHandler: " + ex.Message)

End Try

Else

KBSoft.Carts.WriteFile(

"Error in IPNHandler. IPNResponse = 'INVALID'")

Page 60: Paypal Instruction

End If

End While

readStream.Close()

strResponse.Close()

End Sub

Parameters of web.config Adjustment

To use the source code attached to this article, you need the web.config parameters to be correctly specified. While adjusting the parameters in the web.config file, you should pay special attention to the appSettings settings:

Collapse | Copy Code

<appSettings>

<!-- PayPay parameters-->

<add key="BusinessEmail" value="[email protected]"/>

<add key="CancelPurchaseUrl" value="http://YOUR_IP/paypal/default.aspx"/>

<add key="ReturnUrl" value="http://YOUR_IP/paypal/payment_success.aspx"/>

<add key="NotifyUrl" value="http://YOUR_IP/paypal/IPNHandler.aspx"/>

<add key="CurrencyCode" value="USD"/>

<add key="UseSandbox" value="true"/>

<add key="SendToReturnURL" value="true"/>

</appSettings>

Specify the e-mail of the payment recipient in the BusinessEmail parameter. This can be the e-mail that was used while creating an account on PayPal or an alternative e-mail specified in the account parameters as the alternative e-mail. The e-mail that is used as the login to the PayPal account is usually specified in this parameter. As for the CancelPurchaseUrl, ReturnUrl and NotifyUrl parameters: in YOUR_IP you need to specify your global IP address -- not your IP address in local network -- or a domain of the registered site on which the seller's site is hosted. While testing, you may simply specify localhost instead of YOUR_IP. It should be noted that IPN will function only if you correctly specify the global IP address or the name of a registered domain. If you specify localhost, then only the script specified in the

Page 61: Paypal Instruction

ReturnUrl parameter will be able to support interaction with PayPal. The script specified in the NotifyUrl parameter will not. You should keep in mind that IPN may be blocked, depending on the Firewall settings.

The above links are given for the "paypal" virtual directory. If you use another virtual directory or site, you need to specify its name instead of "paypal." To check whether your NotifyUrl is valid, enter its address into "Notification URL:" filed at Profile->Instant Payment Notification Preferences->Edit in your PayPal Business or Premier account. Check the checkbox on this page and click the "Save" button. If the URL is valid, a message about successful validation will be shown.

The CurrencyCode parameter is used to specify the code of the currency that is used for payment. The UseSandbox parameter is used to switch between PayPal SandBox and real PayPal accounts. The SendToReturnURL parameter is used to turn on/off notifications sending to return_url. SendToReturnURL is recommended to be set to true only for the purposes of testing.

Use of the Source Code

Archives with the source code of a simplified online shop are attached to this article. You can use this code in your software products to support interaction with PayPal when you need to perform payments.

To use the code supplied with the article, you need to have .NET Framework 2.0 or higher installed on your system. You also need to have a real or SandBox PayPal account. No additional requirements should be needed to open a SandBox account. However, to create a real PayPal account, you need to have a credit card and/or an account in any American bank. Make sure that the standard WebClient service is running on your system. If you have Visual Studio 2005, you can run tests by opening the paypal.sln solution and executing the code. IPN will not be available in this case. An alternative option is the creation of a virtual directory on the IIS server.

Conclusion

In conclusion, I would like to give you some advice:

Do not ever trust the data obtained by the IPN script before you receive the VERIFIED response from PayPal. Information about processed transactions should be kept. So, when the VERIFIED response is received, you can make sure that the transaction was not processed before.

Do not use payer_email to identify buyers, as the e-mail can be changed. Use payer_id.

txn_type=web_accept does not mean that the seller will receive payment. You should always check if payment_status=completed. The single exception is a seller whose account is not American and pending_reason=intl.

Failures are not impossible in any system and PayPal is no exception. If the IPN script receives suspect data, it should be written to log and an administrator should be informed about this. It is also useful to implement a form for users to be able to inform you about errors.

Page 62: Paypal Instruction

http://www.codeproject.com/Articles/19184/Use-of-the-PayPal-payment-system-in-ASP-NET

Page 63: Paypal Instruction

Download source - 65.63 KB

IntroductionTo do an online credit card transaction in ASP.NET using PayPal Payflow Pro, you’ll need to set up a Payflow Pro online payment gateway account at PayPal.com, download and install .NET SKD for Payflow Pro, and create an ASP.NET application that sends a transaction request to and receives a transaction response from Payflow Pro.

Payflow Pro Online Payment Gateway AccountAt the time of writing this article, the account creation link is: https://registration. paypal .com/welcomePage.do? producttype=C2&country=US&mode=try. PayPal documentation indicates that a testing account can be created, which can then be activated as a production account if needed. Upon the completion of an account setup, you’ll have four user parameters as login credentials to access the account, as shown in the table below.

Using these credentials, you are able to log into https://manager. paypal .com to manage your account settings, to view/manage transactions, and to generate reports, etc. These same user parameters are also required for online transaction in your ASP.NET application.

.NET SDK for Payflow ProPayPal SDK download page is https://cms. paypal .com/us/cgi-bin/?cmd=_render- content&content_ID=developer/library_download_sdks&fli=true#PayflowPro. Scroll down to near bottom of the page, you’ll see the download link for .NET SDK for Payflow

Page 64: Paypal Instruction

Pro v4.31 released in January, 2009. At this time, this is the most current version available.

Download and install the package to your local development machine. By default, it is installed at C:\Program Files\Payflow SDK for .NET\. Browse to the folder, you’ll see two DLLs: Payflow_dotNET_1.1.dll and Payflow_dotNET_2.0.dll which are, as their names imply, for .NET Framework 1.1 and 2.0 respectively. Choose the version you need and RENAME it to Payfow_dotNET.dll before adding a reference to your web application in Visual Studio. As you can see, the SDK has not been updated to the current .NET Framework 4. However, it works fine in the application coded in .NET Framework 4 using Visual Studio 2010.

How Online Transaction WorksUtilizing .NET SDK for Payflow Pro classes, your application sends a transaction request to a Payflow Pro host, where Payflow Pro server processes the request and then sends back a transaction response to your application to notify you of the transaction status. In the request and response cycle, a credit card transaction is accomplished and funds are moved in or out of your bank account that is linked to your Payflow Pro payment gateway account.

Host Name

The host name is a URL for the Payflow Pro server. Payflow Pro provides one for testing and another for production.

For testing : pilot-payflowpro.paypal.com For production: payflowpro.paypal.com

Please note that both testing transaction and production transaction go through the same Payflow Pro account. When you log into https://manager. paypal .com , you are able to search, view and manage both.

Transaction Request

A transaction request consists of a string of name value pairs concatenated with a “&”, which contains all payment information needed in a transaction, such as transaction type, payment method, credit card information, user parameters (credentials) for Payflow Pro account, etc. Some are required, and some optional. Here is an example of a transaction request string:

Collapse | Copy Code

TRXTYPE=S&TENDER=C&ACCT=5105105105105100&EXPDATE=1209&CVV2=123&AMT=99.00&FIRSTNAME=John&LASTNAME=Smith&STREET=123 Main St.&CITY=SanHose&STATE=CA&ZIP=12345&COMMENT1=Reservation&USER=MyUser&PWD=MyPassword&VENDOR=MyVendor&PARTNER=MyPartner

Page 65: Paypal Instruction

In which, TRXTYPE=S indicates it is a sale transaction type and TENDER=C shows that a credit card is used as the method of payment. The tables below lists common parameters and their descriptions used in a transaction request.

Page 66: Paypal Instruction
Page 67: Paypal Instruction

If a parameter is marked as required, it has to be included in a transaction request to get accepted by Payflow Pro server.

Transaction Response

Similarly, a transaction response that your application receives from Payflow Pro is also a string of name value pairs. It provides transaction results including status, transaction number, authorization code, or errors. The string shown below is an example.

Collapse | Copy Code

RESULT=0&PNREF=EFHP0D426A53&RESPMSG=APPROVED&AUTHCODE=25TEST&AVSADDR=Y&AVSZIP=N&CVV2MATCH=Y

RESULT=0 means that the transaction is approved. Any value that is greater than 0 indicates a decline or an error. RESPMSG (response message) gives a brief description

Page 68: Paypal Instruction

for an approved transaction, a declined transaction, or an error corresponding to a result code. The table below displays typical parameters in a Payflow Pro response.

ASP.NET ApplicationNow let’s take a look at how we can implement the transaction process discussed above in an ASP.NET application using .NET SDK for Payflow Pro. A demo application has been prepared for download. It is coded in Visual Studio 2010, .NET Framework 4 using Payflow_dotNET.dll for Framework 2.0.

The application has only one ASP.NET page that collects payment amount and credit card information, constructs a transaction request string, sends the request to and receives a transaction response from Payflow Pro, and then displays the data on the page.

Page 69: Paypal Instruction

The above screen shot illustrates the web interface for collecting the required data. Upon clicking the Submit button, the transaction request string is constructed and sent to Payflow Pro host, and a response string is then received from the host. The screen shot below displays the name values pairs of the request and the response respectively.

When you run this application, you may not see a successful transaction but a failed status. This is because invalid user parameters (USER, VENDOR, PARTNER and PWD) are used in the transaction request. You’ll need to update the user parameters stored in the

Page 70: Paypal Instruction

<appSettings> section of the web.config with valid values associated with your Payflow Pro account.

In the application, the Payflow_dotNET_2.0.dll that came with the .NET SDK for Payflow Pro installation was renamed to Payflow_dotNET.dll and then added to the Visual Studio project as a reference.

Let’s have a look at the code listing:

Collapse | Copy Code

using System;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using System.Collections.Specialized;using System.Configuration;using PayPal.Payments.Common.Utility;using PayPal.Payments.Communication;using PayPal.Payments.DataObjects;

public partial class _Default : System.Web.UI.Page{ protected void Page_Load(object sender, EventArgs e) { if (Page.IsPostBack) { return; }

//populate month string[] Month = new string[]

{ "", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12" }; ddlMonth.DataSource = Month; ddlMonth.DataBind(); //pre-select one for testing ddlMonth.SelectedIndex = 4;

//populate year ddlYear.Items.Add(""); int Year = DateTime.Now.Year; for (int i = 0; i < 10; i++) { ddlYear.Items.Add((Year + i).ToString()); } //pre-select one for testing ddlYear.SelectedIndex = 3; } protected void btnSubmit_Click(object sender, EventArgs e) { try { string PayPalRequest = "TRXTYPE=S" //S - sale transaction + "&TENDER=C" //C - Credit card + "&ACCT=" + txtCardNumber.Text //card number + "&EXPDATE=" + ddlMonth.SelectedValue +

ddlYear.SelectedValue.Substring(2, 2)

Page 71: Paypal Instruction

+ "&CVV2=" + txtCvv.Text //card validation value (card security code) + "&AMT=" + txtAmount.Text + "&COMMENT1=My Product Sale" + "&USER=" + ConfigurationManager.AppSettings["USER"] + "&VENDOR=" + ConfigurationManager.AppSettings["VENDOR"] + "&PARTNER=" + ConfigurationManager.AppSettings["PARTNER"] + "&PWD=" + ConfigurationManager.AppSettings["PWD"];

// Create an instance of PayflowNETAPI. PayflowNETAPI PayflowNETAPI = new PayflowNETAPI();

// RequestId is a unique string that is required for each & every transaction. // The merchant can use her/his own algorithm to generate // this unique request id or use the SDK provided API to generate this // as shown below (PayflowUtility.RequestId). string PayPalResponse = PayflowNETAPI.SubmitTransaction

(PayPalRequest, PayflowUtility.RequestId); //place data from PayPal into a namevaluecollection NameValueCollection RequestCollection =

GetPayPalCollection(PayflowNETAPI.TransactionRequest); NameValueCollection ResponseCollection = GetPayPalCollection(PayPalResponse);

//show request lblResult.Text = "<span class=\"heading\">

PayPal Payflow Pro transaction request</span><br />"; lblResult.Text += ShowPayPalInfo(RequestCollection);

//show response lblResult.Text += "<br /><br /><span class=\"heading\">

PayPal Payflow Pro transaction response</span><br />"; lblResult.Text += ShowPayPalInfo(ResponseCollection); //show transaction errors if any string TransErrors = PayflowNETAPI.TransactionContext.ToString(); if (TransErrors != null && TransErrors.Length > 0) { lblResult.Text += "<br /><br /><span class=\"bold-text\">

Transaction Errors:</span> " + TransErrors; }

//show transaction status lblResult.Text += "<br /><br /><span class=\"bold-text\">

Status:</span> " + PayflowUtility.GetStatus(PayPalResponse); } catch (Exception ex) { lblError.Text = ex.Message.ToString(); } }

private NameValueCollection GetPayPalCollection(string payPalInfo) { //place the responses into collection NameValueCollection PayPalCollection =

new System.Collections.Specialized.NameValueCollection(); string[] ArrayReponses = payPalInfo.Split('&');

Page 72: Paypal Instruction

for (int i = 0; i < ArrayReponses.Length; i++) { string[] Temp = ArrayReponses[i].Split('='); PayPalCollection.Add(Temp[0], Temp[1]); } return PayPalCollection; } private string ShowPayPalInfo(NameValueCollection collection) { string PayPalInfo = ""; foreach (string key in collection.AllKeys) { PayPalInfo += "<br /><span class=\"bold-text\">" +

key + ":</span> " + collection[key]; } return PayPalInfo; }}

Three “using Directives” are required in order to use .NET SDK for Payflow Pro: PayPal.Payments.Common.Utility, PayPal.Payments.Communication and PayPal.Payments.DataObjects.

The transaction related code is shown inside the btnSubmit_Click event handler.

First of all, a string of name value pairs is concatenated and assigned to the variable PayPalRequest. This string includes transaction type (TRXTYPE=S: sale), payment method (TENDER=C: credit card), credit card number, expiration date, amount to charge, user parameters (credentials) for Payflow Pro account, etc. More may be added as needed.

Secondly, an instance of PayflowNETAPI is created so that its properties and methods are exposed to our application.

Thirdly, the method PayflowNETAPI.SubmitTransaction() is called to perform the transaction. This method requires two parameters, a transaction request string built earlier and a RequestId that is an unique ID generated by PayflowUtility object. The return type of the method is a string (stored in the variable PayPalResponse), which is the response from Payflow Pro, consisting of name value pair for transaction results. That is all for a transaction cycle. The rest of the code displays the transaction data on the page, which can be handled differently depending on the requirements in a real world business application.

You may have noticed that in the code sample, Payflow Pro host name is not used anywhere. This is because the host name is placed in the <appSettings> section of web.config file. The SDK knows where to retrieve it directly during a method call. The listing below shows the standard settings provided by the SDK. Some are related to tracing and logging tasks that the SDK also does. These are not turned on in the demo.

Collapse | Copy Code

Page 73: Paypal Instruction

<appSettings> <!-- Payflow Pro Host Name. This is the host name for the PayPal Payment Gateway. For testing: pilot-payflowpro.paypal.com. For production: payflowpro.paypal.com --> <add key="PAYFLOW_HOST" value="pilot-payflowpro.paypal.com" /> <!-- TRACE value when set to ON will show the complete exception stack trace in the response message, if any. Change TRACE value to "ON" to switch on the stack trace in response message.--> <add key="TRACE" value="OFF" /> <!-- This is a LOG level tag.To switch on logging change the

logger level from "OFF" to any of the following: a. DEBUG b. INFO c. WARN d. ERROR e. FATAL --> <add key="LOG_LEVEL" value="OFF" /> <!-- Relative path for LOG file. --> <add key="LOG_FILE" value="logs\PayflowSDK.log" /> <!-- Log file filesize constant. --> <add key="LOGFILE_SIZE" value="102300" /> </appSettings>

SummaryThis article takes a sale credit card transaction as an example to demonstrate how to use .NET SDK for Payflow Pro in ASP.NET. There are other types of transaction, such as Authorization, Void, Delayed Capture, etc. that can all be done using the SDK. No matter what transaction type is involved, in general, it is a similar process of sending a transaction request to a Payflow Pro host and receiving a transaction response from the host, as illustrated in our demo application.  

http://www.codeproject.com/Articles/152280/Online-Credit-Card-Transaction-in-ASP-NET-Using-Pa


Recommended