Skip to content

§00Connect

HubSpot ↔ Oracle NetSuite

Closed in HubSpot. Billed in NetSuite. “Paid” in Slack.

Revenue teams work in HubSpot, finance works in NetSuite, and the moment that matters to both — the customer paying — usually reaches sales last. Deals close, someone recreates them as sales orders, and the account owner hears about payment from a spreadsheet, or doesn’t. PartnerMCP connects the three: a closed HubSpot deal becomes a NetSuite customer and sales order, billing status flows back to the deal, and when NetSuite applies the payment, the deal owner hears it in Slack.

HubSpot → NetSuite
Sandbox

You

“Whenever a deal closes in HubSpot, create the customer and sales order in NetSuite. When payment arrives, update HubSpot and notify the account owner in Slack.”

PartnerMCP· I will:

  1. Detect Closed Won deals in HubSpot — deal.propertyChange on dealstage, checked against each pipeline’s won stage.
  2. Match or create the customer in NetSuite with one upsert by external ID (eid:), keyed on the HubSpot company’s record ID.
  3. Create the sales order from the deal’s line items — entity, item, quantity, rate — with the deal’s record ID as its external ID.
  4. Monitor invoice and payment status in NetSuite with SuiteQL on lastmodifieddate.
  5. Update the HubSpot deal with the sales order number, invoice status and payment date.
  6. Notify the account owner in Slack with chat.postMessage when the payment is applied — the deal’s HubSpot owner, matched by work email.
  7. Retry temporary failures automatically, within NetSuite’s account concurrency and HubSpot’s 10-second limits.
  8. Send unresolved errors for review, with the NetSuite or HubSpot message attached.
Deal · Closed WonCustomer lookupSchema mappingCreate / update customerCreate sales orderMonitor orderSync fulfillmentWatch paymentUpdate DealNotify owner
Integration plan: HubSpot ↔ Oracle NetSuite. HubSpot to Oracle NetSuite, notifying in Slack.
  1. Deal · Closed Won — HubSpot: Trigger · webhooks
  2. Customer lookup — PartnerMCP: companies ⇄ customer
  3. Schema mapping — PartnerMCP: fields · products · prices
  4. Create / update customer — NetSuite: customer
  5. Create sales order — NetSuite: salesorder + item sublist
  6. Monitor order — PartnerMCP: invoice · payment
  7. Sync fulfillment — NetSuite: itemfulfillment
  8. Watch payment — NetSuite: invoice → customerpayment
  9. Update Deal — HubSpot: payment status
  10. Notify owner — Slack: Slack · chat.postMessage
Product preview · sample data
§01—What syncs

What syncs, and which way.

Every record that moves between HubSpot and NetSuite: what starts it, and what it produces on the other side.

HubSpotNetSuite
  1. HubSpot to Oracle NetSuite:

    Deal → salesorder
    When
    deal.propertyChange on dealstage, into a won stage
    Result
    NetSuite sales order with the deal’s line items; its external ID is the deal’s record ID.
  2. HubSpot to Oracle NetSuite:

    Company → customer
    When
    First closed deal for the company
    Result
    Customer upserted through eid:; NetSuite’s internal ID stored on the company.
  3. Oracle NetSuite to HubSpot:

    invoice → Deal
    When
    SuiteQL poll finds an invoice created or changed for the order
    Result
    Invoice number and status on the deal.
  4. Oracle NetSuite to HubSpot:

    customerpayment → Deal + Slack
    When
    Payment applied to the order’s invoice
    Result
    Paid date on the deal, and a Slack message to the deal owner with the amount and the invoice.
  5. Oracle NetSuite to HubSpot:

    inventoryitem → products
    When
    Item changes in NetSuite, found with SuiteQL
    Result
    HubSpot products carry the NetSuite item reference in hs_sku, so each line item maps to a real item.
§02—Field mapping

Field by field.

Every mapping PartnerMCP proposes, with its transformation and confidence. Rules — keys, reconciliation, duplicate guards — carry no confidence: they’re decided and approved, not inferred.

HubSpot ⇄ NetSuite
Draft
  1. companies.hs_object_id

    to customer · eid:<record ID>

    PUT creates or updates in one call

    97% confidence
  2. companies.name

    to customer.companyName

    Trimmed to the field’s length

    97% confidence
  3. customer · internal ID

    to companies.netsuite_customer_id (custom)

    Written back after the upsert

    95% confidence
  4. deals.hs_object_id

    to salesorder · eid:<deal record ID>

    Looked up before every create

    Rule
    HubSpot can deliver the same event twice; the external ID makes the second one harmless.
  5. Associated company

    to salesorder.entity

    The customer’s internal ID

    96% confidence
    NetSuite fills many order fields from the entity.
  6. products.hs_sku (via line_items.hs_product_id)

    to item.items[].item

    Resolved to the item’s internal ID

    93% confidence
  7. line_items.quantity

    to item.items[].quantity

    Copied as-is

    97% confidence
  8. line_items.price

    to item.items[].rate

    Or left to NetSuite’s pricing when finance owns price

    86% confidence
  9. deals.amount

    to Sales order total — reconciled, not written

    Compared after SuiteTax calculates tax

    Rule
  10. Sales order number

    to deals.netsuite_order_no (custom)

    Written back after create

    96% confidence
  11. customerpayment · applied to the order’s invoice

    to deals.netsuite_paid_date (custom)

    Payment date and amount

    93% confidence
  12. deals.hubspot_owner_id

    to Slack user (chat.postMessage)

    Owner matched to a Slack user by work email

    90% confidence
    With no match, the message goes to a channel you choose.
10 field mappings · 2 rules Confidence Lower, or verify on tenant
Product preview · sample data
§03—Edge cases

Edge cases, handled.

What goes wrong between HubSpot and NetSuite in production, and what PartnerMCP does about it.

  1. 01

    Won stages are per pipeline

    HubSpot’s dealstage holds an internal ID, and each pipeline has its own. PartnerMCP reads the pipelines API and treats closed stages with probability 1.0 as won, so a second sales pipeline or a renamed stage doesn’t silently stop orders reaching NetSuite.

  2. 02

    At-least-once webhooks

    HubSpot sends up to 100 events per request, retries failures up to 10 times over 24 hours, makes no ordering promise and doesn’t guarantee that eventId is unique. PartnerMCP de-duplicates on the deal itself and looks for salesorder/eid:<deal ID> before creating anything.

  3. 03

    NetSuite has no outbound webhooks

    NetSuite doesn’t push changes out on its own. PartnerMCP polls with SuiteQL on lastmodifieddate by default; for faster updates it can deploy a SuiteScript User Event script that calls out after save, with the heavy work queued to a scheduled or map/reduce script so saves never wait on the network.

  4. 04

    Paid means applied

    A payment can cover part of one invoice or several invoices at once. PartnerMCP updates the deal when a payment is applied to the deal’s invoice, shows partial payments as partial and sends the owner one message per payment, never one per retry.

  5. 05

    Fulfillment may create the invoice

    Without Advanced Shipping, NetSuite combines fulfillment and invoicing: creating the item fulfillment also creates the invoice. With it, they are separate steps. PartnerMCP reads which way your account works before it maps billing status back to HubSpot.

  6. 06

    A pool shared with everyone

    Your NetSuite account has one concurrency limit for every integration — REST, RESTlets, SOAP and the AI Connector Service — so a busy sync can starve another. PartnerMCP stays inside the allocation set on its integration record and backs off instead of competing.

  7. 07

    Slack is rate-limited too

    chat.postMessage generally allows about one message per second per channel, and Slack answers 429 with Retry-After beyond that. PartnerMCP spaces notifications, honors Retry-After and keys each message on the payment, so nobody gets the same “paid” twice.

§04—Questions

Questions about HubSpot and NetSuite.

Does the account owner need to be in Slack?

No. If PartnerMCP can’t match the HubSpot deal owner to a Slack user by work email, it posts to a channel you choose — or skips the message — and the deal is updated either way.

Can we use HubSpot’s or NetSuite’s MCP servers?

Both exist: HubSpot’s remote MCP server, generally available since April 2026, and NetSuite’s AI Connector Service. They’re built for assistants working under a user’s permissions — the AI Connector’s SuiteQL tools are read-only, and it doesn’t accept the Administrator role. PartnerMCP runs the deal-to-cash flow on the REST APIs and webhooks, and can use either MCP server for conversational access.

How does it handle HubSpot’s API limits?

HubSpot private apps get 100 or 190 requests per 10 seconds depending on your tier, plus a daily limit that every app in the account shares; CRM search has its own limit of five requests per second. PartnerMCP reads and writes in batches by unique-identifier property and leaves headroom for your other apps.

How quickly does “paid” reach Slack?

As fast as the polling interval you choose for SuiteQL — or right after the payment is saved, if you let PartnerMCP deploy a SuiteScript User Event script in NetSuite that calls out.

Which NetSuite records does it touch?

It writes customers and sales orders and reads items, invoices and customer payments — through a dedicated role limited to those records, not an administrator.

§05—References

§06Build

Build this integration.

Start from this plan, or change it in your own words. PartnerMCP builds it against your HubSpot and NetSuite: sandbox first, production when you approve.