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

How to Create HubSpot Deals from Shopify Orders with Pipedream

Automatically creates a HubSpot deal every time a Shopify order is completed, mapping order value, customer details, and product data so your sales team can track revenue attribution and trigger upsell follow-ups.

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

Best for

E-commerce teams that run post-purchase sales motions and need every completed Shopify order reflected as a tracked deal in HubSpot within seconds.

Not ideal for

Stores processing hundreds of orders per hour — at that volume, a batch-based sync via a dedicated Shopify-HubSpot connector avoids per-execution credit costs.

Sync type

real-time

Use case type

sync

Real-World Example

💡

A 12-person DTC brand sells premium home goods on Shopify and uses a 3-person inside sales team to call high-value customers about bundles and subscriptions. Before this automation, a sales ops person exported Shopify orders to CSV every Monday morning and manually created HubSpot deals — a 2-hour weekly task that meant some customers weren't contacted until 6 days after purchase. Now every order over $200 triggers a HubSpot deal within 30 seconds, and the sales team calls while purchase intent is still fresh.

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 Pipedream

Copy the pre-built Pipedream blueprint and paste it straight into Pipedream. 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 with read_orders and read_customers scopes enabled on your private app or custom app
HubSpot account with a Sales Hub seat that allows deal creation via API — free CRM tier works but requires API access enabled under Settings > Integrations > Private Apps
HubSpot Private App token with scopes: crm.objects.deals.write, crm.objects.contacts.write, crm.objects.contacts.read, crm.associations.write
Your HubSpot pipeline ID and deal stage ID for the stage that represents a completed purchase — find these in HubSpot Settings > CRM > Deals > Pipelines
A Pipedream account on any paid plan — the free tier limits you to 10,000 credits/month which supports roughly 1,600 workflow executions at this complexity level

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Deal Namedealname
Deal Amountamount
Pipelinepipeline
Deal Stagedealstage
Close Dateclosedate
Customer Emailemail
4 optional fields▸ show
Deal Sourcedeal_source__c
Shopify Order IDshopify_order_id
Number of Line Itemsnum_associated_line_items
Shopify Order Numbershopify_order_number

Step-by-Step Setup

1

pipedream.com > Workflows > New Workflow

Create a new Pipedream workflow

Go to pipedream.com and sign in. Click the blue 'New Workflow' button in the top-left of the dashboard. You'll land on a blank workflow canvas with a trigger slot at the top labeled 'Add a trigger'. This is where Shopify events will enter the workflow.

  1. 1Sign in at pipedream.com
  2. 2Click 'New Workflow' in the left sidebar
  3. 3Name the workflow something like 'Shopify Order → HubSpot Deal' using the title field at the top
What you should see: You should see a blank workflow canvas with an empty trigger block at the top and a grey '+ Add a step' button below it.
2

Workflow Canvas > Trigger > Search Apps > Shopify > New Order (Instant)

Add the Shopify trigger via webhook

Click the trigger block and search for 'Shopify' in the app search bar. Select 'Shopify' from the results. Choose the event source 'New Order (Instant)' — this uses a Shopify webhook rather than polling, so your workflow fires within seconds of order placement. Connect your Shopify store by clicking 'Connect a Shopify account' and entering your store's .myshopify.com URL and API credentials.

  1. 1Click the trigger block on the canvas
  2. 2Type 'Shopify' in the search field
  3. 3Select 'New Order (Instant)' from the event list
  4. 4Click 'Connect a Shopify account'
  5. 5Enter your store URL in the format yourstore.myshopify.com and authenticate
What you should see: You should see a green 'Connected' badge next to your Shopify account name and a 'Generate Test Event' button below the trigger config.
Common mistake — The 'New Order (Instant)' trigger fires on order creation, not payment confirmation. If you only want paid orders, you'll need to add a filter step checking financial_status === 'paid'. Skipping this creates deals for abandoned checkouts that were technically submitted but never paid.
Pipedream
+
click +
search apps
HubSpot
HU
HubSpot
Add the Shopify trigger via …
HubSpot
HU
module added
3

Trigger Block > Generate Test Event

Generate a test Shopify order event

Click 'Generate Test Event' in the trigger configuration panel. Pipedream will either pull in a recent real order from your store or prompt you to place a test order. Use Shopify's test gateway to place a $1 draft order so you have real payload data to map in later steps. Once the event loads, expand the payload in the right panel — you'll see fields like order_number, total_price, customer.email, customer.first_name, line_items, and financial_status.

  1. 1Click 'Generate Test Event'
  2. 2If no events exist, open your Shopify admin and place a test order using Shopify's Bogus Gateway
  3. 3Return to Pipedream and click 'Refresh' to pull in the test event
  4. 4Expand the payload tree to verify fields like total_price and customer.email are populated
What you should see: You should see a fully populated JSON payload in the right panel including order_number, total_price as a string like '249.00', and a nested customer object with email and name fields.
Common mistake — Shopify returns total_price as a string, not a number. When you map it to HubSpot's amount field later, you must parse it with parseFloat() or HubSpot will reject the value with a type validation error.
Pipedream
▶ Deploy & test
executed
HubSpot
Shopify
Shopify
🔔 notification
received
4

Workflow Canvas > + Add Step > Filter

Add a filter step for paid orders only

Click '+ Add a step' below the trigger and select 'Filter' from Pipedream's built-in helpers. Set the condition to check that the trigger event's financial_status field equals 'paid'. This prevents deals from being created for pending, voided, or refunded orders. If the condition is false, Pipedream will halt the workflow and not bill credits for downstream steps.

  1. 1Click '+ Add a step'
  2. 2Select 'Filter' from the built-in helpers list
  3. 3Set the left side to {{steps.trigger.event.financial_status}}
  4. 4Set the operator to 'Equals'
  5. 5Set the right side to the string 'paid'
What you should see: The filter step shows a green checkmark and 'Condition passed' when run against your test event — assuming your test order was paid.
Common mistake — If you're using Shopify's test Bogus Gateway, the financial_status may be 'pending' even after checkout completes. Temporarily disable this filter during initial testing, then re-enable before going live.
HubSpot
HU
trigger
filter
Condition
matches criteria?
yes — passes through
no — skipped
Shopify
SH
notified
5

Workflow Canvas > + Add Step > HubSpot > Search CRM Objects

Search HubSpot for an existing contact by email

Click '+ Add a step' and search for 'HubSpot'. Select the action 'Search CRM Objects'. Set the object type to 'Contacts' and search by the email property using the customer email from the Shopify payload. This step checks whether a HubSpot contact already exists for this customer before creating a deal — you'll use the contact ID in the deal association step. Connect your HubSpot account via Connected Accounts using OAuth.

  1. 1Click '+ Add a step'
  2. 2Search for 'HubSpot' and select it
  3. 3Choose the action 'Search CRM Objects'
  4. 4Set object type to 'contacts'
  5. 5Set filter property to 'email' and value to {{steps.trigger.event.customer.email}}
  6. 6Connect your HubSpot account and click 'Test'
What you should see: You should see a response with a 'total' count and a 'results' array. If the contact exists, results[0].id will contain their HubSpot contact ID.
Common mistake — HubSpot's search endpoint returns up to 10 results by default. If a customer has duplicate contact records in HubSpot, this step returns the most recently modified one first — not necessarily the canonical record. Deduplicating HubSpot contacts before going live saves headaches.
6

Workflow Canvas > + Add Step > Node.js Code

Conditionally create a HubSpot contact if none exists

Add a Node.js code step to check whether the search returned a contact. If steps.hubspot_search.results.total equals 0, call the HubSpot Contacts API to create a new contact using the Shopify customer's email, first name, and last name. Store the resulting contact ID in a variable you'll pass to the deal creation step. If a contact was found, just pass through the existing ID.

  1. 1Click '+ Add a step'
  2. 2Select 'Run Node.js code'
  3. 3Paste the contact upsert logic (see pro tip code section)
  4. 4Reference the HubSpot search results from the previous step using steps variable
  5. 5Export the contactId so it's available in downstream steps
What you should see: After running, the step output should show a contactId field — either the existing HubSpot contact ID or the newly created one.
Common mistake — Filters are the most common place setups break. Double-check the field name and value exactly match what your app sends — a single capital letter difference will block everything.
7

Workflow Canvas > + Add Step > HubSpot > Create Deal

Create the HubSpot deal

Add another HubSpot step and choose the action 'Create Deal'. Map the deal fields from the Shopify order payload. Set dealname to the Shopify order number, amount to the parsed total_price, pipeline to your target HubSpot pipeline ID, and dealstage to the appropriate stage ID for a closed/won or new purchase deal. Use the closedate field set to the Shopify order's created_at date.

  1. 1Click '+ Add a step' and select HubSpot
  2. 2Choose 'Create Deal'
  3. 3Set dealname to {{steps.trigger.event.order_number}} or a formatted string like 'Shopify Order #{{steps.trigger.event.order_number}}'
  4. 4Set amount to parseFloat({{steps.trigger.event.total_price}})
  5. 5Set pipeline and dealstage using your HubSpot pipeline and stage IDs
  6. 6Set closedate to {{steps.trigger.event.created_at}}
What you should see: The step returns a deal object with a numeric id field — this is the new HubSpot deal ID you'll use in the next step to associate the contact.
Common mistake — Pipeline and dealstage require internal HubSpot IDs, not the display names you see in the UI. Find them by going to HubSpot Settings > CRM > Deals > Pipelines and hovering over each stage — the ID appears in the URL or via the Pipelines API at /crm/v3/pipelines/deals.
8

Workflow Canvas > + Add Step > HubSpot > Create Association

Associate the deal with the HubSpot contact

Add a HubSpot step and select 'Create Association'. Set the from object type to 'deals', the from object ID to the deal ID returned in step 7, the to object type to 'contacts', and the to object ID to the contact ID from step 6. This links the deal to the customer record so it appears on their contact timeline in HubSpot and sales reps can access the full purchase history from one place.

  1. 1Click '+ Add a step' and select HubSpot
  2. 2Choose 'Create Association'
  3. 3Set fromObjectType to 'deals'
  4. 4Set fromObjectId to {{steps.create_deal.id}}
  5. 5Set toObjectType to 'contacts'
  6. 6Set toObjectId to {{steps.upsert_contact.contactId}}
What you should see: A 200 response with no body content confirms the association was created. Check the contact's record in HubSpot — the deal should now appear in the 'Deals' sidebar panel on their contact page.
9

Workflow Canvas > + Add Step > Node.js Code

Add error handling for API failures

Add a final Node.js code step that checks whether the deal creation or association steps threw errors. Use try/catch blocks and Pipedream's $.send.http() or emit capabilities to log failures to a Slack channel or a Google Sheet. Without this, failed runs are silent — you'll only discover missing deals when a sales rep notices the gap days later.

  1. 1Click '+ Add a step' and select 'Run Node.js code'
  2. 2Wrap the error check logic in a try/catch
  3. 3Use $.send.http() to POST error details to a Slack webhook URL
  4. 4Include the Shopify order number and error message in the payload so failures are actionable
What you should see: On a successful run, this step exits cleanly. On a failed upstream step, you receive a Slack message like 'Deal creation failed for Shopify Order #4521 — HubSpot API returned 429 rate limit error.'
Common mistake — Pipedream retries failed steps automatically up to 8 times with exponential backoff by default. If your error handler fires on a retry that eventually succeeds, you may get false-positive failure alerts. Add a check for $.context.retryCount to suppress alerts on non-final retries.
10

pipedream.com > Workflows > [Your Workflow] > Inspector

Test the full workflow end to end

Place a real test order in your Shopify store using the Bogus Gateway. Watch the Pipedream workflow execution in the 'Inspector' tab — each step lights up green as it completes. Verify the deal appears in HubSpot under the correct pipeline within 30 seconds. Check that the contact association is visible on the customer's HubSpot contact record. Confirm the deal amount matches the Shopify order total exactly.

  1. 1Place a test order in your Shopify store
  2. 2Switch to Pipedream and open the Inspector tab
  3. 3Watch each step execute in sequence
  4. 4Open HubSpot and search for the deal by the order number
  5. 5Click into the deal and verify the contact association is present
What you should see: Every step shows a green checkmark in the Inspector, execution time is under 5 seconds total, and the HubSpot deal record shows the correct amount, pipeline stage, and linked contact.
11

Workflow Canvas > Active Toggle > Settings > Notifications

Enable and monitor the workflow

Toggle the workflow from 'Paused' to 'Active' using the switch in the top-right of the workflow canvas. Set up Pipedream's built-in alerting under Settings > Notifications to email you if the workflow errors more than 3 times in an hour. Check the Inspector daily for the first week to catch any edge cases — unusual order structures like gift cards or subscription products can produce unexpected payload shapes.

  1. 1Click the 'Active' toggle in the top-right corner of the canvas
  2. 2Go to Settings > Notifications
  3. 3Enable email alerts for workflow errors
  4. 4Set the threshold to 3 errors per hour
  5. 5Bookmark the Inspector URL to check execution logs easily
What you should see: The workflow status badge in the sidebar shows 'Active' in green. Incoming Shopify orders now trigger the workflow automatically — you should see new executions appear in the Inspector within seconds of real orders.

Paste this into a Node.js code step placed between the HubSpot contact search step and the deal creation step. It handles contact upsert logic, parses the Shopify price string to a float, deduplicates by order ID using Pipedream's built-in data store, and exports a clean object your downstream HubSpot steps can reference directly.

JavaScript — Code Stepimport { axios } from '@pipedream/platform';
▸ Show code
import { axios } from '@pipedream/platform';
export default defineComponent({
  async run({ steps, $ }) {

... expand to see full code

import { axios } from '@pipedream/platform';

export default defineComponent({
  async run({ steps, $ }) {
    const order = steps.trigger.event;
    const orderId = String(order.id);
    const orderTotal = parseFloat(order.total_price);

    // Deduplication: skip if this order was already processed
    const processed = await $.data.get(`shopify_order_${orderId}`);
    if (processed) {
      $.flow.exit(`Order ${orderId} already processed. Skipping.`);
    }

    // Resolve contact ID from search results or create new contact
    const searchResults = steps.search_hubspot_contact.$return_value;
    let contactId;

    if (searchResults.total > 0) {
      contactId = searchResults.results[0].id;
      console.log(`Existing HubSpot contact found: ${contactId}`);
    } else {
      // Create new HubSpot contact
      const newContact = await axios($, {
        method: 'POST',
        url: 'https://api.hubapi.com/crm/v3/objects/contacts',
        headers: {
          Authorization: `Bearer ${process.env.HUBSPOT_API_TOKEN}`,
          'Content-Type': 'application/json',
        },
        data: {
          properties: {
            email: order.customer.email,
            firstname: order.customer.first_name,
            lastname: order.customer.last_name,
            phone: order.customer.phone || '',
          },
        },
      });
      contactId = newContact.id;
      console.log(`New HubSpot contact created: ${contactId}`);
    }

    // Validate order total parsed correctly
    if (isNaN(orderTotal) || orderTotal <= 0) {
      throw new Error(`Invalid order total for order ${orderId}: '${order.total_price}'`);
    }

    // Mark order as processed to prevent duplicates
    await $.data.set(`shopify_order_${orderId}`, {
      processedAt: new Date().toISOString(),
      contactId,
    });

    // Export clean data for downstream steps
    return {
      contactId,
      orderTotal,
      dealName: `Shopify Order ${order.name}`,
      closeDate: order.created_at,
      shopifyOrderId: orderId,
      lineItemCount: order.line_items?.length || 0,
    };
  },
});

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 Pipedream for this if your team includes at least one developer who will maintain the workflow, or if you need the flexibility to write custom logic — deduplication, conditional contact creation, or line item mapping — that no-code tools can't handle cleanly. Pipedream's webhook latency is under 100ms and the Node.js environment means you're not fighting a visual interface to do a parseFloat(). The one scenario where you'd pick something else: if your entire team is non-technical and you want someone other than the original builder to troubleshoot it at 11pm — Zapier or Make are easier for non-coders to read and fix on the fly.

Cost

Pipedream's pricing is credit-based. This workflow runs roughly 6 steps per execution — trigger, filter, HubSpot contact search, Node.js code, deal creation, association. That's approximately 6 credits per order on Pipedream's Basic plan ($19/month for 10,000 credits). At 500 orders/month, you're using 3,000 credits — well inside the plan. At 1,500 orders/month, you're at 9,000 credits, still on Basic. Compare that to Zapier, where the same workflow requires a multi-step Zap on the Professional plan at $49/month with a 2,000 task cap — 1,500 orders consume 1,500 tasks minimum, leaving little headroom. Pipedream is cheaper by $30/month at 1,500 orders and the gap widens as volume grows.

Tradeoffs

Zapier has better pre-built HubSpot and Shopify actions — no code required to create deals or search contacts, and the UI is faster to configure for someone who hasn't used Pipedream before. Make's scenario builder lets you visually see data flowing between modules, which makes field mapping easier to audit and debug without reading JSON. n8n's self-hosted option costs nothing at any volume and has solid HubSpot nodes, making it the right call for high-volume stores that don't want per-execution costs. Power Automate has native Microsoft 365 integration that matters zero here — skip it for this use case entirely. Pipedream wins because the combination of instant webhooks, real Node.js, and a generous credit model handles this workflow cleanly without forcing workarounds.

Three things you'll hit after go-live. First, Shopify's webhook system is not guaranteed-once — it retries failed deliveries up to 19 times over 48 hours. If your Pipedream workflow returns a 500 error on the first attempt, Shopify will try again and you'll get duplicate deal creation unless you have the order ID deduplication step in place. Second, HubSpot's deal API silently accepts invalid pipeline or dealstage IDs in some API versions — it creates the deal but places it in a default or archived stage with no error. You won't notice until a sales rep wonders why deals are disappearing. Third, Shopify returns prices in the store's currency but doesn't always include the currency code in the standard order webhook payload — if your HubSpot account uses a different default currency, amounts will be numerically correct but labeled wrong. Explicitly set the deal_currency_code property using order.currency from the webhook payload.

Ideas for what to build next

  • Add high-value deal routing to a Slack channelExtend the workflow with a Slack step after deal creation that posts to #sales-wins when the order total exceeds a threshold like $500 — gives the team instant visibility into upsell targets without checking HubSpot.
  • Enroll new deals in a HubSpot upsell sequenceUse the HubSpot Enrollments API to add the associated contact to a follow-up email sequence immediately after deal creation — automates the first-touch upsell outreach within minutes of purchase.
  • Sync HubSpot deal updates back to Shopify customer tagsBuild a reverse workflow that listens for HubSpot deal stage changes and applies Shopify customer tags like 'upsell-target' or 'vip' — lets Shopify marketing segments stay in sync with sales activity.

Related guides

Was this guide helpful?
HubSpot + Shopify overviewPipedream profile →