use of the paypal payment system in aspdotnet (1)

20
Use of the PayPal payment system in ASP.NET Introduction Those who create commercial si tes are faced with the question, "How should i t receive payments?" One of the most popular payment systems in the world is  PayPal. This system is often chosen because it is reli able, simple to use and allows an acc ount 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 i s to show how payments processing can be organized to supp ort 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 wi th the PayPal system. You can use the code in your appli cations 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 artic le 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

Upload: pradeep-soni

Post on 07-Apr-2018

220 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 1/20

Use of the PayPal payment system in ASP.NET

Introduction

Those who create commercial sites are faced with the question, "How should it receivepayments?" One of the most popular payment systems in the world is PayPal . This system isoften 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 Americanbank. One of shortcomings of the system is its severe security policy. However, practiceevinces that if you follow the rules of the system carefully, then errors are very rare. Thepurpose of this article is to show how payments processing can be organized to supportreliability and security. The article is also aimed at providing you with an example of thedevelopment of a simple online shop, in order to demonstrate interaction with the PayPalsystem. You can use the code in your applications to organize interaction with the PayPalsystem 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 andthe 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 operationssupporting the cart in this case. Unfortunately, this option does not provide themaximal flexibility that is required for implementation of some projects, so the articledoes not consider this option.

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

Recurring billing or subscription. PayPal provides a subscription capability whichmeans that a definite sum will be periodically transferred from the user's account to

Page 2: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 2/20

the seller's account. The user can unsubscribe anytime. The seller can specify thesubscription's period and cost. He can also organize a trial period to let the userassess the quality of the services he provides. The trial period can be either paid orfree.

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 PayPalsystem, KB_Soft Group uses UserControl, which is a product internally developed for thesepurposes. The given example of the code that works with PayPal uses a special HTML formfor requests in order to make clear the explanation of interaction with the system. PayPalalso provides its own Control as a dynamic library, but unfortunately, this control functionscorrectly only with American locale (en-us). Besides, it does not provide full functionality towork 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 thatcontain information about an item (identifier, name, and cost) and a button to send theform. 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 PayPalaccount is used, the form should be sent here . The developed example also allows you towork with the PayPal Sandbox. Use the UseSandbox parameter of web.config and the formwill 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 >

Description of Main Parameters

Parameter Description

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

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

item_number This parameter is an item identifier. This value will not be shown to theuser; however, it will be passed to your script at the time of transaction

Page 3: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 3/20

Parameter Description

confirmation. If you plan to use PayPal to pay for goods in a cart, then youcan 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.

return This is the URL where user will be redirected after the payment issuccessfully performed. If this parameter is not passed, the buyer remainson the PayPal site.

rm

This parameter determines the way information about successfultransaction will be passed to the script that is specified in the returnparameter. "1" means that no parameters will be passed. "2" means thatthe POST method will be used. "0" means that the GET method will be

used. The parameter is "0" by default.

cancel_return This is the URL where the user will be redirected when he cancels thepayment. If the parameter is not passed, the buyer remains on the PayPalsite.

notify_url

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

custom This field does not take part in the shopping process, it will be simplypassed to IPN script at the time of transaction confirmation.

invoice This parameter is used to pass the invoice number. The parameter is notobligatory, but being passed it must be unique for every transaction.

amount This parameter represents an amount of payment. If the parameter is notpassed, the user will be allowed to enter the amount (this is used fordonations).

currency_code This 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 fulllist 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 paymentsprocessing. The essence of the technology lies in a special script created on the seller'sserver. When an event happens related to the seller's account -- for example, a paymenttransfer, payment cancel, subscription creation or cancel, etc. -- the PayPal server sends

Page 4: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 4/20

a POST request with transaction information to the IPN script. The script in its turn, sends arequest to the PayPal server to verify the transaction.

So, the buyer has performed a payment. After a delay of up to several seconds, the PayPalserver sends the request to the IPN script that is specified in the account settings or passedin the notify_url parameter. A good IPN script is the key to payments security. If youhave ever heard that the sellers who use PayPal are victims of somebody's cheating, thenbe 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 thesepurposes, the script generates a POST request to either here or here . It passes all of thevariables it receives, without any changes, together with the cmd parameter havingthe _notify-validate value. As a response to the request, the script receiveseither 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 theform for the payment to be sent to his account. The payment recipient is determined bythe business and receiver_email variables. Two variables are necessary because PayPalallows several e-mails to be registered for one account. The e-mail that is specified duringaccount 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 inthe business parameter. If business and/or receiver_email do not contain anexpected value, then the script immediately terminates.

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

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

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

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

Page 5: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 5/20

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

The received POST variables contain transaction information. The most widely usedvariables 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 paymentsperformed 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 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 istransferred to seller's account. If txn_type = reversal , then themoney is returned to buyer's account.Pending - payment was delayed. The delay reason is determined inthe pending_reason variable. After the payment is complete, PayPalwill send another notification.Failed - payment failed. This state is possible only when the paymentwas performed from a bank account.Denied - seller cancelled the payment. The payment is in this statewhen the seller cancels the payment having the Pending state before.

Refunded - money is returned to the buyer. The payment is in thisstate when the seller cancels the payment having the Completed statebefore.

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 isspecified in settings of seller's account. The payment will be completedwhen the seller confirms the transaction.

Page 6: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 6/20

Parameter Description

intl - seller is not a USA dweller. The payment will be completed whenthe seller confirms the transaction.verify - seller's account is in the unverified state. The payment willbe completed when the seller is identified.

address - settings of a seller's account require the buyer to specify thedelivery address, but the buyer does not specify the address. Thepayment will be completed after seller confirms the transaction.upgrade - the payment was performed using a credit card and theseller's account has 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 moreabout 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 bankaccount or money from the buyer's PayPal account.

mc_gross Payment amount.

mc_fee Commission charges. The amount that is put on the seller's account isdetermined 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

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

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

Page 7: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 7/20

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 thecode can easily adjust and test the created online shop. As for real applications, databasesshould be better used to store information about goods, carts, payment requests andresponses 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 thefunctionality allowing new items to be added to the merchandise catalogue. Informationabout 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 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 intothe order table of DB. In order to simplify the process and to let you easily track thepayment 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 beaccessed only by their users. The given example does not use registration, so it does notcontrol the access of different users to carts. This process is simplified since the user needsonly to select his cart identifier.

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

Collapse | Copy Code

Page 8: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 8/20

<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 paymentdetails from the table of payment details. To simplify the code, we did not use this.

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

Collapse | Copy Code

<Responses > <Response payment_id ="0"

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 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

Page 9: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 9/20

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 validatethe 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"

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 accountshould 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

Page 10: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 10/20

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

When request_id is passed in the custom field, it allows the IPN script to restoreinformation 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 apayment report and thank the buyer for the purchase. As for the given example, use thecode of IPN processing in the payment_success.aspx.cs or payment_success.aspx.vb fileonly for testing, since real products should validate payments in the IPN script specified inthe notify_url parameter for the purposes of security.The payment_success.aspx.cs or payment_success.aspx.vb code was specially written tomake the testing process give as much information as possible. The code contains messagesthat are important only on the testing stage. This information is written into a log file. Thefile 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 usuallycreate a special page where information about errors is sent. Then the information isformatted 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 thegiven 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 resultof the verification to be shown to the user. However, the verification does not provide a100% 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 afterthe check is processed in a bank that also does not provide a guarantee that the money isput 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 theform should be encrypted before it is sent in order to avoid forgery of the paymentinformation. That means that so-called Encrypted Website Payments should be used. If youare not going to use Encrypted Website Payments (EWP) validation, you must check theprice, transaction ID, PayPal receiver email address and other data sent to you by IPN toensure that they are correct. By examining the data, you can be sure that you are not beingspoofed.

KB_Soft Group uses both EWP and validation of the parameters received from PayPal in itsprojects. 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 itwork on any PayPal account, we use only IPN. This is because if we use EWP we have tocreate private and public keys and upload the created public key to our account on thePayPal server. Then we would need to use the obtained identifier of certificate to encryptthe form of the request. Besides, to use EWP we need to download a public key of thePayPal system itself. This article is not aimed at describing in detail the principles of workwith 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 detailedinformation in the archives associated with the source code attached to this article.

Page 11: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 11/20

C#

Collapse | Copy Code

private void Page_Load( object sender, EventArgs e){

string requestUriString;

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);

}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;

// Write the request back IPN strings StreamWriter writer =

new StreamWriter(request.GetRequestStream(), Encoding.ASCII);writer.Write(RuntimeHelpers.GetObjectValue(obj2));writer.Close();

Page 12: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 12/20

//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 {

// 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 = " , ";info2.NumberGroupSizes = new int[] { 3 };

// if the request is verifiedif (String.Compare(IPNResponse, " VERIFIED ", false) == 0){

// check the receiver's e-mail (login is user's// identifier in PayPal)// and the transaction typeif ((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.

Page 13: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 13/20

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," 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 identifierif (this.IsDuplicateID(this.Request[" txn_id "])){

// 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// 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

Page 14: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 14/20

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);

reader.Close();response.Close();return;

}try{

// write a response from PayPalthis.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// 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(

Page 15: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 15/20

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

}reader.Close();response.Close();

}

Visual Basic

Collapse | Copy Code

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

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 16: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 16/20

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.GetResponseStreamDim 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 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 ExceptionKBSoft.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(

"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 (

Page 17: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 17/20

receiver_email or txn_type)" )KBSoft.Carts.WriteFile("Error in IPNHandler: INVALID payment's parameters" +" (receiver_email or txn_type)" )

Catch ex As ExceptionKBSoft.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 ' 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 ' 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), _

Page 18: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 18/20

Page 19: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 19/20

the registered site on which the seller's site is hosted. While testing, you may simplyspecify localhost instead of YOUR_IP . It should be noted that IPN will function only if youcorrectly specify the global IP address or the name of a registered domain. If youspecify localhost , then only the script specified in the ReturnUrl parameter will be ableto support interaction with PayPal. The script specified in the NotifyUrl parameter willnot. 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 virtualdirectory or site, you need to specify its name instead of "paypal." To check whetheryour NotifyUrl is valid, enter its address into "Notification URL:" filed at Profile->InstantPayment Notification Preferences->Edit in your PayPal Business or Premier account. Checkthe checkbox on this page and click the "Save" button. If the URL is valid, a message aboutsuccessful validation will be shown.

The CurrencyCode parameter is used to specify the code of the currency that is used forpayment. The UseSandbox parameter is used to switch between PayPal SandBox and realPayPal accounts. The SendToReturnURL parameter is used to turn on/off notificationssending to return_url . SendToReturnURL is recommended to be set to true only for thepurposes of testing.

Use of the Source Code

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

To use the code supplied with the article, you need to have .NET Framework 2.0 or higherinstalled on your system. You also need to have a real or SandBox PayPal account. Noadditional 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 Americanbank. Make sure that the standard WebClient service is running on your system. If you haveVisual Studio 2005, you can run tests by opening the paypal.sln solution and executing thecode. IPN will not be available in this case. An alternative option is the creation of a virtualdirectory 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 receivethe VERIFIED response from PayPal. Information about processed transactions

should be kept. So, when the VERIFIED response is received, you can make surethat 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. Youshould always check if payment_status=completed . The single exception is aseller whose account is not American and pending_reason=intl .

Page 20: Use of the PayPal Payment System in AspDotNet (1)

8/4/2019 Use of the PayPal Payment System in AspDotNet (1)

http://slidepdf.com/reader/full/use-of-the-paypal-payment-system-in-aspdotnet-1 20/20

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