Custom Woocommerce Extensions

Woocommerce was made with extensions in mind! While it is quite powerful out of the box, there is so much more than you can do with it through extensions.

Although there are plenty of great extensions available for Woocommerce, you may still find that you need a custom solution.

Here’s a quick list of some of the things I’ve done with Woocommerce:

  • Custom registration and checkout fields
  • Admin approval system for site registrations through Woocommerce, to control access to sensitive areas
  • Custom Woocommerce reports
  • Pre-Order messages and ordering options
  • Wholesale pricing & ordering system
  • Custom tax settings and price display setting for different user roles
  • Role & User based pricing systems
  • Large # of product CSV importing system (direct to database, bypassing slow WordPress functions)
  • Custom attributes/meta table system for products for faster searches/filtering
  • Cascading AJAX product filter widget
  • Custom order statuses and actions
  • Custom payment gateways (quote, purchase order, etc.) and actions
  • Custom shipping gateways and actions
  • Custom email classes and templates
  • Removal/replacement of Woocommerce text, sales flash messages, etc.
  • Quick/Bulk edit actions for custom fields
  • Enable/Disable taxes, shipping, payment, & coupons by role or user
  • Custom columns on products & orders list pages

My Personal Experience with Woocommerce

For the last few years, it seems that I have been through every piece of Woocommerce code several times! I started using Woocommerce for my son’s school PTA web site a few years back, using it to register parents and their students through some additional fields I added to the checkout page. I expanded that to include a “pending” type of registration/membership status, and a special report page where PTA chair people could review and approve or deny people for parent level access to our school site (protecting any possible student info from the general public). We also used Woocommerce for selling fundraising items, and I custom programmed a “Classroom Delivery” option for Woocommerce products, which generated a student name and class/teacher field on the checkout form, and then created nice classroom delivery reports on the admin side to make delivery of these items very simple.

After that experience, I expanded on that knowledge to create a Wholesale Ordering extension for my wife’s cashmere site. Initially, I created a special one page order form for wholesale customers, but a lot of that had to be hard coded with her color and size attributes to create a nice grid input for color/size combinations. That didn’t turn out to work very well when she changed the way she entered products, and had too many products to fit on one form nicely. So, we ditched that part of the plugin, and made it so that Wholesale customers could browse the catalog the same way that retail customers could (which is what they were doing even when we had the form), and see the wholesale prices instead of retail prices. I have since added many more features to that plugin, and put in a lot more options to make it work better for a wider variety of sites, and then released the Wholesale Ordering extension to the public.

Since my wife is in the fashion business, and always working a couple of seasons in advance, she wanted some way to allow web customers to know which items were available for pre-order, with messages about when they would be delivered, and payment/shipping messages as well. So, I created the Pre-Order Messages extension. As usually, I added additional features and options to make it useful in a wider variety of situations before I released it to the public.

Next, I had a client in Germany who needed to change the way taxes were displayed and calculated for retail (B2C) versus wholesale (B2B) customers. That was a major upgrade to the Wholesale Ordering extension, and required some brute force methods to override the way Woocommerce determines how prices are displayed and how (and if) taxes are calculated.  In addition, I have been working on WPML compatibility as well as compatibility with the Germanized Woocommerce extension, for the same client. The tax and price display options have been already released, but the WPML compatibility will be released with version 2, due out very soon (April 2015). Thankfully, I have found a nicer work around for some of the tax settings that Woocommerce gets directly from the WordPress options table (with no filter hooks for easy modification), so that I have been able to greatly simplify my code and remove some of the brute force methods I included previously. The newer, simplified code will also be released with version 2, and that version will include hooks of its own so that my extension can be further extended by other plugins.

In the middle of working on version 2 of the Wholesale Ordering extension, I got recruited for a very large project for a Canadian auto-parts web site. The first part of that project was a “proof on concept”, just to see if WordPress & Woocommerce could handle somewhere around 200,000 products without slowing to a crawl. Once we figured out that it was possible to run that size of a store with WordPress & Woocommerce, we then had to figure out a practical way to import a very large number of products into the system from CSV files. Although there are plenty of CSV importer plugins available, most of them use WordPress functions to add the posts, postmeta, terms, taxonomies, etc. All of that is very slow. I let one of those importers run all night, and it only managed to import about 10,000 products before it crashed. The problem is that a single product in Woocommerce has data stored in many different database tables. If you want to do direct database table writing, you have to know some of the relationships between the tables ahead of time to get everything in the proper place, if you want to use the built-in taxonomy & terms system. We wrote our own custom function to import the auto parts from a CSV file and write them to the database in chunks of 1000 parts per table write. Our resulting importer could import 70,000 products in under 4 minutes. Then I wrote a separate CRON function that would process all the images for the parts in the background, processing 250 images every 15 minutes. All the client needed to do was upload the images via FTP, and my function would process them, creating all the various sizes WordPress & WooCommerce needed, move them images to the proper directory, and attach them to the proper products.

Our auto-parts client had several different types of customers with different pricing. Some of them got a percentage off of list (retail) price, while others got a certain percentage above cost. In addition, some of the customers of a certain type received a bigger discount than other customers of the same type, depending on how good of a customer they were. To handle that, I set up a custom pricing system using 2 prices imported from the CSV files. Each part has a retail price and a store cost. The system I set up lets the client choose the base price (retail or cost) for each user role (body shop, warehouse, etc.), and a multiplier value to apply to the base price. Then, I added the same fields to each user account as well, but with the added “default/role” setting. If the user’s price settings were set to default/role, they get the same pricing as anybody else with that role. If they are set to anything other than default/role, then the individual user’s settings are applied for that user. I also set it up so that the shop staff can quickly change the base price and multiplier they see with a widget that only appears for them, so they can quickly quote prices for customers of any type.

Once the big auto-parts job is finished, and I have a bit of time to get version 2 of the Woocommerce Wholesale Ordering plugin out, I plan on working on packaging up some of what we did for the auto parts store into stand alone plugins, such as the user/role based pricing system.