Handling Online Payments Part 10 - A Little Bit More PHP

by All Star ‎06-07-2011 09:35 AM - edited ‎10-20-2011 09:56 AM (11,675 Views)

This is part ten 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 Part 5 of this series we processed the payment and handled the response returned to us whether it be approved, declined, or an error completing the transaction process.


In Part 6 of this series we changed our focus to improving upon our form to make it more user-friendly, secure, and easier to maintain. We accomplished this by preventing duplicate form submissions using the POST/REDIRECT/GET design pattern. In Part 7 of this series we prevented spambots and other malware from making automated form submissions by using a honeypot and form token. Part 8 of this series we used JavaScript to increase the usability of our web form making it even easier to use. In Part 9 of this series we used some HTML and CSS to enhance the layout to make the form easier to use and more visually appealing.


In this installment of the series we are going to improve our PHP code to make maintaining the payment form easier to do.


Making Our Drop Down Menus Easier To Manage


An experienced web developer will review their code, and even HTML, periodically to see if there is anything which might benefit from a round of refactoring. When they see repetition or any other kind of pattern, the first thing they think is, "There's got to be a better way to do this," and there usually is. Our payment form is no exception. We have several opportunities to automate the display of information.


The first one that catches my eye is the expiration date form field. Currently we have hardcoded the current year plus an additional twelve years into our forms as options. The problem with this is, what happens when the New Year comes? Our form is now showing an invalid year as the first option and only offers eleven other years instead of twelve. That's a double whammy of badness. We can use PHP here to dynamically create this drop down for us and always offer the current year plus twelve years automatically, even after New Year’s Day. Let's look at the code for this:


    $current_year = date("Y");
    $stop_year = $current_year + 12;
    for ($year = $current_year; $year <= $stop_year; $year++)
                        <option value="<?php echo $year ?>"><?php echo $year ></option>


We start by getting the current year and the year twelve years from now (we will call it our "stop year"). We then use a for loop to iterate through each year starting from this year and stopping at the stop year. Because the current year and stop year are created dynamically when the New Year comes our form is automatically updated with the correct years. If we ever want the stop year to be more then twelve into the future, let's say 14 years, all we need to do is edit the value of $stop_year to $current_year + 14. That's it.


An even bigger opportunity for us to automate things, and really save us a lot of coding, is to automate the drop down menus for the two "state" fields in our form. We have 50 <option> tags for each drop down. That is more than 100 lines of code to make two drop down menus. There definitely is a better way to do it. We will start with an array containing the abbreviations and full names of all 50 states.


$states = array('AL'=>"Alabama",'AK'=>"Alaska",'AZ'=>"Arizona",'AR'=>"Arkansas",'CA'=>"California",'CO'=>"Colorado",'CT'=>"Connecticut"
               ,'DE'=>"Delaware",'DC'=>"District Of Columbia",'FL'=>"Florida",'GA'=>"Georgia",'HI'=>"Hawaii",'ID'=>"Idaho",'IL'=>"Illinois"
               ,'NE'=>"Nebraska",'NV'=>"Nevada",'NH'=>"New Hampshire",'NJ'=>"New Jersey",'NM'=>"New Mexico",'NY'=>"New York"
               ,'NC'=>"North Carolina",'ND'=>"North Dakota",'OH'=>"Ohio",'OK'=>"Oklahoma",'OR'=>"Oregon",'PA'=>"Pennsylvania"
               ,'RI'=>"Rhode Island",'SC'=>"South Carolina",'SD'=>"South Dakota",'TN'=>"Tennessee",'TX'=>"Texas",'UT'=>"Utah"
               ,'VT'=>"Vermont",'VA'=>"Virginia",'WA'=>"Washington",'WV'=>"West Virginia",'WI'=>"Wisconsin",'WY'=>"Wyoming");


After placing that array at the top of our page we can loop through it where we need to create the <option> tags. We can even go a step further and check to see if the user selected the current state being printed, and if so, have it be selected when the page loads.


    foreach ($states as $state_abbr => $state_name)
        $selected = (isset($billing_state) && $billing_state === $state_abbr) ? ' selected="selected"' : '';
                        <option value="<?php echo $state_abbr; ?>"<?php echo $selected; ?>><?php echo $state_name; ?></option>


Repeat that for the shipping state and suddenly we have eliminated a huge swath of code and made maintaining this form a lot easier.


One More Minor Change


Our custom functions we created to help us validate user-provided data help us out by making our code cleaner and easier to use. But they are kind of "in the way". Yes, we need them to validate data but we don't need to see them every time we manage this form since they aren't really a part of the payment logic. They're more like tools for that logic to work. Ideally we would put them somewhere where they won't get in our way whenever we need to revisit this page and make updates. So what we will do is put them in their own file and include that file whenever we need to use them. In our case it will be when a form is submitted. So we will take these functions out and place them in a file called payment-functions.php and place them in the same directory as our payment form. We then can include them into our payment form by using PHP's require() function.



    // Error handling starts here


By placing the functions in a separate file we have successfully removed the "tools" from our form and left the logic behind. This makes our form much easier to maintain as we do not need to wade through a bunch of functions to find the code we need to change.


Updated Payment Form


To see our new form with our new PHP code included just download the attachment at the end of this blog post. Don't forget to also download the PHP SDK.


What's Next?


Our next installment will be the last in this series. We will wrap things up with some suggestions for small improvements and have a final completed payment form ready for your website.


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

by ibanezjah80 on ‎02-15-2012 03:10 PM

What if I want to have a thank you page that gives them a confirmation code, how would I go about doing that?

by frankvg3 ‎10-06-2014 03:13 PM - edited ‎10-06-2014 03:14 PM

Thanks for putting this together. For others attempting to use this code, it appears Authorize.net has completely changed it's code so that none of this meshes up properly anymore and you can't download a PHP SDK that works any longer. There is no "config.php" file that this code references.


In addiiton the payment-form.php code has a few bugs. If you want to play with the code, you may need to make thes changes;

Line 16:         require('payment-functions.php');
Line 87:     $errors['telephone'] = 'Please provide a telephone number where we can reach you if necessary.';
Line 222:      header('Location: payment-form.php', true, 303);
Line 351:      <form action="payment-form.php" method="post">


Lastly, it appears from the end of part 10 that another installment was planned, but I'm guessing since this was written 2+ years ago, no more installments are going to be made which is too bad.


Unfortuantely, all the new code's documention on GitHub has no working examples and much of the documentation is inaccurate or wrong (as of this writing).

About the Author
  • Authorize.Net Developer Community Manager