stymiee

Handling Online Payments Part 5 - Processing Payment and Handling the Response

by All Star ‎03-01-2011 10:46 AM - edited ‎10-20-2011 09:58 AM (16,302 Views)

This is part five of a multi-part series on handling online payments.

 

In Part 1 of this series we identified our goals (creating a payment form that was usable, accessible, and secure) and began by creating the form we will use to capture payment information. In Part 2 of this series we continued this process by exploring how we will handle the data submitted by that form. In Part 3 of this series we took the data received and sanitized in Part 2 and validated that it was in a format we required. In Part 4 of this series we took the errors we found in Part 3 and displayed them in a user-friendly format to minimize cart abandonment. In this installment we will process the payment using the PHP SDK and handle the response in an appropriate manner.

 

Picking Up Where We Left Off

 

In part 4 of this series we helped our users who submitted erroneous information to find where they made an error and correct it. Once a user has submitted their payment without any errors it is time to process their payment. When a payment is submitted there are three potential scenarios that can occur:

 

  1. The payment is approved
  2. The payment is declined
  3. An error occurs somewhere during the payment process

 

Each of these three scenarios require us to deliver custom responses to our users. How we handle the information submitted to us also will vary depending on your business needs. Let's look at how you might want to handle each of these scenarios one at a time.

 

  1. The Payment Is Approved

     

    Once the payment is approved we do not need anything else from our user. At this point we just want to complete the transaction and hand it off to whoever will be doing order fulfillment.

     

    Our responsibilities will be to:

     

    • Tell the user that hey have successfully completed the checkout process
    • Provide them with a receipt and/or payment confirmation
    • Record the transaction
  2. The Payment Is Declined

     

    If a payment is declined we cannot complete the transaction as we do not have payment yet. However, the user is still present when this happens so all is not lost.

     

    Our responsibilities will be to:

     

    • Present the user with the payment form again
    • Let them know their credit card was declined by their bank
    • Ask them to try another credit card
  3. An Error Occurs Somewhere During The Payment Process

     

    If an error occurs during the payment process, whether due to connectivity or server issues, things can become a bit complicated. Do we try again? Do we ask the user to try again? How do we handle this from a customer service point of view? Exactly how you want to handle this is a business decision you need to make.

     

    In this example, our responsibilities will be to:

     

    • Present the user with the form again
    • Let them know an error occurred
    • Let the know their credit card was not charged
    • Ask the user to try again or
    • Ask the user to contact customer service to complete their order

 

Let's Write The Code To Do This

 

Once we have finished validating our user's data we need to check to see if there where any errors. We can do this by checking to see if there are any values in the $errors array. If there are we know not to process the transaction and display our error message to the user. If there are none we can attempt to process the transaction.

 

If you haven't done so already you will need to download the PHP SDK as we will use it in our example.

 

// If there are no errors let's process the payment
if (count($errors) === 0)
{
    // Format the expiration date
    $expiration_date = sprintf("%04d-%02d", $expiration_year, $expiration_month);

    // Include the SDK
    require_once('./config.php');

    // Process the transaction using the AIM API
    $transaction = new AuthorizeNetAIM;
    $transaction->setSandbox(AUTHORIZENET_SANDBOX);
    $transaction->setFields(
        array(
        'amount' => '1.00',
        'card_num' => $credit_card,
        'exp_date' => $expiration_date,
        'first_name' => $cardholder_first_name,
        'last_name' => $cardholder_last_name,
        'address' => $billing_address,
        'city' => $billing_city,
        'state' => $billing_state,
        'zip' => $billing_zip,
        'email' => $email,
        'card_code' => $cvv,
        'ship_to_first_name' => $recipient_first_name,
        'ship_to_last_name' => $recipient_last_name,
        'ship_to_address' => $shipping_address,
        'ship_to_city' => $shipping_city,
        'ship_to_state' => $shipping_state,
        'ship_to_zip' => $shipping_zip,
        )
    );
    $response = $transaction->authorizeAndCapture();
    if ($response->approved)
    {
        // Transaction approved. Collect pertinent transaction information for saving in the database.
        $transaction_id     = $response->transaction_id;
        $authorization_code = $response->authorization_code;
        $avs_response       = $response->avs_response;
        $cavv_response      = $response->cavv_response;

        // Put everything in a database for later review and order processing
        // How you do this depends on how your application is designed
        // and your business needs.

        // Once we're finished let's redirect the user to a receipt page
        header('Location: thank-you-page.php');
        exit;
    }
    else if ($response->declined)
    {
        // Transaction declined. Set our error message.
        $errors['declined'] = 'Your credit card was declined by your bank. Please try another form of payment.';
    }
    else
    {
        // And error has occurred. Set our error message.
        $errors['error'] = 'We encountered an error while processing your payment. Your credit card was not charged. Please try again or contact customer service to place your order.';

        // Collect transaction response information for possible troubleshooting
        // Since our application won't be doing this we'll comment this out for now.
        //
        // $response_subcode     = $response->response_subcode;
        // $response_reason_code = $response->response_reason_code;
    }
}

 

You can see we start of by checking the size of the $errors array and if it is zero we prepare to process the payment. We start by formatting the expiration date in a format the Authorize.Net will accept. In this case we choose to use the four digit year, a dash, and the two digit month. We follow that up by including the config file from the PHP SDK and initializing our the class that uses the AIM API. We set the code to use the development server so we don't incur any fees for our testing and then we provide the parameters needed to process the transaction.

 

We then process the payment and get the response object which we will use to determine the status of our payment. This is where we have to include some logic to handle the possible outcomes of the transaction. If the transaction is approved we collect the pertinent data returned to us by the merchant account provide: AVS results, CVV results, transaction ID, and authorization number. At this point you probably will want to store the order in the database and send the customer an email receipt for their order. In our example we send the user to a thank you page which probably should also include an order confirmation and printable receipt.

 

If the transaction is declined we really don't have to do much. We can add the notice to our $errors array and display it to the user when the page reloads.

 

If the transaction results in an error things can get dicey from a business perspective. In our example handling it with code is no different then a declined transaction except we are displaying a different message. Naturally an error at this point in the payment process to encounter an error is unexpected and definitely unwanted. You almost certainly should include some code to help you troubleshoot the error and attempt to prevent it from happening again. How you choose to do that is up to you.

 

Our Form Page So Far

 

Now that we have some more code written, let's see our how our page looks now:

 

<?php
    $errors = array();
    if ('POST' === $_SERVER['REQUEST_METHOD'])
    {
        $credit_card           = sanitize($_POST['credit_card']);
        $expiration_month      = (int) sanitize($_POST['expiration_month']);
        $expiration_year       = (int) sanitize($_POST['expiration_year']);
        $cvv                   = sanitize($_POST['cvv']);
        $cardholder_first_name = sanitize($_POST['cardholder_first_name']);
        $cardholder_last_name  = sanitize($_POST['cardholder_last_name']);
        $billing_address       = sanitize($_POST['billing_address']);
        $billing_address2      = sanitize($_POST['billing_address2']);
        $billing_city          = sanitize($_POST['billing_city']);
        $billing_state         = sanitize($_POST['billing_state']);
        $billing_zip           = sanitize($_POST['billing_zip']);
        $telephone             = sanitize($_POST['telephone']);
        $email                 = sanitize($_POST['email']);
        $recipient_first_name  = sanitize($_POST['recipient_first_name']);
        $recipient_last_name   = sanitize($_POST['recipient_last_name']);
        $shipping_address      = sanitize($_POST['shipping_address']);
        $shipping_address2     = sanitize($_POST['shipping_address2']);
        $shipping_city         = sanitize($_POST['shipping_city']);
        $shipping_state        = sanitize($_POST['shipping_state']);
        $shipping_zip          = sanitize($_POST['shipping_zip']);

        if (!validateCreditcard_number($credit_card))
        {
            $errors['credit_card'] = "Please enter a valid credit card number";
        }
        if (!validateCreditCardExpirationDate($expiration_month, $expiration_year))
        {
            $errors['expiration_month'] = "Please enter a valid exopiration date for your credit card";
        }
        if (!validateCVV($credit_card, $cvv))
        {
            $errors['cvv'] = "Please enter the security code (CVV number) for your credit card";
        }
        if (empty($cardholder_first_name))
        {
            $errors['cardholder_first_name'] = "Please provide the card holder's first name";
        }
        if (empty($cardholder_last_name))
        {
            $errors['cardholder_last_name'] = "Please provide the card holder's last name";
        }
        if (empty($billing_address))
        {
            $errors['billing_address'] = 'Please provide your billing address.';
        }
        if (empty($billing_city))
        {
            $errors['billing_city'] = 'Please provide the city of your billing address.';
        }
        if (empty($billing_state))
        {
            $errors['billing_state'] = 'Please provide the state for your billing address.';
        }
        if (!preg_match("/^\d{5}$/", $billing_zip))
        {
            $errors['billing_zip'] = 'Make sure your billing zip code is 5 digits.';
        }
        if (empty($telephone) || strlen($telephone) > 20)
        {
            $errors['billing_city'] = 'Please provide a telephone number where we can reach you if necessary.';
        }
        if (!filter_var($email, FILTER_VALIDATE_EMAIL))
        {
            $errors['email'] = "Please provide a valid email address";
        }
        if (empty($recipient_first_name))
        {
            $errors['recipient_first_name'] = "Please provide the recipient's first name";
        }
        if (empty($recipient_last_name))
        {
            $errors['recipient_last_name'] = "Please provide the recipient's last name";
        }
        if (empty($shipping_address))
        {
            $errors['shipping_address'] = 'Please provide your shipping address.';
        }
        if (empty($shipping_city))
        {
            $errors['shipping_city'] = 'Please provide the city of your shipping address.';
        }
        if (empty($shipping_state))
        {
            $errors['shipping_state'] = 'Please provide the state for your shipping address.';
        }
        if (!preg_match("/^\d{5}$/", $shipping_zip))
        {
            $errors['shipping_zip'] = 'Make sure your shipping zip code is 5 digits.';
        }

        // If there are no errors let's process the payment
        if (count($errors) === 0)
        {
            // Format the expiration date
            $expiration_date = sprintf("%04d-%02d", $expiration_year, $expiration_month);

            // Include the SDK
            require_once('./config.php');

            // Process the transaction using the AIM API
            $transaction = new AuthorizeNetAIM;
            $transaction->setSandbox(AUTHORIZENET_SANDBOX);
            $transaction->setFields(
                array(
                'amount' => '1.00',
                'card_num' => $credit_card,
                'exp_date' => $expiration_date,
                'first_name' => $cardholder_first_name,
                'last_name' => $cardholder_last_name,
                'address' => $billing_address,
                'city' => $billing_city,
                'state' => $billing_state,
                'zip' => $billing_zip,
                'email' => $email,
                'card_code' => $cvv,
                'ship_to_first_name' => $recipient_first_name,
                'ship_to_last_name' => $recipient_last_name,
                'ship_to_address' => $shipping_address,
                'ship_to_city' => $shipping_city,
                'ship_to_state' => $shipping_state,
                'ship_to_zip' => $shipping_zip,
                )
            );
            $response = $transaction->authorizeAndCapture();
            if ($response->approved)
            {
                // Transaction approved. Collect pertinent transaction information for saving in the database.
                $transaction_id     = $response->transaction_id;
                $authorization_code = $response->authorization_code;
                $avs_response       = $response->avs_response;
                $cavv_response      = $response->cavv_response;

                // Put everything in a database for later review and order processing
                // How you do this depends on how your application is designed
                // and your business needs.

                // Once we're finished let's redirect the user to a receipt page
                header('Location: thank-you-page.php');
                exit;
            }
            else if ($response->declined)
            {
                // Transaction declined. Set our error message.
                $errors['declined'] = 'Your credit card was declined by your bank. Please try another form of payment.';
            }
            else
            {
                // And error has occurred. Set our error message.
                $errors['error'] = 'We encountered an error while processing your payment. Your credit card was not charged. Please try again or contact customer service to place your order.';

                // Collect transaction response information for possible troubleshooting
                // Since our application won't be doing this we'll comment this out for now.
                //
                // $response_subcode     = $response->response_subcode;
                // $response_reason_code = $response->response_reason_code;
            }
        }
    }

    function sanitize($value)
    {
        return trim(strip_tags($value));
    }

    function validateCreditcard_number($credit_card_number)
    {
        $firstnumber = substr($credit_card_number, 0, 1);

        switch ($firstnumber)
        {
            case 3:
                if (!preg_match('/^3\d{3}[ \-]?\d{6}[ \-]?\d{5}$/', $credit_card_number))
                {
                    return false;
                }
                break;
            case 4:
                if (!preg_match('/^4\d{3}[ \-]?\d{4}[ \-]?\d{4}[ \-]?\d{4}$/', $credit_card_number))
                {
                    return false;
                }
                break;
            case 5:
                if (!preg_match('/^5\d{3}[ \-]?\d{4}[ \-]?\d{4}[ \-]?\d{4}$/', $credit_card_number))
                {
                    return false;
                }
                break;
            case 6:
                if (!preg_match('/^6011[ \-]?\d{4}[ \-]?\d{4}[ \-]?\d{4}$/', $credit_card_number))
                {
                    return false;
                }
                break;
            default:
                return false;
        }

        $credit_card_number = str_replace('-', '', $credit_card_number);
        $map = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 4, 6, 8, 1, 3, 5, 7, 9);
        $sum = 0;
        $last = strlen($credit_card_number) - 1;
        for ($i = 0; $i <= $last; $i++)
        {
            $sum += $map[$credit_card_number[$last - $i] + ($i & 1) * 10];
        }
        if ($sum % 10 != 0)
        {
            return false;
        }

        return true;
    }

    function validateCreditCardExpirationDate($month, $year)
    {
        if (!preg_match('/^\d{1,2}$/', $month))
        {
            return false;
        }
        else if (!preg_match('/^\d{4}$/', $year))
        {
            return false;
        }
        else if ($year < date("Y"))
        {
            return false;
        }
        else if ($month < date("m") && $year == date("Y"))
        {
            return false;
        }
        return true;
    }

    function validateCVV($cardNumber, $cvv)
    {
        $firstnumber = (int) substr($cardNumber, 0, 1);
        if ($firstnumber === 3)
        {
            if (!preg_match("/^\d{4}$/", $cvv))
            {
                return false;
            }
        }
        else if (!preg_match("/^\d{3}$/", $cvv))
        {
            return false;
        }
        return true;
    }
?>
<!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">
        <style type="text/css">
            #errormessage
            {
                background-color: #FFE7E7;
                border: 3px solid #CC0033;
                color: #000000;
                margin: 20px auto;
                padding: 10px;
                width: 890px;
                -moz-border-radius: 6px;
                -webkit-border-radius: 6px;
                border-radius: 6px;
                -moz-box-shadow: 5px 5px 5px #ccc;
                -webkit-box-shadow: 5px 5px 5px #ccc;
                box-shadow: 5px 5px 5px #ccc;
                background: -webkit-gradient(linear, 0 0, 0 bottom, from(#FFEAEA), to(#FFB3B3));
                background: -moz-linear-gradient(#FFEAEA, #FFB3B3);
                background: linear-gradient(#FFEAEA, #FFB3B3);
            }
            .labelerror
            {
                color: #ff0000;
                font-weight: bold;
            }
        </style>
    </head>
    <body>
<?php
    if (count($errors))
    {
?>
        <div id="errormessage">
            <h2>
                There was an error with your submission. Please make the necessary corrections and try again.
            </h2>
            <ul>
<?php
            foreach ($errors as $error)
            {
?>
                <li><?php echo $error; ?></li>
<?php
            }
?>
            </ul>
        </div>
<?php
    }
?>
        <form action="/payment-form.php" method="post">
            <p>
                <label for="credit_card"<?php if (in_array('credit_card', $errors)) echo ' class="labelerror"'; ?>>Credit Card Number</label>
                <input type="text" name="credit_card" id="credit_card" autocomplete="off" maxlength="19" value="">
            </p>
            <p>
                <label for="expiration_month"<?php if (in_array('expiration_month', $errors)) echo ' class="labelerror"'; ?>>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"<?php if (in_array('cvv', $errors)) echo ' class="labelerror"'; ?>>Security Code</label>
                <input type="text" name="cvv" id="cvv" autocomplete="off" value="" maxlength="4">
            </p>
            <p>
                <label for="cardholder_first_name"<?php if (in_array('cardholder_first_name', $errors)) echo ' class="labelerror"'; ?>>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"<?php if (in_array('cardholder_last_name', $errors)) echo ' class="labelerror"'; ?>>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"<?php if (in_array('billing_address', $errors)) echo ' class="labelerror"'; ?>>Billing Address</label>
                <input type="text" name="billing_address" id="billing_address" maxlength="45" value="">
            </p>
            <p>
                <label for="billing_address2"<?php if (in_array('billing_address2', $errors)) echo ' class="labelerror"'; ?>>Suite/Apt #</label>
                <input type="text" name="billing_address2" id="billing_address2" maxlength="45" value="">
            </p>
            <p>
                <label for="billing_city"<?php if (in_array('billing_city', $errors)) echo ' class="labelerror"'; ?>>City</label>
                <input type="text" name="billing_city" id="billing_city" maxlength="25" value="">
            </p>
            <p>
                <label for="billing_state"<?php if (in_array('billing_state', $errors)) echo ' class="labelerror"'; ?>>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"<?php if (in_array('billing_zip', $errors)) echo ' class="labelerror"'; ?>>Zip Code</label>
                <input type="text" name="billing_zip" id="billing_zip" maxlength="5" value="">
            </p>
            <p>
                <label for="telephone"<?php if (in_array('telephone', $errors)) echo ' class="labelerror"'; ?>>Telephone Number</label>
                <input type="text" name="telephone" id="telephone" maxlength="20" value="">
            </p>
            <p>
                <label for="email"<?php if (in_array('email', $errors)) echo ' class="labelerror"'; ?>>Email Address</label>
                <input type="text" name="email" id="email" maxlength="20" value="">
            </p>
            <p>
                <label for="recipient_first_name"<?php if (in_array('recipient_first_name', $errors)) echo ' class="labelerror"'; ?>>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"<?php if (in_array('recipient_last_name', $errors)) echo ' class="labelerror"'; ?>>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"<?php if (in_array('shipping_address', $errors)) echo ' class="labelerror"'; ?>>Shipping Address</label>
                <input type="text" name="shipping_address" id="shipping_address" maxlength="45" value="">
            </p>
            <p>
                <label for="shipping_address2"<?php if (in_array('shipping_address2', $errors)) echo ' class="labelerror"'; ?>>Suite/Apt #</label>
                <input type="text" name="shipping_address2" id="shipping_address2" maxlength="45" value="">
            </p>
            <p>
                <label for="shipping_city"<?php if (in_array('shipping_city', $errors)) echo ' class="labelerror"'; ?>>City</label>
                <input type="text" name="shipping_city" id="shipping_city" maxlength="30" value="">
            </p>
            <p>
                <label for="shipping_state"<?php if (in_array('shipping_state', $errors)) echo ' class="labelerror"'; ?>>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"<?php if (in_array('shipping_zip', $errors)) echo ' class="labelerror"'; ?>>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>

 

What's Next?

 

At this point we have a fully functional checkout form that's usable and secure. But that doesn't mean we can't improve upon it. In the remaining posts in this series we are going to make incremental improvements to our form and payment process. We'll begin by preventing a page refresh from resubmitting the form again.

 

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 TheWizard on ‎03-02-2011 06:45 AM

Hi

 

Great Series, from 1 to 5. :smileyhappy:

Could you have a simple modification of this post (part 5), and add code in C# - ASP .NET Web Forms (not MVC), as well.

 

Thanks

by musictranscribe on ‎03-12-2012 11:57 PM

I love this tutorial, but I am confused a bit by the fact that you keep requiring the config.php file instead of the AuthorizeNet.php file that is in the SDK. I don't see any config.php file in the SDK.... Thanks!

by man6812 on ‎03-08-2013 11:48 PM

Thanks for the tutorial it makes much more sense than the sample code on document.  Anyway, I have a few questions.

 

1.  If I need to include optional recurring biling (ARB or CIM) how do I incorporate the code with your sample form?

2.  Do I need to have database to process or can it be directly send to Authorize.net?

 

 

thx.

by Moderator Moderator on ‎03-12-2013 01:13 PM

1. Processing with ARB and CIM are substantially different in terms of transaction flow. For ARB, you could largely use this form for collecting customer information, and replace the usage of an AuthorizeNetAIM object with an AuthorizeNetARB object. However, this would require you to add additional information describing the payment schedule of the subscription.

The transaction flow for CIM is really too different to be applied with this example. When using CIM, transaction processing is separated into two distinct steps of collecting customer information, and charging the customer.

2. The database in this example is only used if you would like to store the transaction results within your own system. Strictly speaking, it is not necessary.

by auththch on ‎06-24-2013 10:17 AM

I've tried to adapt this AIM "test environment" setup to a live, secure setup but keep getting validation errors. The form seems to be working properly but I keep getting "There was an error with your submission", which is the text appearing in the 

"if (count($errors))" div at the beginning of the html. I've removed the validation for structure of the expiration date and just want authorize.net to validate it's accuracy. Is that a problem? If I were to post my code, could you please check it and let me know? If so, I'll be happy to post it.

Thanks.

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