Keep Shopify and Mautic consent in sync
Your email list looks fine until it doesn’t. A customer opts out in Shopify, stays opted in inside Mautic, and suddenly you’re sending campaigns to people who very clearly told you “no.”
This is the kind of mess that hits ecommerce managers first, but marketers running Mautic and ops folks handling data hygiene feel it too. With Shopify Mautic consent automation, subscription changes stay aligned both ways, so segments stay clean and complaints drop.
This workflow keeps consent updates moving automatically, explains the logic in plain English, and shows what you need to get it running safely.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Keep Shopify and Mautic consent in sync
flowchart LR
subgraph sg0["Flow 1"]
direction LR
n6["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Webhook"]
n7@{ icon: "mdi:cog", form: "rounded", label: "Crypto", pos: "b", h: 48 }
n8@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If", pos: "b", h: 48 }
n9@{ icon: "mdi:cog", form: "rounded", label: "No Operation, do nothing1", pos: "b", h: 48 }
n10["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/graphql.png' width='40' height='40' /></div><br/>GraphQL"]
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/graphql.png' width='40' height='40' /></div><br/>Marketing Consent - subscribed"]
n12["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/graphql.png' width='40' height='40' /></div><br/>Marketing Consent - unsubscr.."]
n13@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Mautic - Accepts Marketing?", pos: "b", h: 48 }
n14@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Customer exists?", pos: "b", h: 48 }
n15@{ icon: "mdi:cog", form: "rounded", label: "No Operation, do nothing2", pos: "b", h: 48 }
n16@{ icon: "mdi:swap-vertical", form: "rounded", label: "Set Shopify Subdomain", pos: "b", h: 48 }
n8 --> n10
n8 --> n9
n7 --> n8
n10 --> n14
n6 --> n7
n6 --> n16
n14 --> n13
n14 --> n15
n13 --> n11
n13 --> n12
end
subgraph sg1["Shopify Flow"]
direction LR
n0["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/shopify.svg' width='40' height='40' /></div><br/>Shopify Trigger"]
n1@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Accepts Marketing?", pos: "b", h: 48 }
n2@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Accepts Marketing?1", pos: "b", h: 48 }
n3@{ icon: "mdi:cog", form: "rounded", label: "No Operation, do nothing", pos: "b", h: 48 }
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/mautic.svg' width='40' height='40' /></div><br/>Add to confirmed segment"]
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/mautic.svg' width='40' height='40' /></div><br/>Remove from confirmed segment"]
n17["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/mautic.svg' width='40' height='40' /></div><br/>Search for Contact by Email"]
n18@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Contact exists?", pos: "b", h: 48 }
n19["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/mautic.svg' width='40' height='40' /></div><br/>Create a new contact"]
n18 --> n1
n18 --> n2
n0 --> n17
n1 --> n4
n1 --> n5
n2 --> n19
n2 --> n3
n19 --> n4
n17 --> n18
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n0 trigger
class n8,n13,n14,n1,n2,n18 decision
class n6 api
classDef customIcon fill:none,stroke:none
class n6,n10,n11,n12,n0,n4,n5,n17,n19 customIcon
The Problem: Consent Drifts Between Shopify and Mautic
Consent isn’t static. Customers opt in at checkout, unsubscribe from a campaign, re-subscribe after a product drop, or change their mind again two weeks later. When Shopify and Mautic don’t talk, those changes split into two “truths,” and your team ends up guessing which one to trust. The fallout is real: you lose confidence in segments, you waste time fixing records, and you take on compliance risk because the same person can be treated as subscribed in one system and unsubscribed in the other.
It adds up fast. Here’s where it usually breaks down.
- Someone unsubscribes via an email footer, but Shopify still shows them as opted in, so a future sync or import can quietly re-subscribe them.
- Lists get “cleaned” manually before a campaign, which means last-minute spreadsheet work and missed sends when you’re already under deadline.
- Customer service gets dragged into it after complaints, because nobody can quickly explain where the opt-in status came from.
- Segmentation rules inside Mautic become unreliable, so personalization gets weaker and reporting starts to lie.
The Solution: Two-Way Consent Sync With n8n
This n8n workflow is built as a two-way bridge between Shopify and Mautic. On the Shopify side, it watches for customer marketing preference changes and then looks up the matching contact in Mautic by email. If the contact exists, the workflow updates their status by adding or removing them from a “confirmed” group (and it can create the contact if you choose). On the Mautic side, it listens for webhook events, verifies the request signature for safety, fetches the correct Shopify customer record via the Admin API (GraphQL), and then updates Shopify’s email marketing consent to match what happened in Mautic. No plugins, no brittle exports, no weekly “sync day.”
The workflow starts with either a Shopify update trigger or an incoming Mautic webhook. It checks consent rules using simple IF logic, then updates the other system using the Mautic API and Shopify GraphQL calls. When something doesn’t match (invalid signature, missing customer, missing contact), it stops cleanly instead of forcing bad updates.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Let’s say you run two campaigns a week and you do a consent cleanup before each send. Manually, that often means exporting from Shopify, checking statuses in Mautic, chasing duplicates, then updating records, which can easily take about 2 hours per cleanup (so roughly 4 hours a week). With this workflow, the “cleanup” becomes checking a small log when you want peace of mind. Consent updates happen as they occur, and you spend a few minutes reviewing instead of burning an afternoon fixing drift.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Shopify as the consent source and customer database
- Mautic to store marketing consent and segments
- Shopify Admin API access token (create a custom app in Shopify)
Skill level: Intermediate. You’ll connect APIs, paste credentials, and test a webhook signature check.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A Shopify customer update kicks off the first sync. When a customer’s email marketing preference changes in Shopify, n8n catches it via the Shopify trigger and immediately looks up the matching email in Mautic.
The workflow checks if the contact exists and what the opt-in status should be. If the contact is found, IF rules decide whether to append them to a confirmed group or remove them. If the contact isn’t found, the workflow can generate a new contact first, then apply the right group status.
A Mautic webhook handles the “other direction.” Mautic events arrive through an incoming webhook, and the workflow calculates an HMAC signature hash and compares it before doing anything else. If the signature doesn’t match, it stops. Good.
Shopify gets updated through GraphQL and only when the customer exists. After verification, the workflow queries Shopify (GraphQL) to find the customer record, checks for a match, then sets consent to subscribed or unsubscribed based on the Mautic opt-in state. Missing customer records route to a “no-op” branch so you don’t accidentally create junk updates.
You can easily modify group names and consent rules to match your process based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Shopify Trigger
Set the Shopify trigger to fire on customer profile updates and connect your Shopify credentials.
- Add Shopify Update Trigger and set Topic to
customers/update. - Set Authentication to
accessToken. - Credential Required: Connect your
shopifyAccessTokenApicredentials.
Step 2: Connect Mautic for Contact Lookup and Segments
Configure Mautic to look up contacts, create new contacts, and manage segment membership based on Shopify consent.
- In Lookup Contact Email, set Operation to
getAll, Limit to1, and Search to{{ $json.email }}. - Credential Required: Connect your
mauticOAuth2Apicredentials to Lookup Contact Email, Append to Confirmed Group, Remove from Confirmed Group, and Generate New Contact. - In Append to Confirmed Group, set Resource to
contactSegment, Segment ID to1, and Contact ID to{{ $json.id }}. - In Remove from Confirmed Group, set Operation to
remove, Segment ID to1, and Contact ID to{{ $json.id }}. - In Generate New Contact, map Email to
{{ $('Shopify Update Trigger').item.json.email }}, First Name to{{ $('Shopify Update Trigger').item.json.first_name }}, and Last Name to{{ $('Shopify Update Trigger').item.json.last_name }}.
Step 3: Set Up Webhook Verification and Shopify Subdomain
The webhook path listens for Mautic subscription events, verifies the signature, and defines the Shopify subdomain. Incoming Webhook Listener outputs to both HMAC Signature Hash and Define Shopify Subdomain in parallel.
- In Incoming Webhook Listener, set HTTP Method to
POSTand Path to6485fca6-c641-4067-b19a-192709b88e45. - Enable Raw Body in Incoming Webhook Listener options to compute the HMAC signature.
- In HMAC Signature Hash, set Type to
SHA256, Action tohmac, Encoding tobase64, and Binary Data totrue. - In Define Shopify Subdomain, set Shopify Subdomain to
[YOUR_SHOPIFY_SUBDOMAIN].
[CONFIGURE_YOUR_TOKEN] in HMAC Signature Hash with your Shopify webhook signing secret, or the Signature Match Check will fail and route to No-Op Invalid Signature.Step 4: Configure Consent Routing with IF Nodes
Use conditional logic to route existing and new contacts and keep Mautic segments synced with Shopify marketing consent.
- In Verify Contact Presence, keep the condition checking Left Value
{{ $json.id }}with operatorexists. - In both Check Marketing Opt-In and Check Marketing Opt-In B, set the condition to
{{ $('Shopify Update Trigger').item.json.email_marketing_consent.state }}equalssubscribed. - Ensure the true path of Check Marketing Opt-In goes to Append to Confirmed Group, and the false path goes to Remove from Confirmed Group.
- Ensure the true path of Check Marketing Opt-In B goes to Generate New Contact, and the false path goes to Do Nothing Placeholder.
Step 5: Sync Mautic Subscription Changes Back to Shopify
When Mautic notifies a subscription change, validate the webhook, query the customer, and update Shopify consent via GraphQL.
- In Signature Match Check, keep the comparison between
{{ $('Incoming Webhook Listener').item.json.headers['webhook-signature'] }}and{{ $json.data }}. - In Shopify GraphQL Query, set Endpoint to
https://{{ $('Define Shopify Subdomain').params["fields"]["values"][0]["stringValue"] }}.myshopify.com/admin/api/2024-01/graphql.jsonand keep the provided Query expression. - Credential Required: Connect your
httpHeaderAuthcredentials to Shopify GraphQL Query, Set Consent Subscribed, and Set Consent Unsubscribed. - In Mautic Opt-In Check, set the condition to
{{ $('Incoming Webhook Listener').item.json.body['mautic.lead_channel_subscription_changed'][0].new_status }}equalscontactable. - In Set Consent Subscribed and Set Consent Unsubscribed, keep the Variables JSON with
{{ $json["data"]["customers"]["edges"][0]["node"]["id"] }}and{{ $now }}values.
Step 6: Test and Activate Your Workflow
Verify both Shopify-triggered updates and Mautic webhook updates before turning on the workflow in production.
- Click Test workflow and trigger a customer update in Shopify; confirm data reaches Lookup Contact Email and flows through Verify Contact Presence.
- Send a test request to the Incoming Webhook Listener URL and confirm the flow passes Signature Match Check and reaches Shopify GraphQL Query.
- Successful execution should either add/remove the contact in Mautic via Append to Confirmed Group/Remove from Confirmed Group or update Shopify via Set Consent Subscribed/Set Consent Unsubscribed.
- Toggle the workflow Active to enable continuous syncing.
Common Gotchas
- Shopify credentials can expire or lack the right scopes for Admin API access. If updates stop, check your custom app permissions and the access token you stored in n8n first.
- If you’re relying on webhook verification, one wrong secret breaks everything. Confirm the webhook secret in Mautic matches what your HMAC node uses, then re-send a test event to validate.
- Mautic contact matching by email sounds simple, but aliases and typos create “missing contact” cases. Decide upfront if you want the workflow to create new contacts automatically or route them to review.
Frequently Asked Questions
Plan on about 45 minutes if you already have Shopify and Mautic API access.
No. You’ll mostly copy credentials, set a few values, and run test events.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in Shopify and Mautic running costs (the workflow itself does not require paid AI APIs).
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, but be strict about the rule. You can change the logic in the “Check Marketing Opt-In” and “Mautic Opt-In Check” decision nodes so only confirmed (double opt-in) contacts get added to your confirmed group or marked as subscribed in Shopify. Common customizations include mapping different Mautic segments, using a different group name, and routing uncertain cases to a review queue instead of auto-updating.
Usually it’s an access token issue. Regenerate the Shopify custom app token, confirm it has the right Admin API scopes, and update both the Shopify Trigger credentials and the header auth used by the GraphQL requests. If it fails only during spikes, you may be hitting rate limits, so spacing events or adding retry logic can help. Also confirm the workflow is using the right Shopify subdomain value in the “Define Shopify Subdomain” step.
A lot. On n8n Cloud, capacity depends on your plan’s monthly executions, and self-hosting depends on your server. Practically, consent events are lightweight, so most small shops can run this all day without noticing.
Often, yes. The big reason is bidirectional sync with guardrails: webhook signature validation, branching logic, and GraphQL calls are all normal in n8n, while other tools can get expensive or awkward once you go beyond a simple two-step zap. n8n also gives you the option to self-host, which is handy if you process lots of small events. If you only need a one-way update and you never want to touch a webhook secret, Zapier or Make can still be simpler. If you’re unsure, Talk to an automation expert and you’ll know quickly.
Once consent stays synced, your segments stop drifting and your team stops second-guessing every send. Set it up, test it, and let the workflow do the boring part.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.