E-Commerce in Cold Fusion
Posted by James Harvey
at 2:03 PM on Nov 7, 2008
0 comments - Posted In:
Tutorials | Cold Fusion
This tutorial uses arrays and structures to develop a shopping cart system. This tutorial also contains web-front order processing (e-commerce) information that most of you will probably find very helpful alongside the shopping cart.
This tutorial comes from an eclectic group of sources. I utilized Macromedia's LiveDoc's, CJ's tutorials, as well as many other tutorial information when I first built a full shopping cart system. With that in mind, some of my coding may seem familiar from elsewhere, and I want to acknowledge that I took parts of my coding from other sources when I initially wrote all of this coding. At this point I cannot cite exactly which parts are from elsewhere, but just know that some parts are.
Additionally, this tutorial utilizes a processing system in which people who shop must sign up as members. The coding is written so it is not a nuisance for customers to sign up as they check out. The code should be easily understood and editable so customers do not have to sign up before purchasing. I did this because I have found it more convenient for customers to store their information, and its more secure as it only uses one address for both billing and shipping.
This part of the tutorial deals with setting up your database and signing up members.
| Section 1 - Database Layout |
For the sake of making this tutorial pretty comprehensive, I am going to give a fairly large database example. There are some extraneous columns in the product table that aren't necessary for the shopping cart system to work, but it will make your site be organized in many ways.
The database I'm describing here is a Microsoft Access 2000 database with 3 tables: LCustomers, LProducts, and LOrders.
Below is the LCustomers table, which holds all the customer information so they can log-in and place orders.
| LCustomers | |||
| # | Column Name | Type | Description |
| 1. | c_id | AutoNumber | Unique id number |
| 2. | c_fname | Text | First name |
| 3. | c_lname | Text | Last name |
| 4. | c_street | Text | Street address |
| 5. | c_city | Text | City |
| 6. | c_state | Text | State |
| 7. | c_zip | Number | Zip/Postal Code |
| 8. | c_phone | Text | Phone number |
| 9. | c_email | Text | E-mail address |
| 10. | username | Text | Username (I set it to equal the e-mail) |
| 11. | password | Text | Selected password |
| 12. | cc_type | Text | Credit Card Type (AmEx, Visa, etc.) |
| 12. | cc_num | Number or Text | 15-digit Credit Card Number |
| 13. | cc_verify | Number | Credit Card Verification Code (CVV2) - usually needed |
| 14. | cc_expir_m | Number | Expiration month as a number |
| 15. | cc_expir_y | Number | Expiration year as a number |
Please note: you should not use "username" and "password" as database fields, but for a matter of simplicity I used them here.
Below is the LProducts table, which holds all of the products that will be for sale on your site.
| LProducts | |||
| # | Column Name | Type | Description |
| 1. | p_id | AutoNumber | Unique id number |
| 2. | p_name | Text | Product name |
| 3. | p_type | Text | Type of product. This would be something like category (i.e. Electronics). |
| 4. | p_brand | Text | Brand name of the product |
| 5. | p_price | Currency | The price of the item |
Below is the LOrders table, which holds all of the order information when it is processed by your site.
| LOrders | |||
| # | Column Name | Type | Description |
| 1. | o_id | AutoNumber | Unique id number |
| 2. | o_cust | Number | Customer number - Unique ID number from LCustomers table |
| 3. | o_items | Memo | All of the items added in an order - inserted as a list |
| 4. | o_date | Date/Time | Date and time of order - put Now() as default value for this field |
| 5. | o_total | Currency | The total price of the order |
Ok, now that you're database is all set up (the easy part), we can move onto the actual coding of the site, starting with the Member sign up page. If you don't plan on using the member system, you can skip through here.
| Section 2 - Member Sign Up |
These are the scripts to sign up the members to your site. This will be expanded on in the Checkout section of the tutorial, but for now you just need the scripting.
<tr style="background-color:#FFFFFF;">
<td>First Name:</td>
<td><input type="text" name="c_fname" value=""></td>
</tr>
<tr style="background-color:#FFFFFF;">
<td>Last Name:</td>
<td><input type="text" name="c_lname" value=""></td>
</tr>
<tr style="background-color:#FFFFFF;">
<td>Address:</td>
<td><input type="text" name="c_street" value=""></td>
</tr>
<tr style="background-color:#FFFFFF;">
<td>City:</td>
<td><input type="text" name="c_city" value=""></td>
</tr>
<tr style="background-color:#FFFFFF;">
<td>State:</td>
<td><input type="text" name="c_state value=""></td>
</tr>
<tr style="background-color:#FFFFFF;">
<td>Zip:</td>
<td><input type="text" name="c_zip" value="" OnKeyPress="if(((event.keyCode < 48) || (event.keyCode > 57))) event.returnValue = false;"></td>
</tr>
<tr style="background-color:#FFFFFF;">
<td>Phone:</td>
<td><input type="text" name="c_phone" value=""></td>
</tr>
<tr style="background-color:#FFFFFF;">
<td>E-mail:<br><div style="font-weight:normal;font-size:8pt;">Will Be Your User Name</div></td>
<td><input type="text" name="c_email" value=""></td>
</tr>
<tr style="background-color:#FFFFFF;">
<td>Password:</td>
<td><input type="password" name="password" value=""></td>
</tr>
<tr style="background-color:#EEEEEE;">
<td colspan="2" style="font-weight:normal;font-size:9pt;border-bottom:1px solid #DDDDDD;">Optional Credit Card Information</td>
</tr>
<tr style="background-color:#EEEEEE;">
<td>Type:</td>
<td><select name="cc_type">
<option selected value="">Select Credit Card</option>
<option value="American Express">American Express</option>
<option value="Visa">Visa</option>
<option value="MasterCard">MasterCard</option>
</select>
</td>
</tr>
<tr style="background-color:#EEEEEE;">
<td>Number:</td>
<td><input type="text" name="cc_num" value="" OnKeyPress="if(((event.keyCode < 48) || (event.keyCode > 57))) event.returnValue = false;" maxlength="15"></td>
</tr>
<tr style="background-color:#EEEEEE;">
<td>CVV2</td>
<td><input type="text" name="cc_verify" value="" OnKeyPress="if(((event.keyCode < 48) || (event.keyCode > 57))) event.returnValue = false;"></td>
</tr>
<tr style="background-color:#EEEEEE;">
<td>Expiration:<div style="font-weight:normal;font-size:8pt;">(mm/yy)</td>
<td><input type="text" name="cc_expir_m" size="4" value="" maxlength="2" OnKeyPress="if(((event.keyCode < 48) || (event.keyCode > 57))) event.returnValue = false;"> <input type="text" name="cc_expir_y" size="4" value="" maxlength="4" OnKeyPress="if(((event.keyCode < 48) || (event.keyCode > 57))) event.returnValue = false;"></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Sign Up"> <input type="reset" value="Clear"></td>
</tr>
</table>
</form>
I'm rushing through this part. This is nowhere near the crux of the tutorial, and, if you're reading this tutorial and can comprehend it, this should all be pretty self-explanatory to you. It is just the form coding with some javascript to prevent unwanted entries (numbers and letters).
Below is the coding to add the customer into the database.
<script>
alert("Please enter your first name.");
self.location="Javascript:history.go(-1)";
</script>
</cfif>
<cfif form.c_lname EQ "">
<script>
alert("Please enter your last name.");
self.location="Javascript:history.go(-1)";
</script>
</cfif>
<cfif form.c_street EQ "">
<script>
alert("Please enter your street address.");
self.location="Javascript:history.go(-1)";
</script>
</cfif>
<cfif form.c_city EQ "">
<script>
alert("Please enter your city.");
self.location="Javascript:history.go(-1)";
</script>
</cfif>
<cfif form.c_state EQ "">
<script>
alert("Please select your state.");
self.location="Javascript:history.go(-1)";
</script>
</cfif>
<cfif form.c_zip EQ "">
<script>
alert("Please enter your zip code.");
self.location="Javascript:history.go(-1)";
</script>
</cfif>
<cfif form.c_phone EQ "">
<script>
alert("Please enter your phone number.");
self.location="Javascript:history.go(-1)";
</script>
</cfif>
<cfif form.c_email EQ "">
<script>
alert("Please enter your e-mail address.");
self.location="Javascript:history.go(-1)";
</script>
</cfif>
<cfif form.password EQ "">
<script>
alert("Please enter a password.");
self.location="Javascript:history.go(-1)";
</script>
</cfif>
<cfif form.c_fname NEQ "" and form.c_lname NEQ "" and form.c_street NEQ "" and form.c_city NEQ "" and form.c_state NEQ "" and form.c_zip NEQ "" and form.c_phone NEQ "" and form.c_email NEQ "" and form.password NEQ "">
<cfquery name="DupCheck" datasource="test">
SELECT c_email
FROM LCustomers
WHERE c_email = '#form.c_email#'
</cfquery>
<cfif DupCheck.recordCount GT "0">
<script>
alert("That e-mail address is already registered.");
self.location="Javascript:history.go(-1)";
</script>
<cfelse>
<cfif Not IsDefined('form.cc_type')><cfset form.cc_type EQ ""></cfif>
<cfif Not IsDefined('form.cc_num')><cfset form.cc_num EQ ""></cfif>
<cfif Not IsDefined('form.cc_expir_m')><cfset form.cc_expir_m EQ ""></cfif>
<cfif Not IsDefined('form.cc_expir_y')><cfset form.cc_expir_y EQ ""></cfif>
<cfif Not IsDefined('form.cc_verify')><cfset form.cc_verify EQ ""></cfif>
<cfquery name="AddMember" datasource="test">
INSERT INTO LCustomers (c_fname, c_lname, c_street, c_city, c_state, c_zip, c_email, username, password, cc_type, cc_num, cc_verify, cc_expir_m, cc_expir_y, c_phone)
VALUES ('#form.c_fname#','#form.c_lname#', '#form.c_street#', '#form.c_city#', '#form.c_state#', '#form.c_zip#', '#form.c_email#', '#form.c_email#', '#form.password#', '#form.cc_type#', '#form.cc_num#', '#form.cc_verify#','#form.cc_expir_m#', '#form.cc_expir_y#', '#form.c_phone#')
</cfquery>
<!--- Mail Information to User --->
<cfmail
from="newmember@yoursite.com"
to="#form.c_email#"
subject="Thank you for signing up." type="html">
<html>
<head>
<style type="text/css">
Body, table, td {font-family:Arial;font-size:9pt;color;##000000;}
</style>
</head>
<body>
Thank You For Signing Up<br>
Dear #form.c_fname# #form.c_lname#,<br>
Thank you for signing up with Your Company.
Your username and password are below. Be sure to write them down for future reference.<p>
<b>Username:</b> #form.c_email#<br>
<b>Password:</b> #form.password#<p>
Thank you for signing up and we sincerely appreciate your business.
</body>
</html>
</cfmail>
Thank you for signing up. Your details have been e-mailed to you.
</cfif>
</cfif>
This too is pretty self explanatory for an intermediate programmer. It error checks at the beginning to make sure the required fields are entered. If the fields that aren't required are blank it sets them to "". It then adds the user information into the database. Notice that it sets the username to be the e-mail address. Finally, the new user has their information e-mailed to them.
This is the MAIN part of the tutorial. This is where we set up our shopping cart and learn how to add products into it.
| Section 3 - Main Shopping Cart Page |
Coding a shopping cart really is not very hard at all. All you need is knowledge of arrays and structures and you're ready to go. I will first show all the scripting for this part and then describe each part of the coding in more detail.
Your shopping cart is currently empty.
<cfelse>
<cfset totalItems = 0>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfset totalItems = variables.totalItems + session.shoppingcart[i].quantity>
</cfloop>
<cfif totalItems EQ 0>
Your shopping cart is currently empty.
<cfelse>
<p>
<table width="90%" align="center" border="0" cellpadding="2" cellspacing="0" style="border:2px solid #DDDDDD;">
<tr>
<td colspan="7" style="font-weight:bold;font-size:11pt;background-color:#DDDDDD">Items in Shopping Cart</td>
</tr>
<tr>
<td><b>#</b></td><td><b>Product</b></td><td><b>Size</b></td><td><b>Unit Price</b></td><td><b>Quantity</b></td><td><b>Total</b></td><td><b>Action</b></td>
</tr>
<cfoutput>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfset total[i] = session.shoppingcart[i].price * session.shoppingcart[i].quantity>
<tr style="background-color:##<cfif i MOD 2>EFEFEF<cfelse>FFFFFF</cfif>;">
<td>#i#</td>
<td>#session.shoppingcart[i].name#</td>
<td>#session.shoppingcart[i].size#</td>
<td>#DollarFormat(session.shoppingcart[i].price)#</td>
<td>#session.shoppingcart[i].quantity#</td>
<td>#DollarFormat(total[i])#</td>
<td><a href="delete_item.cfm?id=#i#">Remove Item</a></td>
</tr>
</cfloop>
</cfoutput>
<cfset totalprice = 0>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfset totalprice = variables.totalprice + total[i]>
</cfloop>
<tr style="background-color:#DDDDDD;">
<td> </td><td> </td><td> </td><td> </td><td> </td><td><b><cfoutput>#DollarFormat(variables.totalprice)#</cfoutput></b></td><td><a href="checkout.cfm"><b>Checkout</b></a></td>
</tr>
</table>
<p>
You currently have <cfoutput><strong>#variables.totalItems#</strong></cfoutput> <cfif variables.totalItems EQ 1>item<cfelse>items</cfif> in your cart.<br>
<a href="checkout.cfm"><b>Proceed to Checkout >></b></a><p>
<a href="clear_cart.cfm">Clear Shopping Cart</a>
</cfif>
</cfif>
See, it's not so bad at all. Very little coding. Now to the explanations:
<cfif IsDefined('session.shoppingcart') is "NO">
Your shopping cart is currently empty.
<cfelse>
This part simply sees if a shopping cart is defined. If it isn't, then you tell the user that their shopping cart is empty.
<cfelse>
<cfset totalItems = 0>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfset totalItems = variables.totalItems + session.shoppingcart[i].quantity>
</cfloop>
<cfif totalItems EQ 0>
Your shopping cart is currently empty.
<cfelse>
Now, we do a loop. Since we have already discovered that a shopping cart exists, we loop through to see what products we have in there. This part is from CJ's tutorial and he explains it well there. If it turns out our shopping cart exists, but the user deleted all the items, it again tells the user the shopping cart is empty.
Now, if the user has products in their cart, we show everything to them.
<cfoutput>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfset total[i] = session.shoppingcart[i].price * session.shoppingcart[i].quantity>
<tr style="background-color:##<cfif i MOD 2>EFEFEF<cfelse>FFFFFF</cfif>;">
<td>#i#</td>
<td>#session.shoppingcart[i].name#</td>
<td>#session.shoppingcart[i].size#</td>
<td>#DollarFormat(session.shoppingcart[i].price)#</td>
<td>#session.shoppingcart[i].quantity#</td>
<td>#DollarFormat(total[i])#</td>
<td><a href="delete_item.cfm?id=#i#">Remove Item</a></td>
</tr>
</cfloop>
</cfoutput>
This code comes after we format our table. We loop through our shopping cart and display all of the information. We set the price for the total for each item determined by its price and quantity (total[i]), and then display all the information. We use the "DollarFormat" function to put a dollar sign before the price and limit the decimal places to two.
<cfset totalprice = 0>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfset totalprice = variables.totalprice + total[i]>
</cfloop>
<tr style="background-color:#DDDDDD;">
<td> </td><td> </td><td> </td><td> </td><td> </td><td><b><cfoutput>#DollarFormat(variables.totalprice)#</cfoutput></b></td><td><a href="checkout.cfm"><b>Checkout</b></a></td>
Now we determine the total price of all of the items in the shopping cart to display to the user. We loop through the cart and keep adding the total[i] prices we determined in earlier coding until we reach the end of our cart. Then you see we display it again using the DollarFormat function.
The end of the coding just displays the total products that we calculated earlier.
Now, as you might have noticed, there is a link that says "Remove Item" when our products are displayed in the shopping cart. When the user clicks this, it deletes the item from the shopping cart array. Below is the coding.
<script>
self.location="cart.cfm";
</script>
Very simple. It uses the ArrayDeleteAt function to remove the item from the cart. It uses the variable passed from the product display page to know which item to remove. Then, we use a quick script to forward the user back to the cart.
You probably also notice the "Clear Cart" link. This is similar to the "Remove Item" link, but clears out the entire cart.
ArrayClear(session.shoppingcart);
</cfscript>
<script>
self.location="cart.cfm";
</script>
As you can see, we don't delete the items, actually. We clear out the entire array that is session.shoppingcart. This is the easiest and most efficient way. We don't want to clear the entire session structure, because the user may be logged in and that would log them out. Keep that in mind with your "logout" script for your site. Just because a user logs out doesn't mean he wants to clear out his shopping cart. They may want to log in under another account.
Phew, ok, that was the hard part. And it wasn't too bad at all. If you look closely at the coding you will definitely be able to understand all of it, no matter what your level of ColdFusion knowledge. As you can see, its apparent that we set all of those structure values earlier inside our shopping cart (which is our main array). Now, you may be thinking, when is our cart defined? and, when is that information added for each product? Well, that all happens in our very next section!
| Section 4 - Product Display - "Add to Cart" |
Before we add the product to the shopping cart, we have to show our products to our user. This is just a basic display script that gets all of the products from the database. Of course, you can use the different columns in your products table to only show certain items.
SELECT *
FROM LProducts
ORDER BY p_name ASC
</cfquery>
<table border=0 width="100%" cellpadding="2" cellspacing="0">
<tr>
<td><b>Product</b></td><td><b>Price</b></td><td><b>Quantity</b></td>
</tr>
<cfoutput query="getProds">
<form name="Add#getProds.p_id#" action="addtocart.cfm" method="post">
<tr style="background-color:##<cfif currentrow MOD 2>EFEFEF<cfelse>FFFFFF</cfif>;">
<td>#getProds.p_name#</td>
<td>#DollarFormat(getProds.p_price)#</td>
<td><input type="hidden" name="id" value="#getProds.p_id#">
<input type="hidden" name="name" value="#getProds.p_name#">
<input type="hidden" name="p" value="#getProds.p_price#">
<input type="text" name="qnt" value="1" OnKeyPress="if(((event.keyCode < 48) || (event.keyCode > 57))) event.returnValue = false;" maxlength="3"> <input type="submit" value="Add to Cart">
</td>
</tr>
</form>
</cfoutput>
</table>
This is very simple coding. We first query the database for all of our products and then sort them by name. Then, we set up a form for each product by giving each form a name that is "Add" and then the product ID number - making each form unique. We then simply output all of the information about our product we want the customer to see. You'll notice there are a few hidden values. These are used to pass variables that we need when the product is added to the shopping cart. The product name, price, and quantity are all added. Quantity is input by the user and they can change the default value of 1.
<cfset session.shoppingcart = arrayNew(1)>
</cfif>
<cfset newitem = 0>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfif session.shoppingcart[i].productid EQ #form.id#>
<cfset session.shoppingcart[i].quantity = session.shoppingcart[i].quantity + #form.qnt#>
<cfset newitem = 1>
<cfbreak>
</cfif>
</cfloop>
<cfif newitem EQ 0>
<cfset temp = arrayAppend(session.shoppingcart, structNew())>
<cfset session.shoppingcart[arrayLen(session.shoppingcart)].productID = #form.id#>
<cfset session.shoppingcart[arrayLen(session.shoppingcart)].name = #form.name#>
<cfset session.shoppingcart[arrayLen(session.shoppingcart)].quantity = #form.qnt#>
<cfset session.shoppingcart[arrayLen(session.shoppingcart)].price = #form.p#>
</cfif>
<script>
self.location="cart.cfm";
</script>
This page goes hand-in-hand with the cart.cfm page. This is where we get all of our products to display! After the user clicks the "Add to Cart" button, this script actually puts the product and all of its contents as a new structure into our shopping cart aray.
The first thing it does is check to see if a shopping cart array exists. If not, it creates that new array.
Then, it loops over our cart and checks to see if that product is already in the shopping cart, using its ID number as a reference. If the product is in fact in the cart, it adds the quantity number as entered on the product display page to the current quantity inside the cart.
Using a variable called "newitem" it checks to see if we already updated the quantity of an existing product. If not, we have to add this product to the cart. We set up our new structure and insert all of the new values into their positions. You'll see that the new product number is designated by using the arrayAppend function, creating a free position for our new product to be entered. This adds a new spot at the end of the array for our product to be entered.
Finally, we send the user to cart.cfm so they can see they're cart with its new quantity or new products.
Now that we have our products in the cart, there's only one thing left to do... make those people pay! You'll notice the cart.cfm page has links to checkout.cfm.
This part of the tutorial deals with having the customer check out and process their order. Additionally, it contains special code snippets that you will find helpful and will want to revert back to as you build your shopping cart.
| Section 5 - Checkout - Order Processing |
Now our customers have products in their cart and they're ready to submit their order. So, there are a number of things we have to do. Firstly, we have to check to see if our customer is logged in. If they're not, we have to give them the option to log in. If they don't have an account, we give them the option to sign up. Here is our checkout.cfm page:
<table cellpadding="3" cellspacing="0" border="0" align="center" width="100%">
<tr>
<td valign="top">
<div>Customer Sign In</div>
<form name="CustSignIn" action="checkout_signin.cfm" method="post">
<table width="350" border="0" align="center" cellspacing="0" cellpadding="5" style="font-weight:bold;border:2px solid #DDDDDD;">
<tr>
<td><b>E-mail Address:</b></td>
<td><input type="text" name="username" value="" size="25"></td>
</tr>
<tr>
<td><b>Password:</b></td>
<td><input type="password" name="password" value="" size="25"></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Sign In"></td>
</tr>
</table>
</form>
</td>
<td>
<div>New Customer Sign Up</div>
*****SAME FORM AS ABOVE SIGN UP PAGE*****
</td>
</tr>
</table>
<cfelse>
<script>
self.location="confirmorder.cfm";
</script>
</cfif>
So what we do in this file is first check to see if the user is logged in (session.allowin). If they are not, we show them our page. Our page gives them the option to log in or sign up a new account. Notice how it is not inconvenient to sign up a new account. The user can simply sign up just as if it were a normal checkout (without membership). The only difference is they have to choose a password.
At the bottom of the page, we see the <cfelse> tag that is finishing off the initial cfif tag checking if our customer is logged in. If they ARE logged in, we forward them to our next page, confirmorder.cfm.
You must sign in before your order can be confirmed.
<cfelse>
<cfquery name="logMem" datasource="test">
SELECT *
FROM LCustomers
WHERE username = '#session.username#'
</cfquery>
<cfif logMem.cc_type EQ "">
You do not have a credit card on file.
<cfelseif logMem.cc_num EQ "">
You do not have a credit card number on file.
<cfelseif logMem.cc_expir_m EQ "">
You do not have sufficient credit card information on file.
<cfelseif logMem.cc_expir_y EQ "">
You do not have sufficient credit card information on file.
<cfelse>
<cfquery name="logMem" datasource="test">
SELECT *
FROM LCustomers
WHERE username = '#session.username#'
</cfquery>
<cfinclude template="ordertotals.cfm">
<div>Order Confirmation</div>
<div style="font-size:8pt;">
Your order information is outlined below. To process this order, please click the button below. The expenses will be charged to the credit card listed on file.<br>
<form name="ConfirmOrder" action="processorder.cfm" method="post">
<input type="submit" value="Click Here to Process This Order">
</form>
</div>
<cfoutput>
<table width="320" border="0" cellpadding="3" cellspacing="0" style="border:2px solid ##DDDDDD;font-size:8pt;">
<tr>
<td colspan="2" style="font-size:11pt;font-weight:bold;background-color:##DDDDDD;">Customer Information</td>
</tr>
<tr style="background-color:##FFFFFF;">
<td valign="top"><b>Customer Name</b>:</td><td>#logMem.c_fname# #logMem.c_lname#</td>
</tr>
<tr style="background-color:##FFFFFF;">
<td valign="top"><b>Address</b>:</td><td>#logMem.c_street#<br>#logMem.c_city#, #logMem.c_state# #logMem.c_zip#</td>
</tr>
<tr style="background-color:##FFFFFF;">
<td valign="top"><b>Credit Card:</b></td><td>#logMem.cc_type#<br>xxxx-xxxx-xxxx-#Right(logMem.cc_num,4)#</td>
</tr>
</table>
</cfoutput><br>
<table width="90%" border="0" align="center" cellpadding="2" cellspacing="0" style="border:2px solid #DDDDDD;">
<tr>
<td colspan="6" style="font-size:11pt;font-weight:bold;background-color:#DDDDDD;">Order Breakdown</td>
</tr>
<tr>
<td><b>#</b></td><td><b>Product</b></td><td><b>Size</b></td><td><b>Unit Price</b></td><td><b>Quantity</b></td><td><b>Total</b></td>
</tr>
<cfoutput>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfset total[i] = session.shoppingcart[i].price * session.shoppingcart[i].quantity>
<tr style="background-color:##<cfif i MOD 2>EFEFEF<cfelse>FFFFFF</cfif>;">
<td>#i#</td>
<td>#session.shoppingcart[i].name#</td>
<td>#session.shoppingcart[i].size#</td>
<td>#DollarFormat(session.shoppingcart[i].price)#</td>
<td>#session.shoppingcart[i].quantity#</td>
<td>#DollarFormat(total[i])#</td>
</tr>
</cfloop>
</cfoutput>
<tr style="background-color:#DDDDDD;font-size:9pt;">
<td colspan="6" align="right">
Subtotal: <cfoutput>#DollarFormat(variables.subtotal)#</cfoutput><br>
<cfif logMem.c_state EQ "FL">
Tax: <cfoutput>#DollarFormat(variables.tax)#</cfoutput>
</cfif>
Shipping:<cfoutput>#DollarFormat(variables.shipping)#</cfoutput>
<b>Order Total: <cfoutput>#DollarFormat(variables.totalprice)#</cfoutput></b></td>
</tr>
</table><p>
Total Items in Order: <cfoutput>#variables.totalItems#</cfoutput><br>
<b>Order Total: <cfoutput>#DollarFormat(variables.totalprice)#</cfoutput></b>
</cfif>
</cfif>
This page is slightly complex, but not too bad once we look into it. We start off doing some error checking. First, we check to see if the user is logged in. We don't want someone who hasn't logged in stumbling upon this page. You can use this snippet on all of the order processing pages. Then, we check to make sure we have all the credit card information we need after making a database query to get the session user information. If we don't, the user cannot move forward and process their order. If the user passes all the tests, they can then move on to the next part of the coding.
We then do a virutally identical loop to the one in our cart.cfm page. We find and display all of the products in the user's shopping cart. Next, several variables are displayed regarding the order: the subtotal, tax, shipping, and the combined total. Now, you may be wondering, where do all these variables come from? Well, if you notice the <cfinclude> tag, that is your answer. In the page ordettotals.cfm we create several variables that we need on this page and the processing page subsequent to this one. Below is the ordertotals page:
<cfset total[i] = session.shoppingcart[i].price * session.shoppingcart[i].quantity>
</cfloop>
<cfset totalprice = 0>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfset totalprice = variables.totalprice + total[i]>
<cfset subtotal = variables.totalprice>
</cfloop>
<cfset shipping = variables.totalprice * .1>
<cfif logMem.c_state EQ "FL">
<cfset tax = variables.totalprice * .06>
<cfset fulltotal = variables.totalprice + variables.shipping + variables.tax>
<cfset totalprice = variables.fulltotal>
<cfelse>
<cfset fulltotal = variables.totalprice + variables.shipping>
<cfset totalprice = variables.fulltotal>
</cfif>
<cfset totalItems = 0>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfset totalItems = variables.totalItems + session.shoppingcart[i].quantity>
</cfloop>
We set a few variables on this page: total price per item, total price, shipping price, tax (if applicable), and the fulltotal.
Like in our cart, we loop through to find the price of each item. Then, like before, we add up the prices to get our subtotal. Next, we figure out the shipping. Here, it is configured as 10%. This page is helpful because if you ever want to change the shipping right, the only place you have to change it is here.
A commonly disregarded item is the tax. On the Internet, the only time you ahev to charge tax is when it is an intrastate purchase (within the selling state). In this case, the homestate is Florida (make sure you use a select box in the sign up page to guarantee the state is input as "FL" to maintain consistency. In Florida, sales tax is 6%. Depending on whether or not the customer is in our home state, it sets the next 2 varibales: totalprice, and fulltotal. Full total is the total item price + the shipping price + the tax price (if necessary). You see the cfif tag is used to determine whether or not tax is to be added.
Lastly, we figure out the total items in the cart. You should recognize this code from the cart.cfm page.
Now, the last, and possibly most important part - processing the order.
You must be logged in to view this area.
<cfelse>
<cfquery name="logMem" datasource="test">
SELECT *
FROM LCustomers
WHERE username = '#session.username#'
</cfquery>
<cfinclude template="ordertotals.cfm">
<!--- Insert into Orders Database --->
<cfquery name="addOrder" datasource="test">
INSERT INTO LOrders (o_cust, o_total, o_items)
VALUES ('#logMem.c_id#','#variables.totalprice#', '<cfoutput><cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i"><cfif i eq arrayLen(session.shoppingcart)>#session.shoppingcart[i].name#<cfelse>#session.shoppingcart[i].name#, </cfif></cfloop></cfoutput>')
</cfquery>
<!--- E-mail order to Administration --->
<cfmail
from="order@yoursite.com"
to="CustomerService@yoursite.com"
subject="YourSite.com - Order" type="html">
<html>
<head>
<style type="text/css">
Body, table, td {font-family:Arial;font-size:9pt;color:##000000;}
</style>
</head>
<body>
<div>Order To Be Processed</div>
<table width="350" border="0" cellpadding="3" cellspacing="0" style="border:2px solid ##DDDDDD;font-size:8pt;">
<tr style="background-color:##EFEFEF;">
<td><b>Date/Time:</b></td><td>#DateFormat(now(), 'mm/dd/yyyy')# #TimeFormat(Now(), 'hh:mm tt')#</td>
</tr>
<tr style="background-color:##FFFFFF;">
<td valign="top"><b>Customer Name</b>:</td><td>#logMem.c_fname# #logMem.c_lname#</td>
</tr>
<tr style="background-color:##EFEFEF;">
<td valign="top"><b>Address</b>:</td><td>#logMem.c_street#<br>#logMem.c_city#, #logMem.c_state# #logMem.c_zip#</td>
</tr>
<tr style="background-color:##FFFFFF;">
<td valign="top"><b>Credit Card:<br>Number:<br>CVV2:<br>Expiration:</b></td>
<td>#logMem.cc_type#<br>#logMem.cc_num#<br>#logMem.cc_verify#<br>#logMem.cc_expir_m#/#logMem.cc_expir_y#</td>
</tr>
</table><br><br>
<table width="90%" border="0" align="center" cellpadding="2" cellspacing="0" style="border:2px solid ##DDDDDD;">
<tr>
<td colspan="6" style="font-size:11pt;font-weight:bold;background-color:##DDDDDD;">Order Breakdown</td>
</tr>
<tr>
<td><b>Item</b></td><td><b>Product</b></td><td><b>Size</b></td><td><b>Unit Price</b></td><td><b>Quantity</b></td><td><b>Total</b></td>
</tr>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfset total[i] = session.shoppingcart[i].price * session.shoppingcart[i].quantity>
<tr style="background-color:##<cfif i MOD 2>EFEFEF<cfelse>FFFFFF</cfif>;">
<td>#session.shoppingcart[i].productID#</td>
<td>#session.shoppingcart[i].name#</td>
<td>#session.shoppingcart[i].size#</td>
<td>#DollarFormat(session.shoppingcart[i].price)#</td>
<td>#session.shoppingcart[i].quantity#</td>
<td>#DollarFormat(total[i])#</td>
</tr>
</cfloop>
<tr>
<td colspan="6" style="font-size:11pt;font-weight:bold;background-color:##DDDDDD;" align="right">
<div style="font-size:9pt;">
<b>Subtotal</b>: #DollarFormat(variables.subtotal)#<br>
<cfif logMem.c_state EQ "FL">
Tax: #DollarFormat(variables.tax)#<br>
</cfif>
<b>Shipping</b>: #DollarFormat(variables.shipping)#</div>
Order Total: #DollarFormat(variables.totalprice)#</td>
</tr>
</table>
</body>
</html>
</cfmail>
<!--- E-mail order to customer --->
<cfmail
from="order@yoursite.com"
to="#logMem.c_email#"
subject="YourSite.com - Thank You for Your Order" type="html">
********SIMILAR E-MAIL BODY TO ABOVE & BELOW (DO NOT USE CFOUTPUT TAGS)********
</cfmail>
<!--- Show Order Information page to Customer --->
<div>Order Information</div>
Your order has been processed. This information has been e-mailed to <b><cfoutput query="logMem">#logMem.c_email#</cfoutput></b>.
<br>Please print this page for your records.<p>
<table width="250">
<tr>
<td valign="top"><b>Customer Name</b>:</td><td><cfoutput query="logMem">#logMem.c_fname# #logMem.c_lname#</cfoutput></td>
</tr>
<tr>
<td valign="top"><b>Address</b>:</td><td><cfoutput query="logMem">#logMem.c_street#<br>#logMem.c_city#, #logMem.c_state# #logMem.c_zip#</cfoutput></td>
</tr>
<tr>
<td valign="top"><b>Credit Card:</b></td><td><cfoutput query="logMem">#logMem.cc_type#<br>xxxx-xxxx-xxxx-#Right(logMem.cc_num,4)#</cfoutput></td>
</tr>
</table><br><br>
<table width="90%" border="0" align="center" cellpadding="2" cellspacing="0" style="border:2px solid #DDDDDD;">
<tr>
<td><b>#</b></td><td><b>Product</b></td><td><b>Size</b></td><td><b>Unit Price</b></td><td><b>Quantity</b></td><td><b>Total</b></td>
</tr>
<cfoutput>
<cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i">
<cfset total[i] = session.shoppingcart[i].price * session.shoppingcart[i].quantity>
<tr style="background-color:##<cfif i MOD 2>EFEFEF<cfelse>FFFFFF</cfif>;">
<td>#i#</td>
<td>#session.shoppingcart[i].name#</td>
<td>#session.shoppingcart[i].size#</td>
<td>#DollarFormat(session.shoppingcart[i].price)#</td>
<td>#session.shoppingcart[i].quantity#</td>
<td>#DollarFormat(total[i])#</td>
</tr>
</cfloop>
</cfoutput>
<tr style="background-color:#DDDDDD;font-size:11pt;">
<td colspan="6" align="right">
<div style="font-size:9pt;">
Subtotal: <cfoutput>#DollarFormat(variables.subtotal)#</cfoutput><br>
<cfif logMem.c_state EQ "FL">
Tax: <cfoutput>#DollarFormat(variables.tax)#</cfoutput><br>
</cfif>
Shipping: <cfoutput>#DollarFormat(variables.shipping)#</cfoutput></div>
<b>Order Total: <cfoutput>#DollarFormat(variables.fulltotal)#</cfoutput></b></td>
</tr>
</table><br>
<div align="left">
<a href="Javascript:window.print();">Print This Page</a></div>
<cfscript>
ArrayClear(session.shoppingcart);
</cfscript>
</cfif>
Ok, that was a long one, but pretty simple, and by now, it should mostly be familiar to you. We start off by checking if the user's logged in. Then, we do our query to get all our user information and include the ordertotals.cfm page to get our variables for use again.
<cfquery name="addOrder" datasource="test">
INSERT INTO LOrders (o_cust, o_total, o_items)
VALUES ('#logMem.c_id#','#variables.totalprice#', '<cfoutput><cfloop from="1" to="#arrayLen(session.shoppingcart)#" index="i"><cfif i eq arrayLen(session.shoppingcart)>#session.shoppingcart[i].name#<cfelse>#session.shoppingcart[i].name#, </cfif></cfloop></cfoutput>')
</cfquery>
Now we add our order into our database table. This should all be familiar to you, with perhaps the exception of the loop. We look over our shopping cart one more time. This time, we output our item names as a comma delimited list. Look closely to understand precisely how the list is created.
At this point, we just have 3 things left to do: send the e-mail to ourselves to process it, send the e-mail to our customer as confirmation, and show the order confirmation page to the customer on our site after they process their order. There is nothing new in the code with the exception of the Right() function. This simply gets the 4 last digits of the customer's credit card number and displays it to them with Xs for the first 11 digits.
Our order information table is formatted just like on the cart.cfm page and the confirmorder.cfm page. By this point, you should have that loop over our shopping cart array virtually memorized. You see we again show all of our variables back to the user and input them in our e-mails. In your e-mail to your customer, use the Right() function for the credit card, just for security.
Sending an e-mail is of course just one way to process your order. This is assuming each order is processed by hand. You can of course use all differenet kinds of processing (online merchant processing, PayPal, sending the order via FTP to another computer). No matter what you do, it's all the same concept and you can use the same output coding.
Well, that is all there is to an e-commerce system with a fully functional shopping cart.

0 responses to “E-Commerce in Cold Fusion”