My family owns and runs a small bicycle shop in Appleton, WI. For years they used a turn-key solution to sell items online. Over time the solution proved to be inadequate and they asked me if I could help them migrate to something new. After doing quite a bit of research I discovered that most free or open source solutions were missing features or were incredibly difficult to configure and maintain. On top of that, most of the for-pay subscription services were expensive and still didn’t have all of the features I was looking for. At this point I decided to build my own. Little did I know that I was starting a path that would teach me why most e-commerce solutions were complicated, missing features, expensive, or all three.
Building a full ecommerce site from scratch can be overwhelming. There are a lot of moving parts that constantly need to be tracked and used in various ways. In the first part of this guide I’ll cover an introduction to the various components required to build an ecommerce site. Later, I’ll dive into actual code examples for building an ecommerce site in Django.
The first part of an ecommerce site is the product we are going to sell. Through the entire process of building the site the code will almost always be touching the product in some way. We’ll want to ensure that the product model has a few key attributes. At a minimum we should have name, price, and description. As your site grows in complexity you’ll eventually add more fields, but for now this will give us a good start.
Anyone that has shopped online will know that we don’t want to list all of the products on one page. In order to help people find what they are looking for we’ll want to categorize the products. From a software engineering perspective, categories are actually an interesting problem to solve. At a minimum we’ll want to have a category model that has a name and parent attribute, and a method to find subcategories.
The name attribute will describe the category. The parent attribute will help us establish some sort of hierarchical relationship among all of the categories and products. A parent relationship will let us find subcategories (children) and super-categories (parents). Once we’ve established the categories, we’ll want to add a category attribute to the product model we built earlier. This would be a great time to think about whether or not you will need many-to-many relationships on your products and categories.
At this point we should be able to navigate the categories and find products. The logical next step is to have a cart where a consumer can add the products they wish to purchase while they browse more products. A cart is actually very simple in theory, but we’ll want to consider a few key things while creating it.
A cart will need to be associated with a user. If a user is not logged in then we’ll need to have a way to identify carts per session. Saving carts in the session will eventually lead to a situation where we will need to merge carts when a user logs in.
Next we’ll need a way to add, remove, and modify items in a cart. The simplest way to do this is to create a separate model for cart items that associates products with a user’s cart. This structure will help us in the future when we need to work with quantities, discounts, and custom products.
From here we will be able to do all of our operations on the cart. The code will be structured in such a way that we can easily calculate totals, subtotals, taxes, shipping, etc. The last thing we’ll want to consider, depending on the framework being used, is that we will want a reliable and consistent way to retrieve the cart every time a consumer views a page. We’ll want to ensure that this code is executed every request before we get into any other code.
After a consumer adds their products to the cart, they will hopefully commit to purchasing them. This is where things can get complicated if we don’t plan a bit. Before we write code for the checkout process we will want to decide how we are going to accept payments. If you decide at any point in time that you want to store payment information about your users you will absolutely need to consider PCI Compliance. Regardless of this decision we will at minimum need an SSL certificate for the entire site. In the past it was a common practice to only use SSL when sensitive information was being passed to/from the site to reduce overhead. However, since computing power has dramatically increased, using SSL on all pages for every request poses almost no hot to performance and is highly beneficial. As such, I highly recommend enabling SSL for all requests because it will make your site more secure and will also make sessions easier to manage.
Security and payment
After obtaining an SSL certificate, the next step it to pick a payment processor. Depending on the size of your business and your requirements there are many options available including local credit unions, national banks, Authorize.net, and PayPal, Zuora. My favorite, as a developer, is Stripe.js. Stripe.js has incredible documentation and a well-thought-out API. Using Stripe.js also enables us to store almost no information about the consumers on our servers. We can leave the fun that is credit card security up to a company that specializes in it.
Now that we have someone to process the payments we will need to gather the information required for processing a payment. At minimum we will need to collect a billing address, credit card information, and the total price of the cart. The simplest way to do this is to put all of the form fields on one page. But this isn’t very user friendly especially since we will most likely want to gather more information including shipping address, order notes, gift options, and anything else you can think of that is related to your business. In regards to making the site and checkout process more user friendly we will probably want to narrow the scope of each page to one or two activities. This will require planning a method to keep track of and continuously validate the submitted information during the process. For example, let’s say we have the following steps:
- Shipping address
- Billing address
- Payment information
- Confirmation page
When we go from step 1 to step 2 we will want to validate and store the shipping address. Then going from step 2 to step 3 we will want to validate the billing address and assert that we still have a shipping address in case the consumer tries to pull a fast one on us and jump around the checkout process. Again, going from step 3 to 4 will require assertions of all of the previous steps. In the final step we will have one more aspect to consider. If the payment information is valid then we will need to clear the checkout session and record the transaction. If the payment fails then we will need to back out everything we did while attempting the payment and report the error to the consumer and allow them to go back and update or fix any incorrect information. This is where planning a solid framework for storing the checkout session information becomes incredibly valuable and should be a substantial portion of your planning and testing.
Extra Considerations for Ecommerce
Some other features you may want to consider while planning your ecommerce site is the inclusion of shipping costs and discounts. Shipping costs can be approached a few different ways. We can calculate costs per order, per the number of items in the order, per the weight of the order, etc. The hardest part about shipping costs is calculating exact costs. This difficulty can be mitigated on the physical side of things by keeping track of product weights, sizes, flat-rate shipping costs, etc. Depending on the framework you use or build there are some plugins and APIs that can be used to simplify the process of calculating actual costs. Even with these tools careful planning will be needed to make them effective. Discounts can be implemented in a wide variety of ways, but there are a few simple implementations that will cover more use cases. Adding discounts that are whole cart, per category, and per product is the minimum implementation to have effective discounts.
There you have it. This is the bare minimum outline to build a full ecommerce website. In the next part I’ll discuss the options available for existing ecommerce code bases and then step through actual code examples to implement the points discussed in this guide in the Django framework.