Intermediate~15 min setupCRM & E-commerceVerified April 2026
HubSpot logo
Shopify logo

How to Sync Shopify Customers to HubSpot with Power Automate

Automatically creates or updates a HubSpot contact whenever a new customer registers or completes a purchase in Shopify, keeping your CRM current with the latest email, name, and order data.

Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.

Best for

Microsoft-stack e-commerce teams who already pay for Power Automate through a Microsoft 365 plan and want Shopify customer data in HubSpot without a third-party subscription.

Not ideal for

Stores processing 500+ orders per day — HubSpot's API rate limits and Power Automate's per-flow run costs will add up; use Make instead.

Sync type

real-time

Use case type

sync

Real-World Example

💡

A 12-person DTC apparel brand runs Shopify for sales and HubSpot for email marketing. Before this flow, their marketing team exported Shopify CSVs weekly and imported them into HubSpot manually — new customers sat in limbo for up to 7 days before receiving a welcome sequence. After setting up this flow, every new Shopify customer lands in HubSpot as a contact within 90 seconds, tagged with their first order value and product category, and the welcome sequence fires the same day.

What Will This Cost?

Drag the slider to your expected monthly volume.

/mo
505005K50K

Each platform counts differently — Zapier: 1 task per trigger. Make: 1 operation per module per record. n8n: 1 execution per run.

Prices shown for annual billing. Based on published pricing as of April 2026.

Estimated ROI

1000

min saved/mo

$583

labor value/mo

Free

no platform cost

Based on ~2 min manual effort per operation at $35/hr fully loaded labor cost.

Implementation

Skip the setup

Import this workflow directly into Power Automate

Copy the pre-built Power Automate blueprint and paste it straight into Power Automate. All modules, filters, and field mappings are already configured — you just need to connect your accounts.

Before You Start

Make sure you have everything ready.

Shopify Admin API access token with read_orders and read_customers scopes enabled
HubSpot account with Contacts write permissions — free CRM tier works, but you need at least one custom property created for Shopify Order ID if you plan to map it
Microsoft Power Automate account — the Premium Shopify connector requires a Power Automate Premium plan (not the free tier or the basic Microsoft 365 plan)
HubSpot private app token or OAuth credentials with crm.objects.contacts.write scope granted
A sample Shopify order webhook payload JSON saved locally — you'll need it to generate the Parse JSON schema in Step 4

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Email Addressemail
First Namefirstname
Last Namelastname
7 optional fields▸ show
Phone Numberphone
Citycity
Countrycountry
Shopify Customer IDshopify_customer_id
Total Order Valueshopify_last_order_value
Order Countshopify_order_count
Lifecycle Stagelifecyclestage

Step-by-Step Setup

1

make.powerautomate.com > My flows > + New flow > Automated cloud flow

Open Power Automate and create a new Automated cloud flow

Go to make.powerautomate.com and sign in with your Microsoft account. In the left sidebar, click 'My flows', then click '+ New flow' at the top of the page. Select 'Automated cloud flow' from the dropdown — this is the flow type that triggers from an external event, which is what the Shopify webhook will use. Give your flow a name like 'Shopify → HubSpot Customer Sync' and click 'Create' to open the flow editor.

  1. 1Click 'My flows' in the left sidebar
  2. 2Click '+ New flow' at the top
  3. 3Select 'Automated cloud flow'
  4. 4Enter flow name: 'Shopify → HubSpot Customer Sync'
  5. 5Click 'Create'
What you should see: The flow editor opens with a blank trigger picker dialog showing a search bar and a list of connector icons.
Common mistake — Do not choose 'Instant cloud flow' or 'Scheduled cloud flow' — those won't respond to Shopify events in real time. You need Automated cloud flow specifically.
2

Flow editor > Trigger picker > Search 'Shopify' > When an order is placed

Add the Shopify 'When an order is placed' trigger

In the trigger picker, type 'Shopify' in the search bar. Select the Shopify connector from the results. You'll see a list of available triggers — choose 'When an order is placed'. This trigger fires immediately when a Shopify order is completed, which captures both new customers and returning ones along with their latest purchase data. If you want to also capture customers who register without purchasing, you'll need a second flow using 'When a customer is created'.

  1. 1Type 'Shopify' in the trigger search bar
  2. 2Click the Shopify connector tile
  3. 3Select 'When an order is placed' from the trigger list
What you should see: A Shopify trigger card appears in the flow canvas with a 'Sign in' button, indicating Power Automate needs to connect to your Shopify store.
Common mistake — The Shopify connector requires your store's Admin API credentials, not your regular Shopify login. Have your store URL (yourstorename.myshopify.com) and API key ready before proceeding.
Power Automate
+
click +
search apps
HubSpot
HU
HubSpot
Add the Shopify 'When an ord…
HubSpot
HU
module added
3

Shopify trigger card > Sign in > Connection dialog

Authenticate the Shopify connection

Click 'Sign in' on the Shopify trigger card. A dialog will ask for your Shopify store URL and API key. Enter your store URL in the format 'yourstorename.myshopify.com' — no https://, no trailing slash. Paste your Admin API access token in the password field. Click 'Create' to save the connection. Power Automate stores this as a named Connection you can reuse across flows.

  1. 1Click 'Sign in' on the Shopify trigger card
  2. 2Enter your store URL: yourstorename.myshopify.com
  3. 3Enter your Admin API access token in the API Key field
  4. 4Click 'Create' to save the connection
What you should see: The Shopify trigger card shows your store name under 'Connection' and the trigger is now active with no red error indicators.
Common mistake — If you generate a new API token in Shopify after setting this up, you must update the Connection in Power Automate manually — the old token becomes invalid immediately and the flow will start failing silently.
4

Flow editor > + New step > Search 'Parse JSON' > Data Operations – Parse JSON

Add a 'Parse JSON' action to extract customer fields

Click '+ New step' below the Shopify trigger. Search for 'Parse JSON' and select the 'Data Operations – Parse JSON' action. In the Content field, click inside the box and select 'Body' from the dynamic content panel — this is the raw JSON payload Shopify sends. For the Schema, click 'Generate from sample' and paste in a sample Shopify order webhook payload. This step gives you clean, named dynamic content tokens like customer.email and customer.first_name that you'll map to HubSpot in later steps.

  1. 1Click '+ New step'
  2. 2Search 'Parse JSON' in the action search bar
  3. 3Select 'Data Operations – Parse JSON'
  4. 4Click in the Content field and select 'Body' from dynamic content
  5. 5Click 'Generate from sample' and paste a Shopify order webhook payload
  6. 6Click 'Done' to generate the schema
What you should see: The Parse JSON card shows a green schema preview with field names like 'email', 'first_name', 'last_name', 'total_price' visible in the schema box.
Common mistake — If you skip the Parse JSON step and try to use Body directly in HubSpot fields, Power Automate will wrap the entire payload in a 'for each' loop automatically, which creates duplicate HubSpot contacts for orders with multiple line items.
HubSpot fields
firstname
lastname
email
company
hs_lead_status
available as variables:
1.props.firstname
1.props.lastname
1.props.email
1.props.company
1.props.hs_lead_status
5

Flow editor > + New step > Search 'HubSpot' > Search for contact

Add a HubSpot 'Search for contact' action to check for duplicates

Click '+ New step'. Search for 'HubSpot' and select the HubSpot CRM connector. Choose the action 'Search for contact'. In the search query field, use the dynamic content token for 'email' from the Parse JSON output. This step is critical — HubSpot will create duplicate contacts if you skip it and call 'Create contact' blindly for customers who already exist from a previous order. The search returns the contact ID if found, or empty if not.

  1. 1Click '+ New step'
  2. 2Search 'HubSpot' in the action search bar
  3. 3Select the HubSpot CRM connector
  4. 4Choose 'Search for contact' action
  5. 5In the search field, insert the 'email' dynamic content token from Parse JSON output
What you should see: The HubSpot action card shows the email field populated with the dynamic token and a 'Connection' dropdown showing your authenticated HubSpot account name.
6

HubSpot action card > Sign in > HubSpot OAuth screen

Authenticate the HubSpot connection

If you haven't used the HubSpot connector before in Power Automate, click 'Sign in' on the HubSpot action card. You'll be redirected to a HubSpot OAuth screen. Log in with the HubSpot account that has access to your CRM portal, then click 'Allow'. Power Automate saves this as a named Connection. You only do this once — all subsequent HubSpot actions in this flow reuse the same connection.

  1. 1Click 'Sign in' on the HubSpot action card
  2. 2Log into HubSpot on the OAuth redirect page
  3. 3Click 'Allow' to grant Power Automate access
  4. 4Return to the flow editor — the connection name now shows your HubSpot portal
What you should see: The HubSpot action card shows your portal name under 'Connection' and no authentication error banners.
Common mistake — Use a service account or integration user in HubSpot, not a personal account. If the person who authenticated leaves and their account is deactivated, the entire flow will break and throw 401 errors until re-authenticated.
7

Flow editor > + New step > Control > Condition

Add a Condition to branch on whether the contact exists

Click '+ New step' and choose 'Control – Condition'. In the left side of the condition, insert the 'id' field from the HubSpot 'Search for contact' output using dynamic content. Set the operator to 'is not equal to' and leave the right side blank (empty string). This creates two branches: the 'Yes' branch handles existing contacts (update), and the 'No' branch handles new contacts (create). Label the branches in the flow canvas by clicking the three-dot menu on each — it makes troubleshooting much easier later.

  1. 1Click '+ New step'
  2. 2Select 'Control' category
  3. 3Choose 'Condition'
  4. 4In the left field, insert the 'id' dynamic content token from HubSpot Search output
  5. 5Set operator to 'is not equal to'
  6. 6Leave the right field empty
What you should see: The flow canvas shows a branching Condition card with a 'Yes' path and a 'No' path, each showing an '+ Add an action' button.
Common mistake — The HubSpot Search action returns null — not an empty string — when no contact is found. Using 'is equal to' with an empty string will not catch null returns. Use 'is not equal to' with the right field blank, which handles both null and empty correctly.
HubSpot
HU
trigger
filter
Condition
matches criteria?
yes — passes through
no — skipped
Shopify
SH
notified
8

Condition card > No branch > + Add an action > HubSpot > Create a contact

Configure the 'No' branch: Create a new HubSpot contact

In the 'No' branch (contact doesn't exist), click '+ Add an action'. Search for HubSpot and select 'Create a contact'. Map the fields from your Parse JSON output: Email → customer.email, First name → customer.first_name, Last name → customer.last_name. Add custom properties for Total Order Value and Shopify Customer ID if your HubSpot portal has those properties set up. See the field mapping section below for the full list of recommended fields.

  1. 1Click '+ Add an action' inside the 'No' branch
  2. 2Search 'HubSpot' and select 'Create a contact'
  3. 3Map 'Email' to the 'email' dynamic content token
  4. 4Map 'First name' to 'first_name' token
  5. 5Map 'Last name' to 'last_name' token
  6. 6Add 'Phone' mapped to 'phone' token
  7. 7Add any custom HubSpot properties for order data
What you should see: The Create contact action card shows all mapped fields populated with dynamic content tokens from the Parse JSON step, with no red 'required field' warnings.
9

Condition card > Yes branch > + Add an action > HubSpot > Update a contact

Configure the 'Yes' branch: Update the existing HubSpot contact

In the 'Yes' branch (contact already exists), click '+ Add an action'. Search for HubSpot and select 'Update a contact'. In the Contact ID field, insert the 'id' dynamic content token from the HubSpot Search step — this targets the exact existing record. Map the same fields as the Create step: email, first name, last name, phone, and any order-related custom properties. This overwrites the existing values with the latest data from Shopify, so a customer who updates their phone number on a new order gets the correct number in HubSpot automatically.

  1. 1Click '+ Add an action' inside the 'Yes' branch
  2. 2Search 'HubSpot' and select 'Update a contact'
  3. 3In Contact ID, insert the 'id' token from the HubSpot Search output
  4. 4Map all fields identically to the Create contact step
  5. 5Save the step
What you should see: The Update contact card shows the Contact ID field populated with the dynamic 'id' token and all other fields mapped — no static values, no empty required fields.
Common mistake — Do not map the Email field in the Update action unless you intend to allow email changes. HubSpot treats email as a unique identifier — updating it with an email that belongs to a different contact will merge or overwrite the wrong record.
10

Flow editor > Select HubSpot steps > Control > Scope + Configure run after

Add error handling with a 'Scope' and 'Configure run after'

Select all the HubSpot actions (steps 5 through 9) and wrap them in a 'Control – Scope' action by clicking 'Add a parallel branch' or by restructuring manually. Then add a second Scope for error handling: inside it, add a 'Send an email (V2)' action or a Teams notification that fires when the main scope fails. To connect them, click the three-dot menu on the error Scope, select 'Configure run after', and check 'has failed' and 'has timed out'. This ensures you get alerted when HubSpot rejects a contact instead of data silently dropping.

  1. 1Click '+ New step' after all HubSpot actions
  2. 2Select 'Control – Scope' and name it 'Error Handler'
  3. 3Add a 'Send an email (V2)' or Teams message action inside the error Scope
  4. 4Click the three-dot menu on the error Scope card
  5. 5Select 'Configure run after'
  6. 6Check 'has failed' and 'has timed out', uncheck 'is successful'
What you should see: The flow canvas shows the error Scope connected to the main flow with a dashed line, indicating it only runs on failure — not on every execution.
Power Automate
▶ Test flow
executed
HubSpot
Shopify
Shopify
🔔 notification
received
11

Flow editor > Save > Test > Manually > Flow run history

Test the flow with a real Shopify test order

Click 'Save' in the top right of the flow editor, then click 'Test' → 'Manually' → 'I'll perform the trigger action'. Place a test order in your Shopify store (Shopify has a Bogus Gateway for test payments in Settings > Payments). Return to Power Automate and wait up to 60 seconds for the run to appear in the 'Flow run history' on the flow's detail page. Click the run to expand it — every step shows green checkmarks if successful, or a red X with the exact error message if something failed.

  1. 1Click 'Save' in the top right
  2. 2Click 'Test', then select 'Manually'
  3. 3Click 'I'll perform the trigger action'
  4. 4Place a test order in Shopify using Bogus Gateway
  5. 5Return to Power Automate and click on the flow run in history
  6. 6Expand each step to verify green checkmarks and mapped field values
What you should see: Every step in the run history shows a green checkmark. In HubSpot, a new contact (or updated contact) appears with the test order's email, name, and phone number within 90 seconds of placing the order.
Common mistake — Power Automate's test mode with 'Manually' still processes real data — if you test with a real customer email, HubSpot will create or update that contact for real. Use a test email address like [email protected] to keep test data separate.

Paste this expression into a 'Data Operations – Compose' action placed immediately after the Parse JSON step. It builds a clean HubSpot contact properties object in one shot, including lowercase email normalization and a formatted full name — both things you'd otherwise need multiple Compose steps to handle. In Power Automate, go to the expression editor (click the 'fx' icon in any field) and paste each expression individually per field, or use a single Compose action with a JSON object expression to prep all fields before passing them to the Create/Update contact actions.

Copy this template// Power Automate – Compose action expression
▸ Show code
// Power Automate – Compose action expression
// Builds a normalized HubSpot contact properties object
// Paste as the expression in a Compose action after Parse JSON

... expand to see full code

// Power Automate – Compose action expression
// Builds a normalized HubSpot contact properties object
// Paste as the expression in a Compose action after Parse JSON

{
  "email": "@{toLower(body('Parse_JSON')?['customer']?['email'])}",
  "firstname": "@{trim(body('Parse_JSON')?['customer']?['first_name'])}",
  "lastname": "@{trim(body('Parse_JSON')?['customer']?['last_name'])}",
  "phone": "@{body('Parse_JSON')?['customer']?['phone']}",
  "city": "@{body('Parse_JSON')?['shipping_address']?['city']}",
  "country": "@{body('Parse_JSON')?['shipping_address']?['country_code']}",
  "shopify_customer_id": "@{string(body('Parse_JSON')?['customer']?['id'])}",
  "shopify_last_order_value": "@{float(body('Parse_JSON')?['total_price'])}",
  "shopify_order_count": "@{int(body('Parse_JSON')?['customer']?['orders_count'])}",
  "lifecyclestage": "customer"
}

Going live

Production Checklist

Before you turn this on for real, confirm each item.

Troubleshooting

Common errors and how to fix them.

Frequently Asked Questions

Common questions about this workflow.

Analysis

VerdictWhy n8n for this workflow

Use Power Automate for this if your company is already inside the Microsoft ecosystem — Microsoft 365, Azure, Teams — and your team doesn't want to manage another vendor account. The HubSpot and Shopify connectors exist, the OAuth connections are stable, and you can monitor runs alongside your other internal automation in one place. It's also the right call if your IT department requires all integrations to stay within a Microsoft-approved SaaS boundary. The one scenario where you should pick something else: if your Shopify store processes more than 200 orders per day and you're on the per-flow plan, the cost math gets ugly fast. At that volume, Make handles the same workflow for a fraction of the price.

Cost

Power Automate Premium costs $15/user/month or $100/flow/month. Each Shopify order triggers one flow run. At 500 orders/month on the per-flow plan, that's $100/month for one flow. Make's Core plan at $9/month includes 10,000 operations — the same 500 orders would use roughly 3,000-4,000 operations (trigger + parse + search + create/update), leaving headroom. Zapier's Professional plan starts at $49/month for 2,000 tasks, which covers 500 orders at 4 tasks each with nothing to spare. If you're already paying for Power Automate Premium for other flows and this is one more, the marginal cost is zero. If this is your only automation, Make is cheaper by $91/month.

Tradeoffs

Make's biggest advantage here is the native Shopify module — it parses order data without a separate Parse JSON step, cutting the flow from 11 steps to 7. Zapier has a dedicated HubSpot 'Create or Update Contact' action that handles the duplicate check natively; in Power Automate, you build that logic yourself across a Search + Condition + two branches. n8n's Shopify node supports full webhook subscription management from inside the workflow editor, so you don't touch Shopify's app settings at all. Pipedream lets you write the entire deduplication and field normalization logic in JavaScript, which is faster to debug when something breaks. Power Automate is still right if your team lives in Teams and wants to send failure alerts directly to a Teams channel with one click — the Teams connector is first-class and requires zero extra setup.

Three things you'll hit after setup. First, Shopify's webhook payload includes a nested customer object, but draft orders and some abandoned checkout webhooks return a different structure where customer fields are null. If your store uses draft orders, add a null check on customer.email before the HubSpot search or you'll get 400 errors. Second, HubSpot's API rate limit is 100 requests per 10 seconds per portal for free and Starter tiers. A flash sale with 50 simultaneous orders can breach this — Power Automate runs flows in parallel by default, so all 50 hit HubSpot at once. Add a delay action of 2 seconds before the HubSpot steps during high-traffic events. Third, Shopify stores phone numbers in inconsistent formats — sometimes E.164 (+15038824410), sometimes local (503-882-4410), sometimes blank. HubSpot doesn't normalize these, so your phone field will be messy within a week. Add a Compose step with a regex replace expression to strip non-numeric characters before writing to HubSpot.

Ideas for what to build next

  • Sync HubSpot contact updates back to ShopifyBuild a second flow that triggers on HubSpot contact property changes and updates the matching Shopify customer record — useful when your sales team corrects a phone number or address in the CRM and you want Shopify to reflect it.
  • Tag HubSpot contacts with product categories from their ordersExtend the current flow to parse the line_items array from the Shopify order payload and write product category names to a HubSpot multi-select property, enabling segmented email campaigns by what customers actually bought.
  • Add a Shopify 'customer created' flow for registrations without purchasesBuild a parallel Automated cloud flow using the Shopify 'When a customer is created' trigger to catch customers who register an account but don't immediately buy — so they enter your HubSpot welcome sequence right away instead of waiting for their first order.

Related guides

Was this guide helpful?
HubSpot + Shopify overviewPower Automate profile →