June 14, 2013

Paypal Integration With Asp.Net using Website Payment Method

Nowadays PayPal is the most popular payment gateway worldwide because it is totally free to integrate and PayPal does not charge anything for opening an account, you will pay PayPal when you get paid. And the amount is also lower than other payment gateways.

How to integrate with PayPal in Asp.net?, is common question ask by different developers around the world. When you visit official website of PayPal for help, no doubt they (PayPal) are trying to help visitors to learn techniques and  method to integrate it with their application but for newly person who haven't experience with integration unable to understand the way of success.

There are four methods to integrate PayPal like:
  • 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
But newly person's first choice is "PayPal API" for integration which is wrong. It seems quite easy with other version but after integration when you test  your application using Sandbox test account, it show you version errors and the most common error is display like "Total Order is missing", in fact you already pass total order amount in session as per of description. 

If you are new to PayPal, first learn all of the options that you have with the Website Payments Standard. Then, if you need to add some basic post-payment processing, use Auto-Return or PDT. If not solve your issue then IPN is a more robust option you have.

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 (called Website Payments Pro).

The last item from classification is Payflow Gateway, a different beast. It is a solution aimed specifically at those businesses that have/want an Internet Merchant Account (IMA) and just need the payment gateway. 

Lets start PayPal integration with Asp.net application using Website Payment Method. First follow to set up a new Test account as there are two reasons to test your application before live your application. 
  • 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 on-line. 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. 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 on-line business. This type of account has all of the integration options. 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:

  • Signing up for a Sandbox account

  • After setting up test account, let's start website payment method (HTML)
ParameterDescription
cmdThe parameter is obligatory. It must have the _xclick value for an unencrypted request.
businessThe 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_nameThis is a name of the item that will be shown to the user.
no_shippingPrompt 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.
rmThis 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.
invoiceThis parameter is used to pass the invoice number. The parameter is not obligatory, but 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.

There are two type of integration techniques under Website Payment Method.
  • Passing the Aggregate Cart Amount to PayPal
  • Passing Individual Items to PayPal

A. Passing the Aggregate Cart Amount to PayPal

You may aggregate your entire shopping cart and pass the total amount into PayPal's Buy Now Button code (that is, you will need to post a single name for the entire cart and the total price of the cart's contents as though it were a purchase of a single item).

One drawback of this method is that your buyers will not be able to see the individual items appearing in their carts. In addition, you cannot change PayPal variable names, nor can you add your own variable names.

The code for your PayPal post requires the following 4 hidden variables and an image as the form submit:

Required Variables
NameValue
businessEmail address on your PayPal account
item_nameName of the item (or a name for the shopping cart)
currency_codeDefines the currency in which the monetary variables (amount, shipping, shipping2, handling, tax) are denoted. Possible values are "USD", "EUR", "GBP", "CAD", "JPY".
amountPrice of the item (the total price of all items in the shopping cart)
imageThe image for the button your buyer will press to initiate the PayPal payment process. You can substitute your own image by replacing the src with the URL of your image

This means that the minimum required code for your post to PayPal will look like this:

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="you@youremail.com">
<input type="hidden" name="item_name" value="Item Name">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="amount" value="0.00">
<input type="image" src="http://www.paypal.com/en_US/i/btn/x-click-but01.gif" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>

PayPal offers additional variables to customize your form post. All of the available variables are listed below (variable names must be in lower case):

Available Variables
NameValue
businessEmail address on your PayPal account
quantityNumber of items. This will multiply the amount if greater than one
item_nameName of the item (or a name for the shopping cart). Must be alpha-numeric, with a 127character limit
item_numberOptional pass-through variable for you to track payments. Must be alpha-numeric, with a 127 character limit
amountPrice of the item (the total price of all items in the shopping cart)
shippingThe cost of shipping the item
shipping2The cost of shipping each additional item
handlingThe cost of handling
taxTransaction-based tax value. If present, the value passed here will override any profile tax settings you may have (regardless of the buyer's location).
no_shippingShipping address. If set to "1," your customer will not be asked for a shipping address. This is optional; if omitted or set to "0," your customer will be prompted to include a shipping address
cnOptional label that will appear above the note field (maximum 40 characters)
no_noteIncluding a note with payment. If set to "1," your customer will not be prompted to include a note. This is optional; if omitted or set to "0," your customer will be prompted to include a note.
on0First option field name. 64 character limit
os0First set of option value(s). 200 character limit. "on0" must be defined for "os0" to be recognized.
on1Second option field name. 64 character limit
os1Second set of option value(s). 200 character limit. "on1" must be defined for "os1" to be recognized.
customOptional pass-through variable that will never be presented to your customer. Can be used to track inventory
invoiceOptional pass-through variable that will never be presented to your customer. Can be used to track invoice numbers
notify_urlOnly used with IPN. An internet URL where IPN form posts will be sent
returnAn internet URL where your customer will be returned after completing payment
cancel_returnAn internet URL where your customer will be returned after cancelling payment
image_urlThe internet URL of the 150 X 50 pixel image you would like to use as your logo
csSets the background color of your payment pages. If set to "1," the background color will be black. This is optional; if omitted or set to "0," the background color will be white

PayPal allows you to post extended variables if you change this "cmd" input:

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

To

<input type="hidden" name="cmd" value="_ext-enter">
<input type="hidden" name="redirect_cmd" value="_xclick">

By making the above change to the "cmd" input, you can also use the variables below:

Extended Variables
NameValue
emailCustomer's email address
first_nameCustomer's first name. Must be alpha-numeric, with a 32 character limit
last_nameCustomer's last name. Must be alpha-numeric, with a 64 character limit
address1First line of customer's address. Must be alpha-numeric, with a 100 character limit
address2Second line of customer's address. Must be alpha-numeric, with a 100 character limit
cityCity of customer's address. Must be alpha-numeric, with a 100 character limit
stateState of customer's address. Must be official 2 letter abbreviation
zipZip code of customer's address
night_phone_aArea code of customer's night telephone number
night_phone_bFirst three digits of customer's night telephone number
day_phone_aArea code of customer's daytime telephone number
day_phone_bFirst three digits of customer's daytime telephone number

Note: To specify shipping & handling amounts that differ from the default shipping amounts set in your Profile, please go to your Profile, edit your Shipping Calculations, and click the "allow transaction-based shipping override" checkbox.

B. Passing Individual Items to PayPal

If your custom or third party shopping cart can be configured to pass individual items to PayPal, information about the items will be included in the buyers' and sellers' History logs and notifications. To include information about the items, you will post HTML form elements to a new version of PayPal's Shopping Cart flow. This process is much like the one described in Section #1 "Passing Aggregate Cart Amount to PayPal" with the following exceptions:
  • Set the "cmd" variable to "_cart" 
    • <input type="hidden" name="cmd" value="_xclick"> 
    • (Replace above required HTML line with below line)
    • <input type="hidden" name="cmd" value="_cart">
  • Add a new variable called "upload"
    • <input type="hidden" name="upload" value="1">
  • Define item details
For each of the following item-specific parameters, define a new set of values that correspond to each item that was purchased via your custom cart. Append "_x" to the variable name, where x is the item number, starting with 1 and increasing by one for each item that is added.

NameValue
item_name_x(Required for item #x) Name of item #x in the cart. Must be alpha-numeric, with a 127 character limit
item_number_xOptional pass-through variable associated with item #x in the cart. Must be alpha-numeric, with a 127 character limit
amount_x(Required for item #x) Price of the item #x
shipping_xThe cost of shipping the first piece (quantity of 1) of item #x
shipping2_xThe cost of shipping each additional piece (quantity of 2 or above) of item #x
handling_xThe cost of handling for item #x
on0_xFirst option field name for item #x. 64 character limit
os0_xFirst set of option value(s) for item #x. 200 character limit. "on0_x" must be defined in order for "os0_x" to be recognized.
on1_xSecond option field name for item #x. 64 character limit
os1_xSecond set of option value(s) for item #x. 200 character limit. "on1_x" must be defined in order for "os1_x" to be recognized.

  • Repeat for each item included in cart
Include a set of required variables and any optional variables from the table above for each item included in your buyers' cart. The first item included in the cart should be defined with parameters ending in "_1", such as "item_name_1", "amount_1", etc. Similarly the second item should be denoted with variables like "item_name_2", "amount_2", etc. 


Note: the "_x" values must increment by one continuously in order to be recognized. If you skip from item #1 to item #3 without defining an item #2, the third item will be ignored.


To Specify Currency: All monetary variables (amount, shipping, shipping2, handling, tax) will be interpreted in the currency designated by the "currency_code" variable that is posted with the payment. Since it is not item-specific, there is no need to append a "_x" to the variable name. If no "currency_code" variable is posted, we will assume that all monetary values are in U.S. Dollars.

IPN Verfication

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. 

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.

There following points that need to be check during IPN.
  • When buyer has performed a payment. After a some delay, 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. 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.
IPN for the same transaction can be sent more than once. 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. This will cause dure to failure of script to connect 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.
The most widely used variables are the following:


ParameterDescription
txn_idUnique transaction number.
payment_datePayment date in the "18:30:30 Jan 1, 2000 PST" format .
payer_emailBuyer's e-mail.
businessSeller's e-mail.
payer_idUnique 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 identification.
item_numberItem identifier.
item_nameItem name.
txn_typeTransaction 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_statusPayment 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 thepending_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_reasonReason of payment delay. Possible values are:
echeck - payment was performed with an e-check
multi_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 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_typePayment 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_grossPayment amount.
mc_feeCommission charges. The amount that is put on the seller's account is determined as mc_gross – mc_fee.
mc_currencyPayment currency.
first_nameBuyer's name.
last_nameBuyer's last name.
address_streetStreet.
address_cityCity.
address_stateState/region.
address_zipZip Code.
address_countryCountry.
verify_signDigital signature. It is used in PayPal for transaction verification.

Points To Remember

  • 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.
Hope you understand it completely. Let me know if you stuck some where in the middle or visit PayPal Developer Community. Stay tune!