stymiee

Handling Online Payments Part 1 - Basic Information and Our Form

by All Star ‎01-05-2011 06:47 AM - edited ‎10-20-2011 10:00 AM (17,277 Views)

Accepting payment through a website is easily the most common reason why developers are reading this blog and visiting the Authorize.Net developer center. Doing so through a web form is not as easy as it seems and most implementations lack some, if not many, of the basic usability, accessibility, and security features a payment form should have. To help eliminate these shortcomings in your next payment form I am going to walk through the basics, and not-so-basics, of a good payment form in this multiple part blog series. Although the coding examples will be in PHP the concepts can be applied in any programming language.

 

Part I - Capturing Basic Information

 

In the first article of this series we are going to start with the basic structure of our form. We'll cover what information we want to capture and why we need to capture it.

 

What Do We Want To Capture? And Why Should We Capture It?

 

There are four basic pieces of information we will want to capture when accepting a payment online. They are:

 

  • Billing address

    The billing address is the address the customer has associated with the credit card they will be making payment with. This address is the same address the credit card statement is mailed to each month. This will comprise of two lines for the street address, city, state, and zip code. We will also include a field each for the first and last name. We will want this as two separate fields as many users will leave out their first or last name if not forced to provide it. I have seen orders come in to websites with only one "name" field containing data like, "The Smith Family" and "Bob, Mary, Johnny, and Stacey".

     

    We need to capture this information as it is used to perform Address Verification (AVS).

     

  • Shipping address

    This is the address the customer wishes to have their order shipped to. It may or may not be the same as the billing address. This is important to collect as many customers wish to have their orders sent to a different address then their billing address for a variety of reasons including:

     

    • No one is at the billing address during normal delivery hours
    • The billing address is Post Office Box
    • It is a gift and being sent to the gift recipient

     

  • Credit card information

    This encompasses the credit card number, expiration date, and CVV number for the credit card the customer is making their payment with.

     

  • Contact Information

    If we need to contact the customer for any reason how will we do it? We will capture their email address and telephone number as these are the two quickest and easiest ways to contact a customer.

     

 

The HTML

 

Now that we know what information we will want to capture we can properly construct our web form. We'll use HTML 4.01 strict since xHTML is no longer the direction the web is taking and HTML 5 is still being fleshed out (not to mention support is still lacking in most web browsers as of the writing of this post).

 

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
        <head>
            <title>Payment Form</title>
            <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
            <meta http-equiv="Content-Language" content="en-us">
        </head>
        <body>
            <form action="/payment-form.php" method="post">
                <p>
                    <label for="credit_card">Credit Card Number</label>
                    <input type="text" name="credit_card" id="credit_card" autocomplete="off" maxlength="19" value="">
                </p>
                <p>
                    <label for="expiration_month">Expiration Date</label>
                    <select name="expiration_month" id="expiration_month">
                        <option value="0"> </option>
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                        <option value="4">4</option>
                        <option value="5">5</option>
                        <option value="6">6</option>
                        <option value="7">7</option>
                        <option value="8">8</option>
                        <option value="9">9</option>
                        <option value="10">10</option>
                        <option value="11">11</option>
                        <option value="12">12</option>
                    </select>
                    <select name="expiration_year" id="expiration_year">
                        <option value="0"> </option>
                        <option value="2010">2010</option>
                        <option value="2011">2011</option>
                        <option value="2012">2012</option>
                        <option value="2013">2013</option>
                        <option value="2014">2014</option>
                        <option value="2015">2015</option>
                        <option value="2016">2016</option>
                        <option value="2017">2017</option>
                        <option value="2018">2018</option>
                        <option value="2019">2019</option>
                        <option value="2020">2020</option>
                        <option value="2021">2021</option>
                    </select>
                </p>
                <p>
                    <label for="cvv">Security Code</label>
                    <input type="text" name="cvv" id="cvv" autocomplete="off" value="" maxlength="4">
                </p>
                <p>
                    <label for="cardholder_first_name">Cardholder's First Name</label>
                    <input type="text" name="cardholder_first_name" id="cardholder_first_name" maxlength="30" value="">
                </p>
                <p>
                    <label for="cardholder_last_name">Cardholder's Last Name</label>
                    <input type="text" name="cardholder_last_name" id="cardholder_last_name" maxlength="30" value="">
                </p>
                <p>
                    <label for="billing_address">Billing Address</label>
                    <input type="text" name="billing_address" id="billing_address" maxlength="45" value="">
                </p>
                <p>
                    <label for="billing_address2">Suite/Apt #</label>
                    <input type="text" name="billing_address2" id="billing_address2" maxlength="45" value="">
                </p>
                <p>
                    <label for="billing_city">City</label>
                    <input type="text" name="billing_city" id="billing_city" maxlength="25" value="">
                </p>
                <p>
                    <label for="billing_state">State</label>
                    <select id="billing_state" name="billing_state">
                        <option value="0"> </option>
                        <option value="AL">Alabama</option>
                        <option value="AK">Alaska</option>
                        <option value="AZ">Arizona</option>
                        <option value="AR">Arkansas</option>
                        <option value="CA">California</option>
                        <option value="CO">Colorado</option>
                        <option value="CT">Connecticut</option>
                        <option value="DE">Delaware</option>
                        <option value="DC">District Of Columbia</option>
                        <option value="FL">Florida</option>
                        <option value="GA">Georgia</option>
                        <option value="HI">Hawaii</option>
                        <option value="ID">Idaho</option>
                        <option value="IL">Illinois</option>
                        <option value="IN">Indiana</option>
                        <option value="IA">Iowa</option>
                        <option value="KS">Kansas</option>
                        <option value="KY">Kentucky</option>
                        <option value="LA">Louisiana</option>
                        <option value="ME">Maine</option>
                        <option value="MD">Maryland</option>
                        <option value="MA">Massachusetts</option>
                        <option value="MI">Michigan</option>
                        <option value="MN">Minnesota</option>
                        <option value="MS">Mississippi</option>
                        <option value="MO">Missouri</option>
                        <option value="MT">Montana</option>
                        <option value="NE">Nebraska</option>
                        <option value="NV">Nevada</option>
                        <option value="NH">New Hampshire</option>
                        <option value="NJ">New Jersey</option>
                        <option value="NM">New Mexico</option>
                        <option value="NY">New York</option>
                        <option value="NC">North Carolina</option>
                        <option value="ND">North Dakota</option>
                        <option value="OH">Ohio</option>
                        <option value="OK">Oklahoma</option>
                        <option value="OR">Oregon</option>
                        <option value="PA">Pennsylvania</option>
                        <option value="RI">Rhode Island</option>
                        <option value="SC">South Carolina</option>
                        <option value="SD">South Dakota</option>
                        <option value="TN">Tennessee</option>
                        <option value="TX">Texas</option>
                        <option value="UT">Utah</option>
                        <option value="VT">Vermont</option>
                        <option value="VA">Virginia</option>
                        <option value="WA">Washington</option>
                        <option value="WV">West Virginia</option>
                        <option value="WI">Wisconsin</option>
                        <option value="WY">Wyoming</option>
                    </select>
                </p>
                <p>
                    <label for="billing_zip">Zip Code</label>
                    <input type="text" name="billing_zip" id="billing_zip" maxlength="5" value="">
                </p>
                <p>
                    <label for="telephone">Telephone Number</label>
                    <input type="text" name="telephone" id="telephone" maxlength="20" value="">
                </p>
                <p>
                    <label for="email">Email Address</label>
                    <input type="text" name="email" id="email" maxlength="20" value="">
                </p>
                <p>
                    <label for="recipient_first_name">Recipient's First Name</label>
                    <input type="text" name="recipient_first_name" id="recipient_first_name" maxlength="30" value="">
                </p>
                <p>
                    <label for="recipient_last_name">Recipient's Last Name</label>
                    <input type="text" name="recipient_last_name" id="recipient_last_name" maxlength="30" value="">
                </p>
                <p>
                    <label for="shipping_address">Shipping Address</label>
                    <input type="text" name="shipping_address" id="shipping_address" maxlength="45" value="">
                </p>
                <p>
                    <label for="shipping_address2">Suite/Apt #</label>
                    <input type="text" name="shipping_address2" id="shipping_address2" maxlength="45" value="">
                </p>
                <p>
                    <label for="shipping_city">City</label>
                    <input type="text" name="shipping_city" id="shipping_city" maxlength="30" value="">
                </p>
                <p>
                    <label for="shipping_state">State</label>
                    <select id="shipping_state" name="shipping_state">
                        <option value="0"> </option>
                        <option value="AL">Alabama</option>
                        <option value="AK">Alaska</option>
                        <option value="AZ">Arizona</option>
                        <option value="AR">Arkansas</option>
                        <option value="CA">California</option>
                        <option value="CO">Colorado</option>
                        <option value="CT">Connecticut</option>
                        <option value="DE">Delaware</option>
                        <option value="DC">District Of Columbia</option>
                        <option value="FL">Florida</option>
                        <option value="GA">Georgia</option>
                        <option value="HI">Hawaii</option>
                        <option value="ID">Idaho</option>
                        <option value="IL">Illinois</option>
                        <option value="IN">Indiana</option>
                        <option value="IA">Iowa</option>
                        <option value="KS">Kansas</option>
                        <option value="KY">Kentucky</option>
                        <option value="LA">Louisiana</option>
                        <option value="ME">Maine</option>
                        <option value="MD">Maryland</option>
                        <option value="MA">Massachusetts</option>
                        <option value="MI">Michigan</option>
                        <option value="MN">Minnesota</option>
                        <option value="MS">Mississippi</option>
                        <option value="MO">Missouri</option>
                        <option value="MT">Montana</option>
                        <option value="NE">Nebraska</option>
                        <option value="NV">Nevada</option>
                        <option value="NH">New Hampshire</option>
                        <option value="NJ">New Jersey</option>
                        <option value="NM">New Mexico</option>
                        <option value="NY">New York</option>
                        <option value="NC">North Carolina</option>
                        <option value="ND">North Dakota</option>
                        <option value="OH">Ohio</option>
                        <option value="OK">Oklahoma</option>
                        <option value="OR">Oregon</option>
                        <option value="PA">Pennsylvania</option>
                        <option value="RI">Rhode Island</option>
                        <option value="SC">South Carolina</option>
                        <option value="SD">South Dakota</option>
                        <option value="TN">Tennessee</option>
                        <option value="TX">Texas</option>
                        <option value="UT">Utah</option>
                        <option value="VT">Vermont</option>
                        <option value="VA">Virginia</option>
                        <option value="WA">Washington</option>
                        <option value="WV">West Virginia</option>
                        <option value="WI">Wisconsin</option>
                        <option value="WY">Wyoming</option>
                    </select>
                </p>
                <p>
                    <label for="shipping_zip">Zip Code</label>
                    <input type="text" name="shipping_zip" id="shipping_zip" maxlength="5" value="">
                </p>
                <p>
                    <input type="submit" value="Checkout">
                </p>
            </form>
        </body>
    </html>

 

Let's look at some basic points about this form:

 

  • The form action is POST

    We want to use POST as opposed to GET as GET places the submitted form values in the URL which is seen in the browser address bar. Not only does this make that information susceptible to snooping but it allows it to be saved in a browser's history which can be searched through at a later time by another user of that computer.

     

  • We use MAXLENGTH

    The MAXLENGTH attribute of the INPUT tag allows us to limit the amount of characters a customer may enter into a form field. Typically this value is equal to the length specified in the database field in which this information will be stored. By having this value set we help to prevent the user from submitting too much information and forcing them to correct it only after they submit the form which is inconvenient.

     

  • We use LABELs

    The LABEL tag defines a label for an INPUT element. The LABEL tag does not render as anything special for the user. However, it provides a usability improvement for mouse users, because if the user clicks on the text within the label element, it toggles the form element for which it is associated with.

 

This basic form will capture the four basic pieces of information we will need to handle our orders. Your web application may have additional pieces of information you wish to capture. Naturally you can modify this form to accept them. Additionally, sometimes there is no product to be shipped, like when a donation is being made. In those cases the shipping address can be removed.

 

The Next Step

 

Now that we know what information we will want to capture, and we have our web page and form constructed, we will focus on receiving the submitted information. Sure, that sounds easy enough. Yet many developers fail to do this simple task well. Our next post will show how this is done using best practices.

 

The Handling Online Payments Series

 

  1. Part 1 - Basic Information and Our Form
  2. Part 2 - Reading In And Sanitizing Submitted Data
  3. Part 3 - Data Validation
  4. Part 4 - Handling Validation Errors
  5. Part 5 - Processing Payment and Handling the Response
  6. Part 6 - Preventing Duplicate Submissions with POST/REDIRECT/GET
  7. Part 7 - Preventing Automated Form Submissions
  8. Part 8 - Using JavaScript To Increase Usability
  9. Part 9 - HTML and CSS Enhancements
  10. Part 10 - A Little Bit More PHP
---------------------------------------------------------------------------------------------------


John Conde is a certified Authorize.Net developer

Comments
by pdhinoja on ‎04-06-2011 07:54 AM

HI,

 

I am not sure whether it is right place to post my query but I could not find more appropriate place for it. 

 

We are product development company and we act as third party solution where our product is used my many

customers across the globe behind the scene. The business mode is :

 

1. End User uses one of our customer website and lets say book an service our customer offers.

 2. that request will be routed to our product and rest of the processing is done through our product but end-user always 

feels that it is dealing with our customers not with us.

 

Now we need to integrate Payment gateway to perform card-not present transactions for behalf of our customers. 

we have gone through with the information provided but we are but confused and need assistance.

 

1. which solution we can use from Authorize.net in this kind of business model where our product is integrated

with payment gateway but we are making card-not present transaction for our clients?

 

2. do each of our client need to have merchant account and how we can tell cybersource about it?

 

Some guidelines on this will be appreciated.

 

 

 

by All Star on ‎04-06-2011 10:36 AM

pdhinoja,

 

This question is better asked in the developer forums.

by drymetal ‎04-27-2011 09:26 PM - edited ‎04-27-2011 09:30 PM

Thanks for the great tutorial series!

by larry85704 on ‎05-10-2011 10:10 AM

Where does ./config.php come from? I downloaded the PHP SDK, anet_php_sdk-1.1.3 on 2-4-2011.

There is no config.php.

 

Sorry if I am being stupid here, but I have a web site that works great to test accounts but does not

work to a production account. So I am trying to be very careful about what I do.

by larry85704 on ‎05-10-2011 10:14 AM

Hello again. In your sample code, downloaded as part of your php_aim download, your sample.php files does not include

a config.php. Do you claim that this sample.php works? How can it work without config.php, which I cannot seem to find?

by All Star on ‎05-11-2011 05:59 PM

@larry85704, It is in the PHP SDK root directory. As soon as you unzip the file you should see it. If you don't then you should download a new copy of the SDK as I have verified it is present ion there.

by larry85704 on ‎05-12-2011 03:32 PM

Ok, I am probably the dumbest person you have every helped, so look at this as a challange.

 

First, I use Ubuntu, version 10.10, if that matters.

 

Second, at  http://developer.authorize.net/downloads/ I downloaded anet_php_sdk-1.1.5.zip. I then extract the files and

have no config.php. So, since I remembered the find command I went looking for config.php. Found it. Is this it?

 

<?php
/**
 * This file contains config info for the sample app.
 */

// Adjust this to point to the Authorize.Net PHP SDK
require_once 'anet_php_sdk/AuthorizeNet.php';


$METHOD_TO_USE = "AIM";
// $METHOD_TO_USE = "DIRECT_POST";         // Uncomment this line to test DPM


define("AUTHORIZENET_API_LOGIN_ID","8au8RrB8k");    // Add your API LOGIN ID
define("AUTHORIZENET_TRANSACTION_KEY","3zP278q35Pa8fPY8"); // Add your API transaction key
define("AUTHORIZENET_SANDBOX",true);       // Set to false to test against production
define("TEST_REQUEST", "FALSE");           // You may want to set to true if testing against production


// You only need to adjust the two variables below if testing DPM
define("AUTHORIZENET_MD5_SETTING","");                // Add your MD5 Setting.
$site_root = "http://YOURDOMAIN/samples/your_store/"; // Add the URL to your site


if (AUTHORIZENET_API_LOGIN_ID == "") {
    die('Enter your merchant credentials in config.php before running the sample app.');
}

 

It was in a place where it wasn't being found. So I fixed that. Now I get directed to a thank you

page, so I guess your demo is working on my system.

 

I have to figure out how to get credit card transactions to work reliably. I currently have my shopping card running

reliably in test mode and to the test server. I get failure when running to the production site once in awhile. So, thank

you very much for this tutorial.

 

Does Authorize.Net have people that I can hire to fix this for me? Like I said, I have the site up and running very well

in test mode, I just get errors in production mode. Hopefully, by the time I get done with your example code I'll have figured it out.

 

Thanks for your help.

 

Larry.

by All Star on ‎05-12-2011 07:25 PM

That is the config file so you definitely found it. I'm glad you are able to get it working. If you need to hire someone check out the certified developer directory. If you have specific questions try asking them in the community forums. Somebody there may be able to help you.

About the Author
  • Authorize.Net Developer Community Manager
Announcements
Labels