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);
Facebooktwittergoogle_plusredditlinkedinmailFacebooktwittergoogle_plusredditlinkedinmail
  • Niall O Laoghaire

    Hi Ross
    This tutorial is exactly what I’ve been looking for. I put above code into functions file & the checkbox appears but when I click it nothing else happens. I’m using Sendpress and/or WYSIJA.
    Really appreciate some help on this
    Regards Niall

    • G’day Niall,

      Contact me via my contact page and I’ll see what I can do. Send me a link to your website so that I can see what’s going on.

      cheers,
      Ross

  • dan

    Same here. I am using sendpress, and I would like to add a checkbox on our woocommerce checkout page to add customers to our sendpress list. Can you help?

    • G’day Dan,

      Niall didn’t contact me, so I had to google to find out what SendPress was. My clients tend to use MailChimp so I’ve not needed to look at SendPress. Perhaps you can ask for support on their support forums.

      I’m available for hire for integration jobs if you don’t get any joy from the SendPress people.

      cheers,
      Ross

  • Hi There,

    Due to state laws I need to have the checkbox as default value un-checked. Could you please let me know what kind of code snippet I need to add and where? Other than that, this works perfectly fine!
    Thanks a bunch!
    Cheers,
    Toralf

    • G’day Toralf,

      When an anonymous shopper goes through the checkout, the checkbox is always unchecked. When a logged-in shopper goes through the checkout, it shows checked if that’s what they picked the last time they went through the checkout, because WooCommerce remembers the last settings used. Do you need different behaviour than that?

      cheers,
      Ross

  • Chris Jensen

    Great post Ross. I am a beginner but I think I can follow the above logic. I’ve also reviewed the WC tutorials on customizing checkout fields. One thing I cant determine is where to find these hooks you identified, like woocommerce_checkout_fields for example. Where are they?

    • G’day Chris, you can get a list from the WooThemes website. That list tells you where to find the caller of the hook, so you can look at how it’s calling and work out how you can use it. Basically, the source code is your manual :)

      cheers,
      Ross

      • Chris Jensen

        That was exactly what I was looking for! Thanks Ross!

  • Danielle Burgi

    I’m curious where this stores the e-mail addresses? From the comments below, it sounds like it sends them to a mailchimp list, but I don’t see the code that is making this happen? I’m hoping to adapt it to work with constant contact. Thanks!

    • G’day Danielle, this snippet is for collecting subscribers manually. If you want to add them to a MailChimp list, check out the WooCommerce MailChimp plugin.

      cheers,
      Ross

  • Ross:

    This would be a nice addition to my site. Please contact me.

  • Mikhail

    Howdy there Ross!
    This code looks great but I am wondering how to hook it up to our newsletter service, which is handled through DreamHost. It sounds like this doesn’t automatically input the information to your newsletter service, rather provide a list of people who checked out and whether they want to or not, is that correct? Then one could add them to the list manually with that info?

    • G’day Mikhail,

      Yes, this just lets you know that someone wants to be added to the email list, it doesn’t add them automatically. If you need that functionality, I’d actually recommend using MailChimp and the WooCommerce MailChimp plugin (see below for link)

      cheers,
      Ross

  • Andréa

    Thank you for the great snippet! How could I make the box checked by default? Cheers

    • G’day Andréa, try the snippet I just added to the end of the post.

      cheers,
      Ross

      • Andréa

        Thank you for your answer! However I could not make it work with the snippet. I tried putting it both before and after “WooSubscribeCheckbox::run();”. What could I be doing wrong? Cheers

      • I’m having that same issue. Where does this code for the filter go? after initiating the WooSubscribeCheckbox class? or somewhere within the class?