Menu

Snippets

Yet another programmer blogging about code

Subscribe to mailing list in WooCommerce checkout

A common requirement when building an online shop is to ask shoppers if they’d like to subscribe to shop’s newsletter, so that they can be updated when new products and specials are available. WooCommerce doesn’t come with such things as part of their standard checkout form, but with a few handy hooks, it’s very easy to add.

I did this recently when building a website for a large winery. There were three hooks I needed to utilise:

  • woocommerce_checkout_fields is a filter hook that allows you to add or modify what fields appear on the checkout form
  • woocommerce_checkout_update_order_meta is an action hook that allows you to save your new fields
  • woocommerce_email_order_meta_keys is a filter hook that allows you to add your new fields to the confirmation emails

The WooCommerce docs have a simple tutorial that works you through most of what you need to know. One thing that isn’t made clear is that the name you choose for your custom field on the email will be its label, so if you want to choose a nice friendly field label with spaces in it, you’ll want to make sure it’s different to the nice unique code-friendly name you’ll probably want to use for the form field name.

Putting the three hooks into action, here’s a simple class that wraps it all up.

Edit: the code now writes “yes” or “no” on the new order emails, to make the customer’s intention clearer.

<?php

class WooSubscribeCheckbox {

    // add hooks into WooCommerce
    public static function run() {
        add_filter('woocommerce_checkout_fields',
            array(__CLASS__, 'filterWooCheckoutFields'));

        add_action('woocommerce_checkout_update_order_meta',
            array(__CLASS__, 'actionWooCheckoutUpdateOrderMeta'));

        add_filter('woocommerce_email_order_meta_keys',
            array(__CLASS__, 'filterWooEmailOrderMetaKeys'));
    }

    /**
    * add custom fields to WooCommerce checkout
    * @param array fields
    * @return array
    */
    public static function filterWooCheckoutFields($fields) {
        global $woocommerce;

        // add field at end of billing fields section
        $fields['billing']['our_mailing_subscribe'] = array(
            'type' => 'checkbox',
            'label' => 'Subscribe to mailing list?',
            'placeholder' => 'Subscribe to mailing list',
            'required' => false,
            'class' => array(),
            'label_class' => array(),
        );

        return $fields;
    }

    /**
    * save custom order fields
    * @param int $order_id
    */
    public static function actionWooCheckoutUpdateOrderMeta($order_id) {
        $subscribe = isset($_POST['our_mailing_subscribe']) ? 'yes' : 'no';
        update_post_meta($order_id, 'Subscribe to mailing list', $subscribe);
    }

    /**
    * add our custom fields to WooCommerce order emails
    * @param array $keys
    * @return array
    */
    public static function filterWooEmailOrderMetaKeys($keys) {
        $keys[] = 'Subscribe to mailing list';

        return $keys;
    }

}

WooSubscribeCheckbox::run();

Job is done, if the shopper ticks the box!

Edit: how to auto-tick the checkbox:

add_filter('woocommerce_checkout_get_value', function($value, $input) {
    if ($input == 'our_mailing_subscribe') {
        $value = 'yes';
    }

    return $value;
}, 10, 2);