Integrate Microsoft Dynamics 365 Business Central with Medusa

Type
Concept
Applies to
Medusa v2.x
Updated

Short answer

Medusa has no first-party Business Central connector, so you build one as a custom Medusa module that calls the Business Central API v2.0. Orders push to Business Central sales orders from an order.placed subscriber with rollback, Business Central webhooks drive order status updates, and scheduled jobs sync stock and customer prices into Medusa.

How a Business Central integration with Medusa works

Medusa has no first-party connector for Microsoft Dynamics 365 Business Central. You build the integration as a custom Medusa module that calls the Business Central API v2.0, a REST API on OData v4. Workflows, subscribers, scheduled jobs and API routes then use that module, following Medusa's ERP recipe.

Business Central pushes changes through webhooks:

  • You register with Copy to clipboardPOST /api/v2.0/subscriptions, and your endpoint must echo the Copy to clipboardvalidationToken with a Copy to clipboard200 response.
  • Subscriptions expire after three days unless renewed with a Copy to clipboardPATCH.
  • A notification carries the changed record's URL and a change type, not the record itself, so you Copy to clipboardGET the record afterwards.
  • Supported entities include Copy to clipboarditems, Copy to clipboardcustomers, Copy to clipboardsalesOrders and Copy to clipboardsalesInvoices. Item ledger entries, which hold stock movements, are not on the list.
  • If more than 1,000 records change within 30 seconds, you get one Copy to clipboardcollection notification with a filter instead of one per record.

Mapping Business Central data to Medusa

Each Business Central entity maps to a Medusa commerce module. Statuses describe the Medusa side.

Business CentralMedusaDirectionMechanismStatus
items, itemVariantsProducts and variants, with the BC ID in external_id or metadataBC to MedusaScheduled job, plus items webhookOfficial guide
item inventory (read-only field)Inventory levels via updateInventoryLevelsWorkflowBC to MedusaScheduled job, plus a live check at add-to-cartCustom (scheduled sync); Official guide (live check at add-to-cart)
Customer price groups and price listsPrice lists with customer group rulesBC to MedusaScheduled job reading a custom BC API pageCustom
customersCustomers and customer groupsBothWebhook in, subscriber outCustom
salesOrders, salesOrderLinesOrdersMedusa to BC, status backorder.placed subscriber; salesOrders webhookOfficial guide

The standard API v2.0 has no price list or customer price group resource; items expose a single Copy to clipboardunitPrice. To sync customer-specific prices, publish a custom API page in AL. Custom API pages can also send webhooks if they meet Business Central's webhook requirements.

Real-time or scheduled sync for each Business Central flow

Pick the trigger per flow, not per integration:

  • Orders: real time. An Copy to clipboardorder.placed subscriber runs a workflow that creates the BC sales order.
  • Order status: real time. A Copy to clipboardsalesOrders webhook calls a Medusa API route that fetches the order and updates Medusa. A scheduled job renews the subscription before its three days run out.
  • Stock: scheduled, because stock movements don't fire webhooks. For exact stock, check BC in the Copy to clipboardvalidate hook of Copy to clipboardaddToCartWorkflow.
  • Prices: scheduled into Medusa price lists, or fetched per cart with a custom item price workflow.

Business Central online allows 6,000 OData requests per user in a 5-minute window, 5 concurrent requests, and 100 operations per Copy to clipboard$batch. Above the limits it returns Copy to clipboard429. Set Copy to clipboardmaxRetries and Copy to clipboardretryInterval on steps that call BC; a Copy to clipboardretryInterval makes the workflow long-running.

Code skeleton: push a Medusa order to Business Central with rollback

This skeleton assumes a custom module registered as Copy to clipboardbc whose service wraps Copy to clipboardsalesOrders create and delete calls. The compensation function deletes the BC sales order if the metadata update fails.

// src/workflows/sync-order-to-bc.ts
import { createStep, createWorkflow, StepResponse, WorkflowResponse } from "@medusajs/framework/workflows-sdk"
import { updateOrderWorkflow, useQueryGraphStep } from "@medusajs/medusa/core-flows"
import { OrderDTO } from "@medusajs/framework/types"
const createBcSalesOrderStep = createStep(
{ name: "create-bc-sales-order", maxRetries: 3 },
async ({ order }: { order: OrderDTO }, { container }) => {
const bcOrderId = await container.resolve("bc").createSalesOrder(order)
return new StepResponse(bcOrderId, bcOrderId)
},
async (bcOrderId, { container }) => {
if (!bcOrderId) return
await container.resolve("bc").deleteSalesOrder(bcOrderId)
}
)
export const syncOrderToBcWorkflow = createWorkflow(
"sync-order-to-bc",
({ order_id }: { order_id: string }) => {
// src/subscribers/order-placed-bc.ts
import type { SubscriberArgs, SubscriberConfig } from "@medusajs/framework"
import { syncOrderToBcWorkflow } from "../workflows/sync-order-to-bc"
export default async function orderPlacedBcHandler({ event: { data }, container }: SubscriberArgs<{ id: string }>) {
await syncOrderToBcWorkflow(container).run({ input: { order_id: data.id } })
}
export const config: SubscriberConfig = { event: "order.placed" }

Medusa compared with the Shopify Connector for Business Central

AspectShopify with Microsoft's Shopify ConnectorMedusa with a custom Business Central module
Who builds itMicrosoft. Preinstalled in new Business Central online environmentsYou or your agency
DeploymentBusiness Central online only, not on-premisesAny environment where the BC APIs are reachable
Sync triggerJob queue; Auto Sync Orders starts the order import job when Shopify reports a new orderMedusa events, BC webhooks and scheduled jobs
Customer pricesExports prices from selected customer price groups and discounts, plus B2B catalogsPrice lists with customer group rules, or a live BC price at add-to-cart
ERP rules in the cartShopify Functions; external fetch only for custom apps on Enterprise storesvalidate hook calls BC directly
UpkeepMicrosoft adopts new Shopify API versions in Business Central major releasesYou maintain the module as BC's API changes
LicensesBusiness Central and ShopifyBusiness Central, plus Medusa hosting: self-hosted, or Medusa Cloud from $29 per month with a 0% GMV fee

When Medusa is not the right choice for Business Central

  • You run Business Central online and Shopify, and the connector's syncs cover your order, stock and price flows. Use the connector.
  • You have no developer capacity. A Medusa integration is code you own.
  • You need a vendor-supported connector. Medusa has none for Business Central today.

Common questions

Is there a Medusa plugin for Business Central?

No. Medusa has no first-party or official plugin for Microsoft Dynamics 365 Business Central. You build the integration as a custom module following the Medusa ERP recipe.

Does Business Central send webhooks for stock changes?

Not directly. Business Central webhooks cover entities such as items, customers and salesOrders, but item ledger entries, which record stock movements, are not webhook-supported. Sync stock on a schedule or check it live during add-to-cart.

How do I sync Business Central customer prices to Medusa?

The standard Business Central API v2.0 has no price list resource, so publish a custom API page in AL that exposes price list lines. A Medusa scheduled job can then write them to price lists with customer group rules.

What are the Business Central API rate limits?

Business Central online allows 6,000 OData requests per user in a 5-minute sliding window and 5 concurrent requests per user, and returns HTTP 429 when limits are exceeded. A $batch request holds up to 100 operations.

Does the Shopify Connector work with Business Central on-premises?

No. Microsoft's Shopify Connector is available only for Business Central online. A Medusa integration calls the Business Central API, so it can target any environment where the APIs are enabled and reachable.