Quick Campaign Conversion Tracking in WooCommerce

My company hired a marketing firm that is starting our Constant Contact campaigns amongst other things.  We want to track conversions and at this point we don’t need anything too fancy.  Between that, Facebook ads/posts, Google Analytics and our affiliates, there’s a lot of pixels, JavaScript and php functions that need to be added to our system.  It’s a bit overwhelming and each has its own installation instructions/methods.

Right now, we just want to see conversions.  We want to know what source provide how many purchases and at what value.

I searched for some quick methods and plugins that might help but again, too much complicated setup for simple conversion tracking.  So I built a thing.

Quick Tracking Conversions for WooCommerce

I envisioned a super simple system where you can take on a code to the end of a link and all visits to your site with that code would be tracked and recorded when converted.  I wanted to start with simply recorded full, purchase conversions.

I didn’t want to have to setup a campaign with a code and details in an admin before generating links.  I want to just tell our marketing person put something like ?tracking_code=MyEmailCampaign on the end of all links in a Constant Contact.

So I built a plugin.  It’s light weight, secure and solid.  It does it’s job and it does it right.  You add whatever campaign code you want to links for Facebook, Email blasts, affiliates or anything at all that you want to track conversions from a link.  Here’s an example link that could be in an email:

https://example.com/product/t-shirts?qtc_woo_tracking_code=Oct2016-email-blast

After the email goes out and orders come in I can simply go to the admin page of the plugin, type in Oct2016-email-blast and submit the form.  It will show me number of conversions and total money generated so far.

How It Works

The plugin checks for $_GET[‘qtc_woo_tracking_code’] and sets its value in a cookie.  If the user converts it adds a post_meta to the order for that tracking code.

This allows me to pull all details of every order made.  We can get products purchases, shipping methods, totals, taxes and everything.

Here’s the repo if you want to check it out.  It’s simple right now and has Google Analytics Enhanced Ecommerce option you can enable as well.  There’s room to add all sorts of conversions such as product viewing, add to cart and so on.  This plugin will grow.

https://github.com/ChrisFlannagan/woo-flanny-conversion-tracker

Beatrix Has A YouTube Channel Now

My daughter watches these crazy videos where it’s just someone opening up toys, or pulling them out of play dough, or little toy surprises out of plastic eggs.  It’s the weirdest thing.  Apparently kids can watch these for hours as they have millions and millions of views.  Anyway, she asked me if she could make some so why not!  Here’s her first too:

https://www.youtube.com/watch?v=w8V86imzS2I

https://www.youtube.com/watch?v=CejT6PqBYGk

 

Getting Up To Speed With NativeScript 2.3, Xcode 8 and iOS 10

tns livesync ios --emulator --watch

Unsupported version Xcode 8

Oh no …

It’s That Time

The iPhone 7 is out along with iOS 10 and things have changed.  It hit me today when I was toying with my company’s app for the first time since upgrading Xcode.

So what do? Well, the first thing I needed to solve was getting my apps running in Simulator again.  I opened up Xcode and built my app in there instead of the command line tns.  I ran it on iPhone 7 Simulator and everything popped up and seemed to be working until it crashed right away on launch.

Upgrade NativeScript to “Next”

I uninstalled NS and the tns modules and reinstalled completely using the next version (2.4).

npm uninstall nativescript -g
npm uninstall tns-core-modules
npm install nativescript@next -g
npm install tns-core-modules@next

Then I removed the ios platform from my app and added it back.  Voila, things were loading up.  Thing is, I’m lying a little, I forgot to install the @next version of tns-core-modules and even though the app was opening certain things weren’t working like trying to set the src of an Image via javascript.

Properties Not Methods

So something big is happening.  Xcode is changing some big core items from using methods to initiate and instead using properties.  For example I use local-notifications plugin to send phone notifications.  I was erroring out with:

NSNotificationCenter.defaultCenter() is not a function

Apparently that is now a property so I had to adjust the module’s code in local-notifications.ios.js to

NSNotificationCenter.defaultCenter

And it works just fine now.  Or so I believe, no more errors but haven’t tested it thoroughly.

plist.info Permission Changes

Next the app crashes when I try to open the camera.  I’m getting errors saying there’s permission issues.  Turns out I need to have some new info in app/App_Resources/plist.info

<key>NSPhotoLibraryUsageDescription</key>
<string>Photo Library Access Warning</string>

More To Come

This is all so far but I’ll be sure to add more information as I encounter it.

 

WooCommerce Per Product Shipping Price Without Needing Extension or Plugin

Please note the commenter that pointed out a flaw in this if you have products with different shipping methods: 

The problem with this, is if you also have weight based shipping selected, and only want specific pricing for a handful of products, and someone selects one of those products AND a product which is included in weight based shipping, the customer is given two options for shipping, the flat rate (cheaper) and the weight based (more expensive). -Adam Winchester

I’m a big fan of WooCommerce, seriously.  I hate how much they nickel and dime for small features like this though.  It’s easier for me to move past it because I’m able to do a lot of tweaking in the code with hooks to get what I need done thereby saving a few dollars.  But sometimes, like this example, you can do it with no coding at all.

The shipping system in general can be pretty confusing so I’m going to walk you through how you can have custom, flat rate shipping prices for different products.

Shipping Zones & Methods

Under WooCommerce Settings click the Shipping tab.  Here you need to add a new zone.  For my example I call it US Flat Rate with a Flat Rate shipping method.

Now the confusing interface part.  In order to set details for flat rate you need to click on the words “Flat Rate” in your newly saved Shipping Zone row.  Let’s not do that yet though, click over to “Shipping Classes” option on this page.

Shipping Classes

This is where we will create our per item shipping prices.  Let’s say we have three products: T-Shirt, Mug and Hat.  We are going to create three shipping classes.

t-shirt-row

Now repeat for the other two items.

Back to Shipping Zones

Bounce back over to shipping zones, click on the “Flat Rate” link on your new shipping class row and let’s do some pricing.

Set the main cost to $0.00 then for each shipping class add the price for that item.  It’s that simple.  Go to your T-Shirt product and under shipping select the T-Shirt class.  Now it will  have that flat price added to the product for shipping on checkout.

Remove Item from PayPal Invoice with the REST API

I’m building a pretty crazy system right now around the PayPal Invoice REST API.  I want the owners of the site to be able to adjust all sorts of stuff on invoices whether the status is DRAFT or SENT.  If PAID, no go.  I’m going to give them the option to copy and cancel the original if that’s possible but I haven’t dove that far in yet.

But what I did need at this point was for them to allow users and admins to adjust an invoice by removing items.  So I google searched without much luck then finally looked through the API’s code to find what I needed.

PayPal Invoice Class

Inside the class for Invoice.php is a method removeItem().  Well, I tried this and kept getting a 400 error with no description of why it wouldn’t work.  I was using a foreach loop.

foreach ( $invoice->items as $item ) {
    if( blah blah ) {
        $invoice->removeItem( $item );
    }
}

This was just not working and there were no clues as to why.  I tried adding a count variable $cnt and using removeItem( $invoice->items[ $cnt ] ) but that was producing the same error.

Adjust The Quantity

So I finally settled on just changing the quantity to 0 and, low and behold, that worked just fine.  So end of day, the line item will still be there but you can set the quantity to 0 and it will charge nothing for it.  Final code was basically:

foreach ( $invoice->items as $item ) {
   if ( strpos( $item->name, 'Item ' . $id . ':' ) !== false ) {
      $item->setQuantity( 0 );
      $invoice->update( $api_context );
   }
}

WooCommerce Subscriptions Limit Total Quantity of Subscriptions or Payment Plans in Cart

We use WooCommerce Subscriptions to setup payment plans for our products.  Deposits was our first choice but it only sent “Invoices” for future payments and did not auto charge the credit card used at initial purchase.  Not ok as our products are very expensive and people tended to ignore those invoices.

We also need to limit these purchase to one per customer.  Easier said than done.  I found a WooCommerce extension that would do the trick but we already pay so much a year for extensions we need I try to avoid that for simple functionality.

Limit Subscription

This won’t work for my needs.  The option on a subscription product only limits users from having multiple subscriptions to that particular product.  We only want one subscript for ANY product.

Solution Limits

My solution works for one shopping cart session.  I’m working on preventing others which shouldn’t be too hard by just checking the database at checkout time for active subscriptions to that user.

The Hook & Function

I went with woocommerce_add_to_cart_validation after going through quite a few other hooks and filters.  The hardest thing about finding a solution is finding what all hooks and filters are available.  Takes some serious google-fu to find the right one quickly.

This filter allows you to run a function before an item is validated and sent to the cart.  We tell our add_filter that we need two of the parameters so we can get the product id as well as the validity of the admission.  This is done with the 4th parameter we set to “2.”

Detect Variations Too

If you are using variable Subscriptions you will need to plan ahead that some items in the cart may be variations.  These have a separate class.  We must first detect if the product being added is an instance of WC_Product_Subscription which is a “Simple Subscription” in WooCommerce.  Or is an instance of WC_Product_Variable_Subscription which is like it says a version of a subscription product with variations.

The odd part that caught me off guard is when we are checking items already in the cart.  We check for WC_Product_Subscription like normal but once in the cart the product is of the WC_Product_Subscription_Variation class meaning it’s just a variation of a product and not the full product variable class.

https://gist.github.com/ChrisFlannagan/3aaf4f58a627fa307180604886f2335c

Multiple Overlapping Layers of Transparent PNG Images Using AbsoluteLayout in NativeScript

Say you have an image of a face in your app.  There are multiple quadrants you want a user to be able to select.  When they select, it should highlight that area.  You want the user to have the ability to select any combination of these quadrants.

Stacking Images In AbsoluteLayout

Let’s go over the xml layout first.  I accomplished this task using an AbsoluteLayout with four Image views inside it like so.

https://gist.github.com/ChrisFlannagan/ca79529e943350c093f33e13023a03c7

Notice I set the width to 100% but not height. In my full code the height is set in a GridLayout for row 3, but you can set height to 100% or a pixel amount.

I placed a plain face photo as the background for the AbsoluteLayout.  Then I have four images for different quadrants of the face.  These have their absolute position set to 0px top and 0px left.  My overlaying images are the exact same size as the background image of my AbsoluteLayout so I want them to fit exactly over top.

I set the width to the parent element width, this way I know it will translate to different screen sizes.  I get the parent width in my javascript file then set it using this variable parentWidth.

Each image can be turned on or off by setting the visibility to collapsed or visible.  This is controlled in the javascript by the binding object along with the width.  See below:

https://gist.github.com/ChrisFlannagan/c94006689d4783f6667169d53e4f7beb

When the page is loaded I set my initial variables in pageData then turn that Observable into the binding data for the page.  So initially all images will be collapsed (turned off).

Gestures

Next I set gesture detection to my AbsoluteLayout that has been given the id “main-layout” and attached to the variable “quad.” I measure where the touch took place then if it’s in an images quadrant it toggles the collapsed/visible state.  The images are all positioned absolutely so they layer on top of each other.