A Shopify CRM integration looks like a small job. Orders flow into HubSpot or Salesforce, customers become contacts and sales stops copying data between tabs. In practice it is a contract between two systems that disagree about what a customer is.
Most advice on how to hire for it says the same thing: scope the work, check references, compare quotes. That is right and incomplete. It skips what decides whether the sync survives its first bad week: the data mapping, failure handling, the cost over twelve months and who owns the sync once the agency leaves.
This is a buyer's playbook for e-commerce and operations managers. It shows how to scope the job, choose between a connector, n8n and custom code, agree a mapping, write a contract and plan a timeline. Costs appear as shapes, and any worked numbers are marked illustrative.
Key takeaways
- Scope the objects, direction, source of truth and freshness before you ask anyone for a quote.
- Choose a connector, n8n or custom code by logic complexity and order volume, not by price alone.
- Agree the data mapping table first, including refunds and marketing consent.
- Demand idempotent writes, retries, a dead-letter queue and nightly reconciliation from any team you hire.
- Get ownership of the accounts, the code and the alert channel in writing before work starts.
Shopify CRM integration: what the scope covers
Before you compare vendors, write down what the integration must do. A team can only quote what you can describe, and a vague brief produces a vague fixed price. Scope for a Shopify CRM integration comes down to four decisions: which systems, which objects, which direction and how fresh the data must be.
Skip any of them and every proposal hides a different set of assumptions. You end up comparing prices for different jobs.
The objects that actually sync
Most stores need four objects: customers, orders, refunds and marketing consent. Larger setups add products and inventory (usually owned by an ERP), subscriptions, B2B companies and support tickets. Each object is its own mapping, its own test cycle and its own way to fail.
Name the CRM and every other app in the same document. Count objects and systems, not tools: two systems with four objects each is eight mappings.
One-way, two-way and source of truth
One-way means Shopify writes and the CRM reads. Two-way means both systems can change the same field, and that is where budgets grow, because every shared field needs a conflict rule.
Pick a source of truth per field, not per system. Shopify owns order totals, payment status and the shipping address at purchase. The CRM owns lifecycle stage, account owner, sales notes and deal stage.
Default to one-way for commerce data and write back only what the store needs, such as a segment or a tag. Not two-way everywhere. One-way with two precise write-backs.
How fresh the data needs to be
Real time sounds good and costs more. A sales rep calling after an abandoned checkout needs minutes. A finance report needs a daily close. Write the targets as numbers in the brief, for example: orders reach the CRM within five minutes, customer updates within an hour, totals reconcile every night.
Shopify gives you two tools for this: webhooks for live events and the Admin GraphQL API for reads, backfills and bulk operations. Both are rate limited, which is the first reason a sync needs a queue.
Connector, n8n or custom code: when each wins
There are three ways to build this integration, and each moves cost and risk to a different place. The right pick depends on the logic you need and your order volume, not on which tool is fashionable.
Prebuilt connector: fast, limited
A prebuilt connector is an app from the Shopify App Store or the CRM marketplace. You pay a subscription, often tiered by volume or features, and you configure rather than build. It wins when your needs match its fixed model: standard objects, one direction, no custom rules.
It loses on the first custom field, the first conditional rule or the second system. You usually cannot change how it retries, and you often cannot see why a record failed.
Middleware with n8n: control without a full build
n8n is a workflow tool you can self-host or run in the cloud. A workflow receives the Shopify webhook, transforms the payload, calls the CRM API and handles errors on a canvas you can read. Cost is hosting or a plan plus build hours. Our comparison of n8n, Zapier and Make covers pricing mechanics and limits.
It wins for mid-size stores with two or three systems and custom rules: retries, branching and error workflows are built in. It loses at very high volume, or when the logic needs software structure such as tests and versioned releases. The n8n docs describe a queue mode for scaling, but at that point a custom app deserves a quote.
Custom app: when the logic is yours
A custom app is code you own: a Next.js or Node service with a queue and a database. It suits high volume, complex pricing, B2B hierarchies and anything that needs tests and CI. Cost is the highest build plus a maintenance commitment, because Shopify releases API versions on a schedule and retires old ones.
Cost shape of each option over 12 months
Prices change, so we describe the shape of each option first and then run an illustrative example. Fit and control come before money.
Option A
Prebuilt connector
- Fit: standard objects, one direction
- Cost: monthly subscription
- Control: configuration only
- Failures: limited visibility
Our pick for most mid-size stores
n8n middleware
- Fit: two or three systems, custom rules
- Cost: build hours plus hosting or a plan
- Control: every step readable and editable
- Failures: retries and error workflows you design
Option C
Custom app
- Fit: high volume, complex logic
- Cost: highest build plus maintenance
- Control: full, with tests and CI
- Failures: whatever you engineer, including replay
The pick changes with logic and volume. Heavy business rules or very high order counts move you toward custom code, and a plain one-way sync of standard objects may not justify anything beyond a connector.
| Option | Upfront | Recurring | Where cost surprises you |
|---|---|---|---|
| Prebuilt connector | Low: setup time | Subscription, often tied to volume or features | Workarounds for missing fields, a second tool for the second app |
| n8n middleware | Medium: build hours | Hosting or plan, plus monitoring time | Updates on self-hosted instances, credential rotation |
| Custom app | Highest: design, build, tests | Hosting and a maintenance block | Shopify API version upgrades, on-call time |
Take a store with 5,000 orders a month, one CRM and three flows (illustrative). A connector costs a monthly fee and an afternoon of setup, until a custom field request forces a workaround or a second tool. An n8n build might take 40 to 80 hours plus hosting and a few hours of monthly upkeep. A custom app might cost several times that build, plus a standing maintenance block. Count the workarounds and the failures over twelve months, not only the invoice.
Shopify CRM integration data mapping
The mapping is the contract. It lists every field that moves, where it comes from, where it lands, which way it travels and who wins a conflict. Write it before the build and make the team sign off on it.
Data mapping flow
- 01Shopify eventCustomer, order, refund or consent change
- 02Map and dedupeMiddle layer: n8n or custom app
- 03Consent gateBlocked records skip the email platform
- 04Write to targetsCRM, ERP and email platform
- 05Store external IDWritten back to the Shopify record
Data flow from a Shopify event through mapping and a consent gate to the CRM, ERP and email, with an external ID written back
Read the flow left to right. An event leaves Shopify, the middle layer maps it to CRM fields and deduplicates, a consent gate decides whether the email platform receives the contact, and the CRM record ID is written back to Shopify as an external ID.
| Object | Shopify source | CRM target | Direction | Key rule |
|---|---|---|---|---|
| Customer | Customer, from customers/create and customers/update | Contact (HubSpot) or Contact or Lead (Salesforce) | Shopify to CRM | Match on email plus Shopify customer ID; store the ID in a custom property |
| Order | Order, from orders/create and orders/updated | Deal, opportunity or order record, plus contact rollups | Shopify to CRM | Upsert on Shopify order ID; keep order number and currency |
| Line items | Order line items | Deal line items or a custom object | Shopify to CRM | Copy SKU, quantity and price as at purchase |
| Refund | refunds/create | Fields or notes on the order record | Shopify to CRM | Update, never delete; store amounts |
| Cancellation | orders/cancelled | Closed deal stage with a reason | Shopify to CRM | Keep the record |
| Marketing consent | Customer email and SMS marketing consent | Marketing status and consent properties | Shopify to CRM, unsubscribes both ways | Gate: imports never overwrite consent |
| Segment or tag | None | Customer tag or metafield | CRM to Shopify | One of the few write-backs |
Use the table as a starting point, not a template. Your catalog, your sales process and your markets will change a few rows.
Customers and contacts
Match on email plus the Shopify customer ID. Email alone breaks when a customer changes address or checks out as a guest with another one. Store the Shopify ID in a custom CRM property so every later event updates the same record instead of creating a duplicate. In Salesforce, add an external ID field and upsert on it.
Guest checkouts have no customer ID. Decide whether they become contacts, and key them on email until an account exists.
Orders, line items and deals
An order maps to a deal in HubSpot, or an opportunity or order in Salesforce, depending on whether sales follows up. Pure e-commerce teams often skip deals and write order totals and last order date onto the contact instead. B2B teams with draft orders and quotes usually want a deal per order.
Keep the order number and the Shopify order ID on the record. Copy the currency with the amount and never convert silently.
Refunds and cancellations
A refund updates the order record. It never deletes it. Deletion breaks revenue reporting and the audit trail. Write the refunded amount, the date and a status such as partially refunded. Store amounts, not flags, because a flag cannot say how much. A cancellation moves the deal to a closed stage with a reason.
Marketing consent and compliance
Consent is a gate, never a field to overwrite. Shopify records email and SMS marketing consent per customer. The CRM and the email platform should only mark a contact subscribed when Shopify says so, and an unsubscribe in either place must propagate. A CRM list import must never flip a contact back to subscribed.
In the US, the TCPA covers marketing texts. In Spain, GDPR applies, and several Latin American countries have their own data protection laws. Treat deletion requests the same way: one received in Shopify must reach the CRM. Confirm the rules with your legal advisor.
Webhooks, idempotency, retries and reconciliation
Cheap builds work on the happy path: a webhook arrives, the CRM accepts the record, done. Production is the other path. The CRM times out, Shopify sends the same event twice, a rate limit blocks you on a sale day. Failure handling is the part buyers never ask about, so it is the part to ask about.
Shopify webhooks are delivered at least once and not guaranteed in order, so duplicates and late events are normal. For a wider view of event pipelines, read our post on webhook pipelines for AI integrations. The safe path has five steps.
Verify the signature
Compute the HMAC of the raw body with your app secret and compare it with the X-Shopify-Hmac-Sha256 header.
Acknowledge fast
Return a 200 within seconds and push the event onto a queue.
Deduplicate
Look up the event key. If you have seen it, drop it.
Upsert into the CRM
Write by Shopify ID so a replay updates the record instead of duplicating it.
Retry or park
Retry with backoff. After the limit, move the job to a dead-letter queue and alert.
Verify, acknowledge, then process
Verify the HMAC signature on the raw body, answer with a 200 fast and do the CRM work later in a queue. If you call the CRM inside the webhook request, a slow CRM becomes failed deliveries, and Shopify will eventually stop calling. The handler below is a Next.js route handler. Check the header names against the docs before you copy it.
import { createHmac, timingSafeEqual } from "node:crypto";
// Placeholder: use Redis or a table with a unique constraint in production
const seen = new Set<string>();
export async function POST(req: Request) {
// The HMAC covers the exact bytes Shopify sent, so read the raw body
const raw = await req.text();
const received = req.headers.get("x-shopify-hmac-sha256") ?? "";
const expected = createHmac("sha256", process.env.SHOPIFY_API_SECRET!)
.update(raw, "utf8")
.digest("base64");
const a = Buffer.from(received);
const b = Buffer.from(expected);
if (a.length !== b.length || !timingSafeEqual(a, b)) {
return new Response("Invalid signature", { status: 401 });
}
const topic = req.headers.get("x-shopify-topic") ?? "";
const eventId =
req.headers.get("x-shopify-event-id") ?? req.headers.get("x-shopify-webhook-id") ?? "";
const key = `${topic}:${eventId}`;
if (seen.has(key)) return new Response("Duplicate", { status: 200 });
seen.add(key);
// Hand off to a queue worker and answer fast
await enqueue({ key, topic, payload: JSON.parse(raw) });
return new Response("OK", { status: 200 });
}
async function enqueue(job: { key: string; topic: string; payload: unknown }) {
// Replace with your queue client
console.log("queued", job.key);
}
The in-memory set is a placeholder. In production the event key lives in Redis or a database table with a unique constraint, so it survives restarts and works across instances.
Idempotency keys and duplicate events
Idempotent means processing the same event twice gives the same result as processing it once. Record the event key before you act, and use upserts keyed on the Shopify ID instead of creates. Without that, a retry creates a second deal and your pipeline double counts.
Retries, dead-letter queues and rate limits
CRM APIs fail and throttle. Retry with exponential backoff and jitter so a thousand failed jobs do not hit the API in the same second. After a set number of attempts, park the job in a dead-letter queue: a holding place for events that need a human, with the payload and the error attached. An alert goes to a channel someone reads.
A queue also absorbs flash-sale spikes within the API limits of both sides. Ask any candidate what happens when the CRM is down for two hours. The answer should include the words queue, backoff and replay.
Nightly reconciliation as the safety net
Webhooks can be missed. A nightly job compares the previous day: orders, refunds and new customers in Shopify against the CRM. Gaps are repaired by fetching the missing records through the Admin GraphQL API and upserting them. The HubSpot developer docs list the batch and search endpoints that keep this job cheap.
The job also writes a short report. That report is how you know the sync works, instead of assuming it.
Safe sync path
- 01Webhook arrivesShopify sends the event
- 02Verify HMACInvalid signature is rejected
- 03Event ID lookupTopic and event ID checked
- ADuplicateAlready seen, dropped
- BNew event: CRM writeUpsert keyed on Shopify ID
- Record updatedSuccess ends here
- Retry with backoffOn failure, then dead-letter queue and alert
- CNightly reconciliationCompares Shopify and CRM counts
- Repair gapsFeeds missing records back to CRM write
Failure path of a webhook sync: signature check, duplicate drop, CRM write, retries, dead-letter queue and nightly reconciliation
How to hire a Shopify integration team
Hiring for this is narrower than hiring a web agency. You want a team that has run syncs in production, not one with a polished storefront portfolio. Whether you search for a Shopify HubSpot integration agency, a Shopify Salesforce integration specialist or a Shopify ERP integration developer, the vetting is the same.
What to ask before you sign
Ask these eight questions and listen for mechanisms.
- Who owns the Shopify app credentials, the CRM API keys and the workflow or repository?
- How do you prevent duplicate contacts and deals when an event arrives twice?
- What happens to events when the CRM is down for two hours?
- How do you handle marketing consent and unsubscribes in both directions?
- What do alerts look like, who receives them and how fast?
- How do you backfill historical orders without hitting rate limits?
- What is in the handover: mapping document, runbook, access, export?
- What does maintenance cost after launch, and what does it cover?
A good answer names a mechanism: an event ID table, an upsert on an external ID, a dead-letter queue, a daily report. A weak answer says "we handle that".
A short SOW template
Put these items in the statement of work, one or two lines each:
- Systems and objects in scope, with the mapping table as an appendix
- Direction and source of truth for every field
- Volume and freshness targets, written as numbers
- Error handling, retries and the alerting channel
- Backfill plan and cutover date
- Acceptance tests, run against a sandbox
- Handover: documentation, access, repository or workflow export
- Support window after launch and what it covers
Red flags in proposals
These tend to predict trouble:
- No mapping document before the build starts
- A flat fee with no mention of retries or duplicates
- They hold the API keys, or create the accounts under their own email
- No sandbox, staging environment or test plan
- No monitoring or alerts after launch
- A promise of real time for everything
Who owns the sync after launch
Ownership has three parts: the accounts, the code and the alerts. Get all three in writing before the first invoice.
Ownership rule
The store owns the Shopify app credentials, the CRM API keys, the workflow or repository and the alert channel. The agency gets access, not custody. If the accounts belong to the agency, you cannot replace the agency.
A sync you own can be handed to another team in days. A sync they own has to be rebuilt.
Timeline and cost by integration count
Timeline tracks the number of integrations more than store size. The ranges below are illustrative, typical of projects like these, not guarantees.
For the recommended path, the phases run like this. Each extra integration adds its own mapping and test cycle on top.
- Week 1
Discovery and mapping
Inventory the systems, agree the mapping table, the source of truth and the freshness targets.
- Weeks 2 to 3
Build the first sync
Webhook intake, queue, upserts, retries and alerts, tested against a sandbox.
- Week 4
Backfill and parallel run
Load history and compare totals against the existing process.
- Week 5
Cutover and monitoring
Switch over at a recorded timestamp and watch the reconciliation reports.
Maintenance is part of the budget, not an afterthought. Plan a recurring block of hours for API version upgrades, credential rotation and alert triage, rather than a surprise invoice when a version is retired.
One CRM, one direction
Customers, orders and refunds into HubSpot or Salesforce typically take three to five weeks from kickoff to cutover (illustrative). Most of that time is the mapping workshop and testing, not typing code.
CRM plus ERP plus email
Adding an ERP and an email platform is not additive. The systems interact: ERP stock and prices affect what the CRM shows, and consent has to reach both. An illustrative range is eight to fourteen weeks. The ERP is the usual risk, because legacy systems expose limited APIs or only batch exports. Our post on API and legacy system integrations goes deeper.
Backfill and cutover
Backfill loads history, using Admin GraphQL bulk operations rather than paging through orders one request at a time. Run the new sync in parallel with the old process for a week or two, compare totals, then cut over at a recorded timestamp. Once the core sync is stable, you can layer automation on top, as in our post on Shopify and AI automation.
How werun.dev builds and monitors these syncs
We build Shopify CRM integration work with n8n or a Next.js custom app, and we choose by logic and volume, not preference. The process is the same either way.
Build: mapping first, code second
Week one is a mapping workshop. The output is the table, the source of truth for each field, the consent rules and the acceptance tests. Then we build against a Shopify development store and a CRM sandbox, with idempotent writes, retries and a dead-letter queue from the first commit. Our Shopify work includes Shopify Plus and store operations, so we know what the store side tolerates.
Monitor: alerts and reconciliation reports
Every sync ships with alerts to a channel you own and a daily reconciliation report: counts on both sides, mismatches repaired and jobs waiting in the dead-letter queue. A quiet channel means the numbers matched.
Run: Care plan or Retainer
The Care plan covers monthly maintenance: API version upgrades, credential rotation and alert triage. The Retainer covers ongoing change, such as a new object or a new system. You hold the accounts and the code. We hold access, not custody. The integrations service page lists what we connect.
Where to start
Three moves, in this order:
- Inventory. List every system that touches a customer or an order, and what each one needs to know.
- Draft the mapping. Use the table above, mark the source of truth per field and write freshness targets as numbers.
- Shortlist two or three teams and send each the same brief and the same eight questions.
If you want a second opinion on the mapping or a quote, start from our integrations service page and tell us which systems you run.
Frequently asked questions
How much does a Shopify CRM integration cost?
It depends on the option: a connector is a recurring subscription, n8n is build hours plus hosting, and a custom app is the largest build plus maintenance. Cost grows with the number of systems, two-way sync, custom objects and backfill. Ask for a price tied to a mapping document and a separate line for maintenance.
How long does it take to connect Shopify to a CRM?
As an illustrative range, three to five weeks for one CRM in one direction, and eight to fourteen weeks for a CRM plus an ERP and an email platform. Backfill and a parallel run add time. Most of the schedule goes to mapping and testing.
Should I use a Shopify app connector or hire a developer?
Use a connector when you sync standard objects in one direction with no custom rules. Hire a team when you need custom fields, conditional logic, a second system or visibility into failed records.
Can n8n connect Shopify to HubSpot or Salesforce?
Yes. n8n has Shopify, HubSpot and Salesforce nodes, plus an HTTP Request node for endpoints they do not cover. A Shopify webhook can trigger a workflow that maps the payload, writes to the CRM and handles errors.
What data should sync between Shopify and my CRM?
Start with customers, orders, refunds and marketing consent. Add products, inventory and subscriptions only when a team uses them. Sync only the fields someone acts on, and decide the source of truth for each one.
Who owns the integration after the agency finishes?
You should. The store owns the Shopify app credentials, the CRM API keys, the workflow or repository and the alert channel, and the agency works with access you grant. Put this in the statement of work, along with a handover of documentation.