User ID:
Password:
Remember Me:
Forgot Password?
Not a member?
Click here for more information and to register.

    Using the PayPal Payment System in ASP.NET



    An Example of IPN Processing

    Following is an example of a script that uses the PayPal IPN. I 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 a 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. I chose this way of information storage only for reasons of compatibility and so that any user could download the code and easily adjust and test the created online shop. For real applications, databases should be used to store information about goods, carts, payment requests, and responses to them.

    To store information about goods, use the Goods.xml file. It should have the following structure:

    <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, I did not provide the created online shop with the functionality of allowing new items to be added to the merchandise catalogue. But, information about new items can be added manually into the XML file if needed.

    To store information about carts, I use the Carts.xml file that has the following structure:

    <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

    For real online shops, information about paid carts is not stored there, but is written into the order table of the DB. But, to simplify the process and to let you easily track the payment results, I did not implement this capability in the given code. Besides, real online shops should register users 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 access of different users to carts. This process is simplified because the user needs only to select his cart identifier.

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

    <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. But to simplify the code, I did not use this.

    To store information about responses to payment requests, I use the PaymentResponses.xml file that has the following structure:

    <Responses>
       <Response   payment_id="0"
                   txn_id="3PP58082BD3079037"
                   payment_date="5/28/2007 1:22:40 PM"
                   payment_price="10.99"
                   email= my@email.com 
                   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 a 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
    • request_id is an identifier of the payment request
    • is_success indicates whether the payment was successfully performed
    • reason_fault is a possible reason of payment failure

    If you use XML files to store information, you should use the XML schema to validate the information, but I did not perform validation to simplify the example.

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

    <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 the 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 (what the buyer pays for) that will be shown to the 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 the buyer will be redirected to when payment is successfully performed
    • rm is a parameter that determines the way 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 the transaction (IPN) to
    • cancel_url is the URL 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 in the PayPal.aspx.vb) file of the source code attached to the article. Refer to Table 1 for a more detailed description of the form's fields.

    When the 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. But, if he performs the payment, he is redirected to return_url and, in this case, you 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 in payment_success.aspx.vb) file only for testing because real products should validate payments in the IPN script specified in the notify_url parameter for security purposes. The payment_success.aspx.cs (or 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 at 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 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 either. Real sites usually create a special page where information about the error 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 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, 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's sent 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 e-mail 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.

    About the Author

    Anton Zlobin is a .NET developer at KB_Soft Group, an offshore software development company located in Russia, Novosibirsk. Here he has worked on various .NET projects. He has a Master Degree in Computer Technology from Novosibirsk State Technical University.

    Downloads

  • Use_of_the_PayPal_VB_NET_src.zip

  • IT Offers


    Top Authors