Sync WordPress User Profile Updates to Mailchimp
In this tutorial we are going to update user’s first and last names in WordPress profile and sync the changes with Mailchimp audience fields. You can also check the basic guide how to work with Mailchimp API in WordPress.
I can also recommend you my Simple Mailchimp Sync plugin that allows to sync users between WordPress and Mailchimp automatically.
In this tutorial we assume that a specific email is already subscribed to your Mailchimp audience, in case you need to sync user registrations as well, then please check this example.
We are going to use profile_update
hook which is fired every time a user profile gets updated. Inside the hook we will perform a Mailchimp API request.
add_action( 'profile_update', function( $user_id, $old_userdata, $userdata ) {
$list_id = 'YOUR AUDIENCE ID';
$api = 'YOUR API KEY';
// user data
$email = $old_userdata->user_email;
// we can user's first and last names directly from WP_User object
$first_name = $userdata->first_name;
$last_name = $userdata->last_name;
// but we can also obtain some information from metadata like this
$city = get_user_meta( $user_id, 'city', true );
wp_remote_request(
'https://' . substr($api,strpos($api,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/members/' . md5(strtolower($email)),
array(
'method' => 'PATCH',
'headers' => array(
'Authorization' => 'Basic ' . base64_encode( 'user:'. $api )
),
'body' => json_encode(
array(
'merge_fields' => array(
'FNAME' => $first_name,
'LNAME' => $last_name,
'CITY' => $city,
)
)
)
)
);
}, 25, 3 );
And now just a little bit of explanation how it works:
- First things first, if you don’t know where to insert this code, please check this guide.
- Don’t know how to get your API key? Here is how.
- Don’t know how to get an audience ID? Here is how.
- And the last but not the least, please check the screenshot with my merge fields settings in Settings > Audience fields and *MERGE* tags, so it should be clear for you why I am using
FNAME
,LNAME
andCITY
.


Misha Rudrastyh
Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me
Hi,
The whole posts serie on Mailchimp Webhooks and API 3 is exactly what I was looking for and really didactic. Great job!!
However one specific question:
Everything’s fine if Mailchimp user change fname/lname OR email.
Unfortunatly if both fields are update together, profile AND upemail webhooks must be processed.
No problem if profile webhook is first then upemail webhook.
But if upemail webhook start first, user’s email is change and profile webhook can’t get the userID by email.
Any tips or trick to resolve this?
Thanks ;-)
Hey,
While updating from
upemail
I recommend to store an old email somewhere in user meta. So, when the profile webhook will be fired, check if user exists, if it doesn’t exist, try to find the user by a email we stored in user meta 🙃Correct answer but I’ve just realised that my question was completely wrong (in fact it’s just the opposite problem :D )
When modifying both email and fname/lname,
profile
is send with the new email and no reference to old one. So ifupemail
has not already been fired first to update the old email,profile
is unable to find any reference of the new email.The only solution I could find up to now is to resend
profile
datas after theupemail
with something like this:wp_schedule_single_event( time() + 1, 'resend_profile_datas', array( $datas ) );
But this seems to me to be an ugly process…
I got lost, 😁
Let’s try from the beginning – where you modify email and first/last names? On the website?
P.S. You can use
<code>
tag in comments 🙃Sorry, I start myself to loose my mind with this full 2 way sync.
When a Mailchimp user updates his email and first/last names at the same time, 2 webhooks are sent,
profile
andupemail
.upemail
contains old and new emails andprofile
contains new first/last names and new email.My webhook listener is not always receiving both webhooks in same order.
Good case : If
upemail
is fired first, my webhook listener can updates my user email first so whenprofile
is then fired, the listener can find the related user with the new email.Bad case : If
profile
is fired first, the webhook listener is unable to find the related user as it is still using the old email while theprofile
webhook contains only the new email. Theget_user_by( 'email', $_POST['data']['email'] );
is not returning any valid WP_user object.My new idea to resolve this bad case is, when receiving the
profile
webhook to create a temporary user with new data fromprofile
and adding atemporary
user meta (thanks for the idea).So after when receiving
upemail
, I can first check if I can find a user with new email and thetemporary
user meta (meaning thatprofile
has been fired first) and getting new first/last names from this user before deleting him.Not a completely clean solution (a lot of efforts for basic result) but at least I get rid of the
wp_schedule_single_event
I didn’t trust so much.Thanks for time and posts serie!
Now that I have my Mailchimp to WordPress sync, I will try to set up the other way sync…
Sebastien,
This solution #comment-4188 should fit perfectly for what you’ve just described.
Sorry, I must be dumb.
What would be the use of storing the old email when Upemail as Profile webhook only contains new email?
Just when
upemail
is fired, useupdate_user_meta()
to store the old email somewhere in user meta.When
profile
is fired afterupemail
check if there is a user with a email passed in the hook. If there is not such user, get it by the specific meta key you stored the old email into.