hotchand/module-hubspot-sync

Magento 2 extension to seamlessly synchronize customers and orders to HubSpot CRM.

Maintainers

Package info

github.com/Hotchand/Magento2---sync-orders-and-customers-to-Hubspot-CRM

Type:magento2-module

pkg:composer/hotchand/module-hubspot-sync

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-08-05 21:45 UTC

This package is auto-updated.

Last update: 2026-08-05 21:46:02 UTC


README

Syncs Magento 2 customers → HubSpot contacts and orders → HubSpot deals (associated to the matching contact by email).

Why a queue instead of calling the API on save?

Calling out to HubSpot synchronously from customer_save_after / sales_order_save_after would add API latency to checkout and admin saves, and a HubSpot outage or rate limit would start throwing errors at your customers. Instead:

  1. Observers just write a row to hotchand_hubspot_sync_queue (fast, local, no network call).
  2. A cron job (*/5 * * * * by default) picks up pending rows in batches and calls the HubSpot CRM v3 API, using the batch upsert endpoint for contacts (up to 100 per request) to stay well inside rate limits.
  3. Failures are retried up to max_attempts times, then marked failed and visible in the admin grid under Sales → HubSpot Sync Queue.

Installation

# if pulling from a private repo / packagist
composer require hotchand/module-hubspot-sync

# or copy the app/code/Hotchand/HubspotSync directory directly, then:
bin/magento module:enable Hotchand_HubspotSync
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush

If installing via composer require, place these files under app/code/Hotchand/HubspotSync for a straight code-drop, or set up a private Packagist/Satis repo pointing at this package for a proper Composer install.

Configuration

Stores → Configuration → Hotchand → HubSpot Sync

  1. In HubSpot, create a Private App (Settings → Integrations → Private Apps) with these scopes:
    • crm.objects.contacts.write
    • crm.objects.contacts.read
    • crm.objects.deals.write
    • crm.objects.deals.read
  2. Copy the generated access token into Private App Access Token.
  3. Set Enable HubSpot Sync to Yes.
  4. Optionally adjust the Order Status → Deal Stage Map JSON to match your HubSpot pipeline's internal stage IDs (find these under Settings → Objects → Deals → Pipelines; click a stage to see its internal ID).

Backfilling existing data

bin/magento hotchand:hubspot:resync-customers
bin/magento hotchand:hubspot:resync-orders            # all orders
bin/magento hotchand:hubspot:resync-orders --days=90   # last 90 days only

# then either wait for cron, or force an immediate run:
bin/magento hotchand:hubspot:process-queue

Custom deal properties

OrderSync pushes two custom properties: magento_order_increment_id and magento_order_status. Create these as custom properties on the Deal object in HubSpot (Settings → Properties → Deal properties) before enabling, or remove them from Model/Sync/OrderSync.php if you'd rather not extend the HubSpot schema.

Notes / things to verify against current HubSpot docs before going live

  • The deal↔contact association call in HubspotClient::upsertDeal() uses the default association label deal_to_contact. HubSpot's association API has changed shape a few times — confirm the current default association type/label (or association type ID) in HubSpot's CRM Associations v4 docs and adjust that one call if needed.
  • HubSpot enforces API rate limits per account tier (typically 100–190 requests per 10 seconds, higher on paid tiers). The batch endpoints used here keep this module well under that for most stores, but if you have a very high order volume, consider lowering the cron frequency or increasing batch_size so fewer, larger requests are made.
  • This module intentionally does not delete or deduplicate existing HubSpot contacts — it only upserts by email.

Magento2---sync-orders-and-customers-to-Hubspot-CRM