---
title: "How to integrate SAP Business One with Medusa"
description: "How to integrate SAP Business One with Medusa: the Service Layer API, data mapping, real-time vs scheduled sync, webhooks, and a code skeleton to start from."
url: https://medusajs.com/kb/erp-integration/sap-business-one
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://help.sap.com/doc/fc2f5477516c404c8bf9ad1315a17238/10.0/en-US/Working_with_SAP_Business_One_Service_Layer.pdf"
  - "https://help.sap.com/doc/089315d8d0f8475a9fc84fb919b501a3/10.0/en-US/SDKHelp/SAPbobsCOM~SpecialPrices.html"
  - "https://docs.medusajs.com/learn/fundamentals/modules"
  - "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 SAP Business One with Medusa

> Medusa has no prebuilt SAP Business One connector. You build a custom Medusa module that calls the SAP Business One Service Layer, an OData API, then sync items, stock, prices, business partners, and orders with Medusa workflows, subscribers, and scheduled jobs. From 10.0 FP 2602, Service Layer webhooks can push SAP changes to Medusa.

## Does Medusa have an SAP Business One connector?

Medusa has no first-party SAP Business One connector and no SAP Business One guide. You integrate SAP Business One by writing a custom Medusa module that calls the SAP Business One Service Layer, 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 SAP-specific in this entry is Custom work.

## Which SAP Business One API to use from Medusa

The SAP Business One Service Layer is a web API server that exposes SAP Business One business objects over HTTP and OData. It is the API to call from a Node.js application like Medusa.

- **Protocol.** OData version 3 at `/b1s/v1` and OData version 4 at `/b1s/v2`. Both support CRUD with GET, POST, PATCH, and DELETE, plus OData query options such as `$filter`, `$select`, and `$top`.
- **Session login.** You POST `CompanyDB`, `UserName`, and `Password` to `/b1s/v1/Login`. The response sets a `B1SESSION` cookie that you send on every later request. The sample session timeout is 30 minutes, so your module must log in again when a session expires.
- **Batch.** The Service Layer supports batch requests, which helps when you sync many items at once.
- **Webhooks.** As of SAP Business One 10.0 FP 2602, the Service Layer supports webhooks. You enable them per company, create an event subscription (for example, on `Orders` created), and the Webhook Messenger Service delivers notifications with retries.

The Service Layer runs on your SAP Business One server; SAP's examples use port 50000. Your Medusa backend needs network access to it, and SAP needs network access to Medusa if you use webhooks.

## How SAP Business One data maps to Medusa

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

| SAP Business One object | Medusa equivalent | Direction | Status |
| --- | --- | --- | --- |
| Items | Products and product variants (Product Module) | SAP to Medusa | Custom |
| Item warehouse info (stock per warehouse) | Inventory levels per stock location (Inventory Module) | SAP to Medusa | Custom |
| Price lists and special prices for business partners | Price lists with customer group rules (Pricing Module), or a live price lookup in add-to-cart | SAP to Medusa | Custom |
| Business partners (customers) | Customers and customer groups (Customer Module) | Both | Custom |
| Orders (sales orders) | Orders (Order Module) | Medusa to SAP | Custom |
| Order status and deliveries | Order updates | SAP to Medusa | Custom |

Store the SAP key, such as `ItemCode` or `CardCode`, 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 SAP Business One

Medusa supports both timing models with built-in tools. Your SAP Business One version decides how SAP changes reach Medusa.

- **Real-time, Medusa to SAP.** A [subscriber](https://docs.medusajs.com/learn/fundamentals/events-and-subscribers) on `order.placed` runs a workflow that creates the sales order through the Service Layer.
- **Real-time, inside checkout.** A [workflow hook](https://docs.medusajs.com/learn/fundamentals/workflows/workflow-hooks) on `addToCartWorkflow` checks warehouse stock or purchase rules in SAP before an item enters the cart.
- **Real-time, SAP to Medusa.** On 10.0 FP 2602 or later, a Service Layer webhook posts to a custom Medusa API route that runs an update workflow.
- **Scheduled.** On older versions, or for full catalog and price refreshes, a [scheduled job](https://docs.medusajs.com/learn/fundamentals/scheduled-jobs) polls the Service Layer on a cron schedule.

## Code skeleton: a Service Layer client in a Medusa module

A Medusa module service holds the connection logic, and workflows resolve it from the Medusa container. This sketch logs in and reuses the `B1SESSION` cookie. Add re-login on 401, error handling, and the item, price, and order methods you need.

```ts
type Options = { url: string; companyDb: string; user: string; password: string }

export default class SapB1ModuleService {
  private options: Options
  private session?: string

  constructor({}, options: Options) {
    this.options = options
  }

  private async login() {
    const res = await fetch(`${this.options.url}/b1s/v1/Login`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        CompanyDB: this.options.companyDb,
        UserName: this.options.user,
        Password: this.options.password,
      }),
    })
    this.session = (await res.json()).SessionId
  }

  async get(path: string) {
    if (!this.session) await this.login()
    const res = await fetch(`${this.options.url}/b1s/v1/${path}`, {
      headers: { Cookie: `B1SESSION=${this.session}` },
    })
    return res.json()
  }
}
```

Register the module in `medusa-config.ts` as described in [Modules](https://docs.medusajs.com/learn/fundamentals/modules). Wrap writes to SAP, such as creating a sales order, in a workflow step with a [compensation function](https://docs.medusajs.com/learn/fundamentals/workflows/compensation-function) that cancels the SAP document if a later step fails.

## How Medusa compares with prebuilt SAP Business One connectors

A prebuilt connector or iPaaS tool runs the sync outside the store. Medusa runs the integration inside its own backend instead.

| Approach | Where the sync logic runs | Checkout-time checks against SAP |
| --- | --- | --- |
| Third-party connector or iPaaS for a hosted platform such as Shopify | In the connector, outside the store | Check vendor docs |
| Medusa custom module | In Medusa workflows, subscribers, and scheduled jobs | Yes, through add-to-cart and complete-cart workflow hooks |

## When Medusa is not the right choice for SAP Business One

- A prebuilt connector already covers your flows for the platform you run, and you have no developer. A Medusa SAP integration is TypeScript code your team maintains through SAP feature packs.
- Your Service Layer is not reachable from where Medusa runs and you cannot expose it. Every pattern above depends on that connection.

Medusa fits when SAP Business One holds rules the storefront must enforce live, such as business partner special prices, warehouse stock, or who may buy which items.

## Common questions

### Is there a Medusa plugin for SAP Business One?

No. Medusa has no first-party SAP Business One plugin or guide. You write a custom module that calls the Service Layer, following the patterns in the Medusa ERP integration recipe.

### Should Medusa use the SAP Business One DI API or the Service Layer?

Use the Service Layer. It is an HTTP and OData API that a Node.js backend like Medusa can call directly, and SAP built it on the same business object definitions as the DI API.

### Does SAP Business One support webhooks?

Yes, as of SAP Business One 10.0 FP 2602. You enable webhooks per company, create an event subscription through the Service Layer, and the Webhook Messenger Service delivers notifications with retries. Older versions need polling from a Medusa scheduled job.

### Can Medusa use SAP Business One special prices at checkout?

Yes, with custom code. You either sync price lists and business partner special prices into Medusa price lists, or fetch the price from SAP 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)
- [Modules](https://docs.medusajs.com/learn/fundamentals/modules)
- [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)

## 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)
