I built a shopping cart system the other day. It seemed at the time to be a ridiculous waste of resources — I mean, how many shopping carts are out there already? There are probably 500 open-source versions alone.
But, I built my own, and for good reasons. Here are those reasons, plus some random thoughts that came across my mind when I was putting this thing together.
Build or Buy
I had a perfectly wretched experience a few months ago with a commercial shopping cart. It was horrible — the app had so much functionality built into it, and it wasn’t really designed for anything to be modified.
Instead of integrating it into a site, I spent most of the time shutting functionality off and trying to figure out what that broke and what I had to change to get it working again.
I have an entire post in my head about the theory at work here, but the bottom line is that most commercial shopping carts want to be everything to everyone, so they provide astounding levels of configurability and corresponding levels of complexity.
Why They Have to Be So Complicated
In most cases, you find that you use less than 20% of the available functionality of any store. But the designers of the system have a real problem, because almost everyone uses a different 20%.
A store system is a phenomenally specific thing. I can’t think of many apps that could have a wider set of requirements than a shopping system.
Take content management. It exists online only, really. It’s used to build Web sites that didn’t exist 10 years ago, and that norms have built up around over the years. It’s a known quantity.
But shopping carts have to collide with their real-world equivalent. There are stores and sales and guidelines and offline businesses that need to run on these shopping cart systems, and all of them have their own quirks and idiosyncracies. Precious few online stores are the same, and it’s in the little details where you have a tendency to blow apart requirements and run smack dab into functionality walls.
So, commercial shopping carts have to try and encompass ridiculous ranges of functionality. I’m sure some do it well, although I haven’t seen any yet. Either they’re extremely simple and limited, or they’re extremely complex and flexible.
What Shopping Carts Do
What I needed for this particular app was something so simple that it almost didn’t live up to the term “shopping cart.” So I sat down and figured out what a shopping cart was, at its core.
Distilled down do its most basic elements, a shopping cart is really just a glorified “Contact Us” form. Specifically, this is all the cart I needed had to do. Customers needed to be able to:
- View products.
- Click an “Add to Cart” button for a particular product.
- View what is currently in their cart. From this screen, they needed to be able to change product quantities or remove items.
- Elect to checkout, where they needed to be able to enter personal and payment information then submit their order.
The system itself needed to be able to:
- Automatically calculate shipping and tax.
- Store the customer’s information securely.
- Email the administrator when a new order is received.
The administrator of the system needed to be able to:
- Log in to a protected area of the site to view orders.
- Change the status on an order (from “Pending” to “Waiting on Payment” or whatever).
- Delete orders as necessary.
And that’s it. Like I said, this is just a complicated “Contact Us” form. In fact, I’ve written contact forms that were vastly more complicated than this — they logged in a database, they got a lot of input from the customer, they had an administrative section to view submissions, etc. One of them every sent clickstream data for that customer so the administrator could see every page they had clicked on the site, in the order they clicked on them.
The only thing that makes this fundamentally different is that there’s a session-based system to collect clicks of a button and correspond them to different products.
Automatic vs. Manual Payment Processing
There’s no payment processing in my system, which brings up another point I make time and again to clients: you probably don’t need automatic payment processing, and certainly not right out of the gate.
Payment processing is complicated. And if it fails, the stakes are pretty high — we’re dealing with people’s money, remember. Not charging someone’s card is bad enough. Charging it 17 times by accident is worse.
I’ve met people who are setting up a very simple Web store for which they don’t have any business now and really aren’t expecting a lot. They seem fixated on automatic payment processing. While it’s nice, it’s also expensive to set up, and it really complicates things.
What we advise in these situations is to “human gap” the payment processing phase at first, meaning have a human received a notification email (either secure or without the credit card information), and have them enter orders in some Web control panel. About every merchant account offers Web-based control panels like this, and there are other services that let you arbitrarily charge credit cards as you need to.
So long as you have a facility in your store to set “Order Status,” then it becomes simple for a person to process the orders, then update the order to indicate whether or not it’s been done.
Regarding when to switch to a fully-automated method, I always say the same thing: do it when it makes sense financially. When you’re processing enough orders that you don’t mind paying the extra cost to automatically process charges, then that’s probably a good time to do it.
Product options are a huge wet blanket on the otherwise pleasant experience of writing a shopping cart. A product option is like a size: S, M, or L.
The problem is that they essentially create an entirely new product. A small sweater has to be logged in the cart separately from a medium sweater, and they each have to have their own quantities — I can order two small sweaters, four medium sweaters, and 1,260 large sweaters in the same order.
To get things more complicated, add a second option: size and color, for instance. Now we’re checking options in two dimensions. Four sizes and six colors mean twenty-four effective products.
And do the options affect the price? The shipping? If a customer orders a mailbox and they select the “Include the Mounting Post” option, do you need to add twenty dollars on the price and ten dollars on the shipping?
What about when product options spawn other options? If I select the “add lettering” option to my sweatshirt product, does that create the need to add the “font” and “custom text” options?
They’re tricky because when a customer adds a product to their cart, you have to have a way to check that product’s “signature” — its product ID and its particular combination of options that make it unique. You can then use this to determine if we’re incrementing an existing item in the cart, or if we’re adding a completely new item. As we said before, if any option is different, then this is a new item.
And there you have it. I’m happy with the system I ended up building, and I plan to open-source it at some point.
It’s object-oriented PHP, and it can work like more of a framework than anything else — there are strong, clean interfaces, so if it needs to be modified, it’s not that hard (want to incorporate automatic payment processing — override $Cart->ProcessOrder(), etc.)
That’s the idea, anyway. But feature creep, she is a callin’…