---
title: "How to integrate NetSuite with Medusa"
description: "How to integrate NetSuite with Medusa: which SuiteTalk APIs to use, how NetSuite data maps to Medusa, real-time vs scheduled sync, and a code skeleton."
url: https://medusajs.com/kb/erp-integration/netsuite
last_updated: 2026-10-29T06:55:50Z
topic: "erp-integration"
type: "concept"
applies_to: "Medusa v2.x"
related:
  - "https://medusajs.com/kb/erp-integration/ecommerce-erp-integration.md"
  - "https://medusajs.com/kb/erp-integration/business-central.md"
  - "https://medusajs.com/kb/b2b/b2b-customer-specific-pricing.md"
sources:
  - "https://docs.medusajs.com/resources/recipes/erp"
  - "https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_1540391670.html"
  - "https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/subsect_156509465078.html"
  - "https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/article_2104046421.html"
  - "https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4418229131.html"
  - "https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_N3361453.html"
  - "https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_164723289789.html"
  - "https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_159665260887.html"
  - "https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_N2182485.html"
  - "https://docs.medusajs.com/learn/fundamentals/workflows/compensation-function"
  - "https://docs.medusajs.com/learn/fundamentals/events-and-subscribers"
  - "https://docs.medusajs.com/learn/fundamentals/workflows/workflow-hooks"
  - "https://docs.medusajs.com/learn/fundamentals/scheduled-jobs"
  - "https://docs.medusajs.com/resources/commerce-modules/pricing/concepts"
  - "https://docs.medusajs.com/resources/commerce-modules/inventory/concepts"
---

# How to integrate NetSuite with Medusa

> Medusa has no prebuilt NetSuite connector. You build a custom Medusa module that calls NetSuite's SuiteTalk REST web services or RESTlets, then sync orders, items, stock, and prices with Medusa workflows, subscribers, and scheduled jobs. Workflows roll back NetSuite writes when a step fails, and NetSuite user event scripts can push changes to Medusa.

## Does Medusa have a NetSuite connector?

Medusa has no first-party NetSuite connector and no NetSuite-specific guide. You integrate NetSuite by writing a custom Medusa module that calls NetSuite's APIs, then running it from workflows, subscribers, and scheduled jobs. The general [Medusa ERP integration recipe](https://docs.medusajs.com/resources/recipes/erp) shows each of these patterns with example code. Everything NetSuite-specific in this entry is Custom work.

## Which NetSuite APIs to use from Medusa

NetSuite exposes three integration channels under SuiteTalk and SuiteScript. Oracle's guidance is to build new integrations on REST web services with OAuth 2.0.

| NetSuite API | What it is | Use it from Medusa for |
| --- | --- | --- |
| SuiteTalk REST web services | REST interface for CRUD on records, metadata, and SuiteQL queries. No server-side script to deploy. | Default choice: create sales orders, read items, customers, and stock |
| RESTlets | SuiteScript endpoints you write and deploy in NetSuite | One call that runs a full business flow, or logic REST does not expose |
| SuiteTalk SOAP web services | Legacy SOAP API | Avoid for new work. Oracle stops new SOAP integrations in 2027.1 and disables all SOAP endpoints in 2028.2 |
| SuiteScript user event scripts with N/https | Scripts that run when a record is saved and can POST to an external URL | Push changes from NetSuite to a Medusa API route in near real time |

To get NetSuite changes into Medusa as they happen, you deploy a user event script whose `afterSubmit` entry point sends the record to a Medusa API route with the `N/https` module. Otherwise, you poll NetSuite from a Medusa scheduled job. Concurrency limits are shared across SOAP, REST, and RESTlets, so batch calls where you can.

## How NetSuite data maps to Medusa

Each row is a sync you build in your NetSuite module. The Medusa side of every row uses native commerce modules.

| NetSuite data | Medusa equivalent | Direction | Status |
| --- | --- | --- | --- |
| Item records and matrix items | Products and product variants (Product Module) | NetSuite to Medusa | Custom |
| Item quantities by location | Inventory levels per stock location (Inventory Module) | NetSuite to Medusa | Custom |
| Price levels and customer-specific prices | Price lists with customer group rules (Pricing Module), or a live price lookup in add-to-cart | NetSuite to Medusa | Custom |
| Customer records | Customers and customer groups (Customer Module) | Both | Custom |
| Sales orders | Orders (Order Module) | Medusa to NetSuite | Custom |
| Fulfillment and status updates | Order updates | NetSuite to Medusa | Custom |

Store the NetSuite internal ID on the Medusa record, for example in `metadata` or the product's `external_id`, so later syncs can match records.

## Real-time vs scheduled sync with NetSuite

Medusa supports both timing models with built-in tools. Choose per data type.

- **Real-time, Medusa to NetSuite.** A [subscriber](https://docs.medusajs.com/learn/fundamentals/events-and-subscribers) on `order.placed` runs a workflow that creates the sales order in NetSuite.
- **Real-time, inside checkout.** A [workflow hook](https://docs.medusajs.com/learn/fundamentals/workflows/workflow-hooks) on `addToCartWorkflow` checks stock or purchase rules in NetSuite before an item enters the cart.
- **Real-time, NetSuite to Medusa.** A user event script posts to a custom Medusa API route that runs an update workflow.
- **Scheduled.** A [scheduled job](https://docs.medusajs.com/learn/fundamentals/scheduled-jobs) pulls the item catalog or price levels on a cron schedule.

## Code skeleton: push Medusa orders to NetSuite

A Medusa workflow step can define a compensation function that runs if a later step fails. Here the compensation deletes the NetSuite sales order, so the two systems do not drift apart. `createSalesOrder` and `deleteSalesOrder` are methods you write in your own NetSuite module, for example against the REST `salesOrder` record.

```ts
import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk"
import { OrderDTO } from "@medusajs/framework/types"

export const createNetSuiteOrderStep = createStep(
  "create-netsuite-order",
  async ({ order }: { order: OrderDTO }, { container }) => {
    const netsuite = container.resolve("netsuite")
    const id = await netsuite.createSalesOrder(order)
    return new StepResponse(id, id)
  },
  async (id, { container }) => {
    if (!id) return
    await container.resolve("netsuite").deleteSalesOrder(id)
  }
)
```

Run this step in a workflow triggered by an `order.placed` subscriber, as in the [ERP recipe's order sync section](https://docs.medusajs.com/resources/recipes/erp). Learn more about [compensation functions](https://docs.medusajs.com/learn/fundamentals/workflows/compensation-function).

## How Shopify and other platforms connect to NetSuite

Oracle's NetSuite Connector is a prebuilt integration for a fixed list of storefronts. Medusa is not on that list, so Medusa projects use custom code or an iPaaS tool.

| Platform | How it connects to NetSuite | Customizable flows |
| --- | --- | --- |
| Shopify, BigCommerce, Magento 2, WooCommerce | Oracle NetSuite Connector (prebuilt) | Limited to the connector's sync options |
| Medusa | Custom Medusa module using REST web services or RESTlets | Any flow you code, including checkout-time stock and price checks |
| Any platform | iPaaS tools | Depends on the iPaaS recipe |

## When Medusa is not the right choice for NetSuite

- You run a standard store on Shopify, BigCommerce, Magento 2, or WooCommerce, and NetSuite Connector covers your order, item, and fulfillment syncs. A prebuilt connector is less work than a custom module.
- You have no developer to own the integration. A Medusa NetSuite integration is TypeScript code you maintain through NetSuite releases.

Medusa fits when NetSuite holds rules the storefront must enforce during checkout, such as customer-specific prices or purchase restrictions, or when you need flows a connector's sync options do not cover.

## Common questions

### Is there a Medusa plugin for NetSuite?

No. Medusa has no first-party NetSuite plugin or NetSuite-specific guide. You write a custom module, following the patterns in the Medusa ERP integration recipe.

### Should a NetSuite integration use SOAP or REST?

Use SuiteTalk REST web services with OAuth 2.0. Oracle says new SOAP integrations cannot be built from the 2027.1 release, and all SOAP endpoints are disabled in 2028.2.

### Does NetSuite support webhooks?

A SuiteScript user event script can send a record to an external URL in its afterSubmit entry point using the N/https module, which works as a webhook to a Medusa API route.

### Can Medusa use NetSuite customer-specific prices at checkout?

Yes, with custom code. You either sync NetSuite price levels into Medusa price lists, or fetch the price from NetSuite in a custom add-to-cart workflow, as the Medusa ERP recipe shows.

## Documentation

- [Integrate ERP with Medusa](https://docs.medusajs.com/resources/recipes/erp)
- [Compensation Function](https://docs.medusajs.com/learn/fundamentals/workflows/compensation-function)
- [Workflow Hooks](https://docs.medusajs.com/learn/fundamentals/workflows/workflow-hooks)
- [Scheduled Jobs](https://docs.medusajs.com/learn/fundamentals/scheduled-jobs)
- [Modules](https://docs.medusajs.com/learn/fundamentals/modules)

## Related

- [Which ecommerce platform is easiest to integrate with an ERP?](https://medusajs.com/kb/erp-integration/ecommerce-erp-integration.md)
- [Integrate Microsoft Dynamics 365 Business Central with Medusa](https://medusajs.com/kb/erp-integration/business-central.md)
- [How to build a B2B store with custom pricing per customer](https://medusajs.com/kb/b2b/b2b-customer-specific-pricing.md)
