WooCommerce 3.8: Send a Notification Email When a Customer Changes Their Address

Envelope

Several years ago, I wrote a post, Send a Notification Email When a Woocommerce Customer Changes Their Address, that included a code snippet. Yesterday, I was contacted by a developer who tried to use the snippet and found it wasn’t triggered in his theme. I tested the snippet on my client’s site–he’s still using the Twenty Ten Theme–and found that it was triggered, but the email included the old address, not the updated address.

Back to the Drawing Board

The code snippet in that old post is certainly dated, so I’m very glad I had a reason to review it. It uses the $woocommerce and $current_user globals, both of which are no longer recommended. I have updated the code and modified the email a bit (see below).

The new version makes use of WooCommerce 3.8’s apparent retention of the old values for the address in wc()->customer->get_address(), and uses the get_user_meta() function to get the new values after the customer updates them.

The $woocommerce->customer->set_default_data() used in the old code snippet no longer works in my testing.

The email sent by the new code snippet displays either the billing or the shipping address, depending on which the user changes–since you can only change one at a time–and shows both the old address (from wc()->customer->get_address()) and the updated address (from get_user_meta(). If the way the values are saved changes in the future, that should make it easier for the recipient of the email to tell something isn’t working correctly. I’ve also included the customer’s first and last names in the addresses, as those can be changed as well.

Although the customer’s email address is included in the email, the new code snippet also sets the “Reply-To” header to the customer’s email to make it easy to reply to the customer in case it’s necessary.

I’ve tested the code snippet below with WooCommerce 3.8 in WordPress 5.2.4 on two sites with the Twenty Ten and Twenty Sixteen Themes. It worked for me, so I suspect there may be another issue for the reporting developer.

The Code

Put the following code in your child theme’s functions.php, and set the $from_name, $from_email, and $to values to try it out.

/* *********************************************** Change of Address Email ***************************************** */
// Send notification email when customer changes address.
  add_action( 'woocommerce_customer_save_address','notify_admin_customer_address_change', 10, 2);
  function notify_admin_customer_address_change( $user_id, $load_address ) {
    // Set the $from_name, $from_email, and $to for your site.
    $from_name = 'Your From Name';
    $from_email = 'email@yourdomain.com';
    $to = 'email@somedomain.com';
    
    $current_user = wp_get_current_user();
      if (!($current_user instanceof WP_User)) {
       return;
     }
      
      // format email
      $message .= 'User ' . $current_user->user_login . ' has changed their ' . $load_address .  " address.\n";
      $user_email = $current_user->user_email;
    $message .= 'User Email: ' . $user_email . "\n";
    $message .= 'User First Name: ' . $current_user->user_firstname . "\n";
    $message .= 'User Last Name: ' . $current_user->user_lastname . "\n";
    $message .= "\n";
    $message .= "\n";
    
    // Get the old address, which as of Woocommerce 3.8, is still in wc()->customer.
    $message .= "Old " . ucfirst($load_address) . " Address:\n";
    
    switch($load_address) {
      case 'billing':
        $message .= wc()->customer->get_billing_first_name() . ' ' . wc()->customer->get_billing_last_name() . "\n";
        $message .= wc()->customer->get_address() . "\n";
        $address_2 = wc()->customer->get_address_2();
        if ($address_2 != '') {
          $message.= $address_2 . "\n";
        }
        $message .= wc()->customer->get_city() . " ";
        $message .= wc()->customer->get_state() . " ";
        $message .= wc()->customer->get_postcode() . "\n";
        $message .= wc()->customer->get_country() . "\n\n";
      break;
      case 'shipping':
        $message .= wc()->customer->get_shipping_first_name() . ' ' . wc()->customer->get_shipping_last_name() . "\n";
        $message .= wc()->customer->get_shipping_address() . "\n";
        $shipping_address_2 = wc()->customer->get_shipping_address_2();
        if ($shipping_address_2 != '') {
          $message .= $shipping_address_2 . "\n";
        }
        $message .= wc()->customer->get_shipping_city() . " ";
        $message .= wc()->customer->get_shipping_state() . " ";
        $message .= wc()->customer->get_shipping_postcode() . "\n";
        $message .= wc()->customer->get_shipping_country();
      break;
    }
    
    // Get the updated address, which is in the user meta table.
    $message .= "\n\nNew " . ucfirst($load_address) . " Address:\n";
    
    switch($load_address) {
      case 'billing':
        $message .= get_user_meta($user_id, 'billing_first_name', true) . ' ' . get_user_meta($user_id, 'billing_last_name', true) . "\n";
        $message .= get_user_meta($user_id, 'billing_address_1', true) . "\n";
        $address_2 = get_user_meta($user_id, 'billing_address_2', true);
        if ($address_2 != '') {
          $message.= $address_2 . "\n";
        }
        $message .= get_user_meta($user_id, 'billing_city', true) . " ";
        $message .= get_user_meta($user_id, 'billing_state', true) . " ";
        $message .= get_user_meta($user_id, 'billing_postcode', true) . "\n";
        $message .= get_user_meta($user_id, 'billing_country', true) . "\n\n";
      break;
      case 'shipping':
        $message .= get_user_meta($user_id, 'shipping_first_name', true) . ' ' . get_user_meta($user_id, 'shipping_last_name', true) . "\n";
        $message .= get_user_meta($user_id, 'shipping_address_1', true) . "\n";
        $address_2 = get_user_meta($user_id, 'shipping_address_2', true);
        if ($address_2 != '') {
          $message.= $address_2 . "\n";
        }
        $message .= get_user_meta($user_id, 'shipping_city', true) . " ";
        $message .= get_user_meta($user_id, 'shipping_state', true) . " ";
        $message .= get_user_meta($user_id, 'shipping_postcode', true) . "\n";
        $message .= get_user_meta($user_id, 'shipping_country', true) . "\n\n";
      break;
    }
    
    // Set the email up to reply to the user's email.
    $headers = 'From: ' . $from_name . ' <' . $from_email . '>' . "\n" . 'Reply-To: ' . $user_email . "\n";
    
      wp_mail($to, 'Customer Address Change Notice', $message, $headers);
  }
/* **************************************** End of Change of Address Email ***************************************** */