Accepting Payments Online - Part 1: Getting Started
Sunday, September 18, 2011
This is the first of an eight part series I'm working on explaining how to accept online payments. Just so you know, I'm not going to post code for an entire shopping cart in this series. What I will cover is security considerations, and the actual processing of payments through each of the following payment gateways:
This series is aimed at developers who want to build their own shopping cart. Before going any further, a bit of advice: don't write your own shopping cart! Seriously, there are some really good,full-featured free eCommerce solutions out there, such as Magento or Zen Cart. Writing your own shopping cart software always seems like a cool idea -
I can build this however I want, and I don't have to learn anyone else's system, right? Well, yes, but if you've never written something like this before you are in for a long, long journey.
The Nightmare Begins...
I started the code that has evolved into the shopping cart I use today a few years ago. It started off deceivingly simple: I had a client that wanted to sell one product online for a single price. I started looking at php-based eCommerce packages, and all I read were people griping about how horrible and bloated they were. I downloaded a few, and yep - giant piles of spaghetti-coded crap that somehow hung together enough to function. If there is one thing I hate it's crappy code, so I decided I could certainly handle writing a little application that only had to sell one product for a price that could be hard-coded into it....so I did, and it was easy. I think that client ended up selling exactly 2 products before they gave up, but my code totally worked.
So then it gets out that -
Hey, that guy can make eCommerce sites! Enter the next client, and oh -
I need to sell 100's of different products with all sorts of unique properties. I also need to offer credit card purchases through PayPal, and offer PayPal Express Checkout. Oh, and I need live shipping quotes from Fedex, a feed to Google Merchant Center, Tax Tables for different states, 30 product pictures per item that will need to be resized on the fly to 7 different sizes, and email notifications sent to client purchases, package tracking, refund and void ability, and......
I knocked that out in a couple of months and I was pretty proud of myself. I didn't have much time to celebrate before the next client came along. He needed to sell T-Shirts, but didn't want to hand enter the 30,000 color/size/gender combinations he had available, so he needed a mind boggling matrix of options available: some shirts were only mens, some only womens, some both - each men's shirt had certain colors available, and women's shirts had a completely different color palette - each color was only available in certain sizes, and the sizes depended on the gender - but not every shirt had the same sizes available.....
You can do that, right? By the way, I use Authorize.net and get my quotes through UPS. I also want to provide free shipping if they order 5 shirts or more, but only if they put in a promo code. The code should only be able to be used one time, so I will need to have randomly generated codes that don't contain any "confusing" characters like zero and the letter "O", and I plan on printing these onto business cards, so I will need to be able to download those to an Excel spreadsheet that I can send to my printer. Oh, and it would be really cool if when a user rolled his cursor over the different colors available for a shirt the color would update in the model pictures I will provide. Last thing - I want users to be able to design their own shirts online by picking one of 700 fonts, a shirt color, upload high resolution images and scale/position them, all with a live preview. Cool?
And that's how it went for the next 10 eCommerce sites I built. Every client had new additions, different business logic, products with completely different properties, used a different payment gateway, needed additional promo code features, needed pdf invoices printed in different formats, etc. One of the more recent sites I built sells products in 3 different countries, so they needed full language translation and currency conversion depending on which cute little flag icon the user clicked on. I also had to add product ratings/comments that customers could enter. Oh yeah, and since they are selling in the Netherlands, they needed to support payments through Rabobank's idEAL Payment gateway, whose documentation is scattered into several poorly translated documents that do not follow any logical order, and require creating self-signed certificates through Open SSL, trying to parse certificates through php's cryptic, poorly documented openssl functions, and trying to make sense of unhelpful error messages returned from iDEAL's test environment that are written in.....yep, German!
So why didn't I just give up a long time ago and use something like Magento? Maybe I'm just a glutton for punishment, or perhaps after a certain point I started understanding what kinds of changes clients would need to my shopping cart out of the box, and was able to restructure all of my code so that it was easy to add features. I still haven't found a shopping cart out there that has all of the functionality I have in mine, but at the same time some of the eCommerce solutions out there have hundreds of features I don't have.
What I do have, is a lightweight, easy to use shopping cart that works great for my clients. I wrote all the code so I can easily modify it if I need to, and every new eCommerce client I get wants features that I write into the code that help future clients. I really like what I have and it's easy to use for me, but if I had a crystal ball 3 years ago I probably would have gone with an off-the-shelf solution.
Alright, if I haven't lost you or scared you off yet, feel free to read on.
Security, Security, Security
The second you start thinking about accepting payments through this crazy thing we call the Internet, alarm bells should be going off in your head. Chances are if you've owned a credit card for any amount of time, it's been compromised at one point. There are many ways "hackers" get access to your account information, including viruses, spyware, phishing, etc. Many times however, the culprit is just a mess of naively unsecure code some "PHP cowboy" slapped onto a server. I took on a new eCommerce client awhile back that had an existing site. While examining the old site, I noticed that there wasn't a single secure page on the site, and that credit cards were not actually being processed on the site although customers were required to enter their credit card information during the checkout process. After a meeting, I discovered that all of the customer's information was being posted through a regular http connection, and emailed to the client where they would run the card info on the machine in their office. I almost wanted to pull their order history, call each client, and take a poll on how many had been victims of identity theft, but that might have made some people unhappy.
Before you even start writing a line of code, here is a list of things you will need to prepare for:
Security and eCommerce Requirements
SSLYou will need to purchase and install an SSL Certificate signed by a trusted 3rd party. Certificates vary greatly in price, but I think for anyone starting out the $70 godaddy certificate is the best place to start. It's cheap and accepted by every browser I know of. What you don't want to do is sign your own certificate to save money, or drop $1000 (or more) on a certificate before you've even sold a product. You can always upgrade your certificate later when you are raking in the dough. Lastly, every form on your site where a user is entering personal information needs to be both presented on and posted through a secure https connection. Technically, when a form is submitted it only needs to POST to a secure link, but customers don't know that - they want to see the little lock icon in their browser.
SessionsYour shopping cart is going to require a login system, which will require the use of sessions. There are two ways sessions can be utilized - the first is to store the session id in a cookie on the user's computer. The second is to pass the session id in the query string from page to page. The latter is the method you want to avoid: it increases the chances of session hijacking, and can be problematic when trying to get your pages indexed by search engines.
Information for CustomersVisa and Mastercard have requirements that must be met if you are going to allow customers to make purchases with either card. Even if you are not, their requirements are certainly a good idea. Here are some of the things you will need to add to your website in order to comply:
Business contact informationThe country of origin, physical address, and customer service telephone number. These are things that are a good idea to put on every page, either in the header, footer, or sidebar as it makes potential customers feel at ease. A contact form that allow customers to contact the business owner via email is also highly recommended.
CurrencyIt should be clear what currency the transaction is being conducted in, which is sort of a no-brainer.
DeliveryThe shipping method, approximately how long it will take to ship, etc.
Card logosDisplay a logo for each payment method you accept.
Terms and ConditionsYou will need a terms and conditions page that can be reached from any page on the website (usually the footer is a good place to stick this). You will also need to display either a link, or the full T&C on the one of the final checkout pages (perhaps in a scrollable iframe). There are several templates out there - just make sure you have actually read through what you use, and that it applies fully to the business owner.
Return & Refund PolicyDon't use a template for this, have the business owner actually write this up. It can be as short as a sentence or two. Like the Terms & Conditions, it should be linked to from every page, and either be displayed or linked to near the end of the checkout process.
SSL DescriptionThe type of SSL used on the site (i.e., SSL Secured 128 bit), which can usually be displayed with the Site Seal provided by the Certificate Signing Authority that the certificate was purchased from.
ServerIdeally, your eCommerce server will be a dedicated, or VPN server. Shared hosting servers may be used if the rest of the security measures listed here are followed, but there can be a wide gap in security configurations between hosting companies - some have everything locked down so that other users cannot access your files, others have gaping security holes. Make sure you research your hosting company, and ask them about their security measures prior to purchasing the hosting. What happens if PHP should go down on the server - will php files be displayed in plain text? Also, make sure that they offer access to a private directory that is above the web root. This is where you will want to store sensitive information such as Payment Gateway access codes, database passwords, etc. Never store any kind of a password in a file that is inside a publicly accessible directory. Lastly, if you are on an Apache server, make sure your host allows you to modify .htaccess and php.ini files. .htaccess rules are useful for locking down all directories and files that people have no business rooting around in, and php.ini files allow you to configure php in a secure manner.
DatabaseYour database should be configured not to accept remote connections. All customer passwords should be hashed with a strong hashing algorithm, and certainly never stored in plain text. Your database should be protected with strong passwords, and ideally the passwords should be changed on regular intervals. Use basic security principles such as using prepared statements to prevent SQL injections - I highly recommend PHP's PDO class for this.
Storing InformationYou should never store more information than you absolutely have to. Certainly you will want to store the customer's name, shipping and billing address, etc. What should never be stored are the customer's credit card number, or the 3 digit card verification code (CVV2), or even the card expiration date. The CVV2 code is illegal to store. The credit card number is (theoretically) legal to store based on the PCI Data Security Standard if the server itself is PCI Compliant, and all 20,000 security measures outlined in the document are in place. That will run you at least $3k a year, and you will probably be audited on a regular basis with non-compliance fines starting around $25,000. In short, there is absolutely no reason to ever store either of these items (even temporarily in a session variable). Many payment gateways offer a recurring billing system if you should require that functionality. The payment gateway companies hire large staffs of security experts and consultants to protect the information they store, and spend millions of dollars a year to comply with security laws - leave the information in the hands it belongs in.
Next: Part 2
That about sums up what you'll need to be prepared for. In Part 2 (coming soon), we will get away from all the scary stuff, and start digging into some actual code! Stay tuned...