Automate Shopify-Zendesk customer data sync: A step-by-step guide with Cloudhooks

Transform manual customer updates into a seamless automated flow between Shopify and Zendesk in just 30 minutes, ensuring your support team always has the latest data.

While Zendesk offers powerful customer support features, keeping information synchronized across both platforms can be challenging without the right automation tools. By combining Zendesk with Cloudhooks, you can create automated workflows that keep customer data perfectly synchronized.

Time to complete: ~30 minutes
Difficulty level: Intermediate

What you’ll build

In this tutorial, you'll create an automation that:

  1. Monitors your Shopify store for customer profile updates
  2. Extracts customer details (name, email, phone, address, etc.)
  3. Automatically updates or creates corresponding user profiles in Zendesk
  4. Maintains custom field mappings for Shopify-specific data

Prerequisites:

  • A Shopify store with Cloudhooks installed
  • Access to both Shopify and Zendesk admin panels
  • Basic understanding of API authentication

While this tutorial demonstrates a basic implementation, you can extend it with custom business logic to transform and map data according to your specific needs.

Configure user fields

Zendesk includes basic user fields by default (name, email, phone), but its flexible custom fields system allows you to store additional Shopify-specific data. We'll create custom fields to store important customer information from your Shopify store.

First, let's set up the necessary custom fields in Zendesk:

1) Go to the Admin Center in Zendesk at the https://<YOUR_ZENDESK_SUBDOMAIN>.zendesk.com/admin/home address, and select "User fields" in the menu under "People / Configuration":

2) Click the "Add field" button to create new custom fields:

3) For each field:

  • Choose an appropriate field type (text, number, dropdown, etc)
  • Set a clear display name
  • Define a unique field key (used in the API)

Here's an example of creating the Shopify customer ID field:

4) Create the following custom fields, using these exact field keys to match our hook code:

  • Shopify customer ID (shopifyCustomerId)
  • Address 1 (address1)
  • Address 2 (address2)
  • City (city)
  • Country (country)
  • Region (region)
  • Postal code (postalCode)
  • Phone number (phoneNumber)

💡 Tip: While you can customize field keys, keeping them consistent with the provided hook code will save you from having to modify the code later.

Generate an API key

Next, we'll create an API key that Cloudhooks will use to authenticate with Zendesk's API:

1) Go to the Admin Center in Zendesk at the https://<YOUR_ZENDESK_SUBDOMAIN>.zendesk.com/admin/home address, and select "Zendesk API" in the menu under "Apps and integrations / APIs":

2) Navigate to the "Settings" tab

3) Enable token access (preferred over username/password)

4) Click "Add API token":

5) In the token creation pane:

  • Give your token a descriptive name (e.g., "Cloudhooks Integration")
  • Click "Copy" to save the token
  • Store the token securely (it won't be shown again)

⚠️ Security note: Store your API token in a secure password manager. If your token is ever compromised, generate a new one immediately and update your hook configuration.

Set up Cloudhooks

Prepare your API credentials

Zendesk's API uses HTTP Basic authentication, requiring a base64-encoded credential string. Let's prepare this string for our hook:

1) Create your authentication string in this format:

your.user@example.com/token:YOUR_API_TOKEN

2) Encode this string using base64:

For macOS/Linux
Run the following command in the terminal:

echo -n "your.email@example.com/token:YOUR_API_TOKEN" | base64

For Windows
Run the following command in PowerShell:

[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("your.email@example.com/token:YOUR_API_TOKEN"))

💡 Tip: Replace your.email@example.com with the email address associated with your Zendesk user.

Save the resulting encoded string—you'll need it when configuring the hook.

Determine the Zendesk subdomain

Your Zendesk instance has a unique subdomain (e.g., mystore.zendesk.com). You'll need this subdomain for the hook configuration:

  • Note the subdomain portion of your Zendesk URL
  • Save it without the .zendesk.com par

Configure the hook

1) From your Cloudhooks dashboard, click "Create hook":

2) In the "Trigger" tab:

  • Select "A customer is updated" as your trigger event
  • This event fires for both new and existing customer updates
  • Click "Select trigger" to confirm:

3) Navigate to the "Hook" tab and add your code:

  • Copy the template code from the end of this article
  • Update the configuration constants at the beginning of the code with your credentials:
const API_TOKEN = 'YOUR_API_TOKEN';
const ZENDESK_SUBDOMAIN = 'YOUR_ZENDESK_SUBDOMAIN';

// Hook business logic starts here

4) Configure hook settings:

  • Go to the "Settings" tab
  • Set name: "Sync Shopify customers to Zendesk"
  • Enable the hook by toggling "Status" to "Active"
  • Click "Save"

💡 Best Practice: Choose descriptive names that clearly indicate both the trigger event and the action being performed.

5) Verify activation:

  • Return to the dashboard
  • Confirm the hook shows as "Active"

Testing your integration

Before deploying to production, it's crucial to thoroughly test your integration. We'll explore two testing methods to ensure everything works as expected.

Method 1: Test payload simulation

This approach lets you test the integration without modifying real customer data in Shopify:

1) Open your hook configuration and go to the "Hook" tab

2) Locate the test payload panel on the right

3) Modify the following properties of the test data:

{
	"id": 706405506930370000,
	"email": "bob@biller.com",
	"first_name": "Bob",
	"last_name": "Biller",
	"phone": null,
	"addresses": [],
	"default_address": {
		"id": 12321,
		"customer_id": 706405506930370000,
		"first_name": "Bob",
		"last_name": "Biller",
		"company": null,
		"address1": "151 O'Connor Street",
		"address2": null,
		"city": "Ottawa",
		"province": "ON",
		"country": "Canada",
		"zip": "K2P 2L8",
		"phone": "555-555-5555",
		"name": "Bob Biller",
		"province_code": "ON",
		"country_code": "CA",
		"country_name": "Canada",
		"default": false

	}
}

4) Customize the test payload:

  • Use a valid email address you can access
  • Update customer name and contact details
  • Modify address information
  • Ensure all required fields are populated

5) Execute the test:

  • Click "Run test" in the hook interface
  • Wait for the execution to complete

6) Verify the results:

  • Check the execution logs in the "Test" pane
  • Visit your Zendesk user list at https://<YOUR_ZENDESK_SUBDOMAIN>.zendesk.com/agent/user_filters
  • Confirm the test user was created with all custom fields populated correctly

💡 Tip: Test with various data combinations, including missing or partial information, to ensure your hook handles all scenarios gracefully.

Method 2: Live test purchase

This method tests the complete workflow using Shopify's test environment:

1) Prepare your test environment:

  • Go to Shopify payments settings
  • Enable test mode for payments
  • Ensure your hook is active

2) Create a test customer:

3) Verify the integration:

  • Watch the Cloudhooks execution logs
  • Check for the new user in Zendesk
  • Verify all customer data was synced correctly

⚠️ Important: Always test in a development environment first before enabling the hook in production.

Hook code

Below is the complete hook code that synchronizes customer data between Shopify and Zendesk. Copy this code into your hook's code editor and update the configuration constants with your values:

const API_TOKEN = 'YOUR_API_TOKEN';
const ZENDESK_SUBDOMAIN = 'YOUR_ZENDESK_SUBDOMAIN';

module.exports = async function(payload, actions, context) {
  let userUpdate = {
    name: payload.first_name + ' ' + payload.last_name,
    email: payload.email,
    skip_verify_email: true,
    user_fields: {
      shopifyCustomerId: payload.id.toString(),
    },
  };
  const phoneNumber = payload.phone ?? (payload.defaultAddress && payload.defaultAdddress.phone);
  const defaultAddress = payload.default_address ?? (payload.addresses && payload.addresses.find(address => address.default));

  if (phoneNumber) {
    userUpdate.phone = phoneNumber;
    userUpdate.user_fields.phoneNumber = phoneNumber;
  }

  if (defaultAddress) {
    const addressFields = {}

    defaultAddress.address1   && (addressFields.address1 = defaultAddress.address1);
    defaultAddress.address2   && (addressFields.address2 = defaultAddress.address2);
    defaultAddress.city       && (addressFields.city = defaultAddress.city);
    defaultAddress.province   && (addressFields.region = defaultAddress.province);
    defaultAddress.zip        && (addressFields.postalCode = defaultAddress.zip);
    defaultAddress.country    && (addressFields.country = defaultAddress.country);

    userUpdate.user_fields = {...userUpdate.user_fields, ...addressFields}
  }

  try {
    const result = await actions.http.post(
      `https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/users/create_or_update.json`,
      { user: userUpdate },
      { 
        headers: { 
        'Authorization': `Basic ${API_TOKEN}`, 'Content-type': 'application/json' 
        }
      }
    );

    if (result.status != '200' && result.status != '201' ) {
      throw new Error(result.data);
    }
  } catch (err) {
    console.error('Cannot update user in Zendesk: ', err);
  }

}

💡 Tip: This code includes error handling and logging to help you troubleshoot any issues that may arise.

Understanding the code

The hook performs these key operations:

  1. Extracts customer information from the Shopify payload
  2. Formats the data according to Zendesk's API requirements
  3. Creates or updates the user profile in Zendesk
  4. Handles errors and provides logging

Customization options

You can extend this code to:

  • Add additional custom fields
  • Implement custom data transformation logic
  • Add more error handling scenarios
  • Include additional Zendesk API calls