Fun with WooCommerce

One of my first big achievements as a software engineer was creating an e-commerce platform from scratch. It was only ever used on my clients’ sites, but it was pretty handy, helping small budding businesses process thousands of orders. It is still in use on a few sites today.

I recently helped a friend switch their site over to WordPress. Their old site was running my aging e-commerce system, so I assisted them in upgrading to WooCommerce. I found the experience to be quick and painless. Woo was everything I could ask for in an e-commerce platform: it’s free version has everything a small shop could ask for, and paid extensions are available if you need get more complex.  My friend was able to get by with just the free version.

As a developer, I found Woo very flexible. In just 2 hours, I was able to write a script that ported the past orders archived on my system into Woo. Here is a basic abstraction of how to programmatically add orders to Woo. Hope it helps if you ever need to do something similar.


      // This assumes that all of your archived orders were processed with paypal,
      // and that you've already entered your paypal settings in the WordPress admin area.
      $this->gateway = new WC_Gateway_Paypal();

      foreach ( $this->orders as $order ) {

         // This will generate a new WC_Order object which is a custom post type of shop_order.
         // Sets the status to completed, because I assume if you are importing orders into Woo
         // the orders have already been processed.
         $args      = array(
            'status' => 'completed',
         $woo_order = wc_create_order( $args );

         // A new WC_Order's date defaults to the current time.
         // Let's adjust it to the purchase date of your archived order.
         $this->set_date( $order->payment_date, $woo_order );
         // Adds billing / shipping address to the order
         $this->add_customer( $order, $woo_order );
         $this->add_items( $order, $woo_order );
         $num ++;
      echo '
      echo "$num orders created";
      echo "\n";
      print_r( $this->new_orders );
      echo '


public function set_orders() {
* Populate $this->orders with orders from your old system.
* Ideally, $this->orders should be an array of objects where
* each object contains all possible info about a past order.

* Sets the date of the new woo order to the old order’s purchase date
* @param $orginal_date – the original date of purchase in some human readable format
* @param $woo_order – the WC_Order object
public function set_date( $orginal_date, $woo_order ) {
$args = array(
‘ID’ => $woo_order->id,
‘post_date’ => date( ‘Y-m-d H:i:s’, strtotime( $orginal_date ) ),
‘post_date_gmt’ => gmdate( ‘Y-m-d H:i:s’, strtotime( $orginal_date ) ),
wp_update_post( $args );

* Adds billing and shipping information from the old order to the woo order.
* @param $old_order
* @param $woo_order
public function add_customer( $old_order, $woo_order ) {
$woo_order->set_payment_method( $this->gateway );
// The keys in this array are how woo formats an address.
// The values can be formed to your old systems specs.
// All keys are required. Leave value blank if not using.
$address = array(
‘country’ => $old_order->address_country,
‘first_name’ => $old_order->first_name,
‘last_name’ => $old_order->last_name,
‘company’ => $old_order->address_company,
‘address_1’ => $old_order->address_1,
‘address_2’ => $old_order->address_2,
‘city’ => $old_order->address_city,
‘state’ => $old_order->address_state,
‘postcode’ => $old_order->address_zip,
’email’ => $old_order->payer_email,
‘phone’ => $old_order->payer_phone,
// Assumes that the billing and shipping addresses were identical
$woo_order->set_address( $address ); // defaults to billing
$woo_order->set_address( $address, ‘shipping’ );

public function add_items( $old_order, $woo_order ) {
// loop through every item in the old order and add them to the new woo order.
foreach ( $old_order->items as $item ) {
// This assumes you’ve already imported or added products to Woo.
// This also assumes your old products use some sort of variation logic ( like ‘size’ or ‘color’ ).
// You could also use a different object such as WC_Product_Simple
// What ever type of product you use, you’ll need to write some logic that maps your old product to a woo product
$woo_variation_id = $this->map_product( $item );
$product = new WC_Product_Variation( $woo_variation_id );
$quantity = $item->quantity;

$args = array(
‘totals’ => array(
‘subtotal’ => $item->price,
‘total’ => $item->price * $quantity,
// assumes you’ve already configured your product attributes / variations
// in this example we have size and color, like a t-shirt
‘variation’ => array(
‘pa_color’ => $item->color,
‘pa_size’ => $item->size,

$woo_order->add_product( $product, $quantity, $args );

// Adds a flat rate shipping line item to the order.
// Assumes you’ve already configured your woo shipping settings.
// You could get more complex if you need to.
$shipping_rate_id = ‘wc_shipping_flat_rate’;
$shipping_rate_label = ‘Flat Rate’;
$shipping_rate_cost = $old_order->shipping;
$shipping_rate_tax = 0;
$shipping_rate_method_id = false;
$shipping_rate = new WC_Shipping_Rate( $shipping_rate_id, $shipping_rate_label, $shipping_rate_cost, $shipping_rate_tax, $shipping_rate_method_id );
$woo_order->add_shipping( $shipping_rate );

// All of these totals are required, set them to ‘0’ if you don’t plan to use them
$woo_order->set_total( $old_order->tax, ‘tax’ );
$woo_order->set_total( $old_order->payment_total );
$woo_order->set_total( $old_order->shipping, ‘shipping’ );
$woo_order->set_total( ‘0’, ‘shipping_tax’ );
// This will allow the imported sales to show up in reports


* @param $product – information about a product from your old system
* @return int – should return a woo product id or a woo variation id
public function map_product( $product ) {
// run logic to map your old product to a woo product
return 1;

Leave a Reply

Powered by

Up ↑

%d bloggers like this: