Microsoft Dynamics 365 Business Central is the ERP of choice for many mid-market companies, especially those already invested in the Microsoft ecosystem. Integrating it with WooCommerce requires understanding D365’s API landscape and choosing the right integration pattern for your scale and complexity.

D365 Business Central API Options

OData/REST APIs (Standard)

Business Central exposes standard entities via OData v4 endpoints:

GET https://{tenant}.api.businesscentral.dynamics.com/v2.0/{environment}/api/v2.0/items

GET https://{tenant}.api.businesscentral.dynamics.com/v2.0/{environment}/api/v2.0/salesOrders

GET https://{tenant}.api.businesscentral.dynamics.com/v2.0/{environment}/api/v2.0/customers

Authentication: OAuth 2.0 via Azure AD. Register an app in Azure Portal, grant Financials.ReadWrite.All permissions.

Custom APIs (AL Extensions)

For complex integrations, build custom API endpoints in Business Central using AL language:

page 50100 "WooCommerce Items API"

{

PageType = API;

APIPublisher = 'wpclan';

APIGroup = 'woocommerce';

APIVersion = 'v1.0';

EntityName = 'item';

EntitySetName = 'items';

SourceTable = Item;

// ... field definitions

}

Dataverse (Advanced)

For bi-directional sync with change tracking, Business Central can sync data to Dataverse (formerly Common Data Service). This provides webhook-like change notifications.

Integration Patterns

Pattern 1: Power Automate (Low-Code)

Best for: Simple integrations, < 100 orders/day

Microsoft Power Automate can connect D365 to WooCommerce via HTTP connectors:

Trigger: When a WooCommerce order is created (HTTP webhook)

→ Parse JSON (order data)

→ D365: Find or create customer

→ D365: Create sales order

→ D365: Add line items

→ WooCommerce: Update order meta with D365 reference

Pros: No code, visual workflow, built-in error handling
Cons: API call limits (Performance plan needed), slower execution, limited transformation logic

Pattern 2: Azure Functions + Service Bus (Cloud-Native)

Best for: Medium-high volume, Microsoft-stack teams

WooCommerce Webhook → Azure Function → Service Bus Queue → Azure Function → D365 API

D365 Change Feed → Azure Function → Service Bus Queue → Azure Function → WooCommerce API

Azure Functions handle the API calls and data transformation. Service Bus provides reliable message queuing with dead-letter support.

Pattern 3: Custom Node.js Middleware (Full Control)

Best for: Complex requirements, custom business logic

// D365 Business Central client

class D365Client {

constructor(tenantId, clientId, clientSecret, environment) {

this.baseUrl = https://api.businesscentral.dynamics.com/v2.0/${environment}/api/v2.0;

this.tokenUrl = https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token;

this.clientId = clientId;

this.clientSecret = clientSecret;

}

async getToken() {

const response = await fetch(this.tokenUrl, {

method: 'POST',

headers: { 'Content-Type': 'application/x-www-form-urlencoded' },

body: new URLSearchParams({

grant_type: 'client_credentials',

client_id: this.clientId,

client_secret: this.clientSecret,

scope: 'https://api.businesscentral.dynamics.com/.default'

})

});

const data = await response.json();

return data.access_token;

}

async getItems() {

const token = await this.getToken();

const response = await fetch(${this.baseUrl}/items, {

headers: { 'Authorization': Bearer ${token} }

});

return response.json();

}

async createSalesOrder(orderData) {

const token = await this.getToken();

return fetch(${this.baseUrl}/salesOrders, {

method: 'POST',

headers: {

'Authorization': Bearer ${token},

'Content-Type': 'application/json'

},

body: JSON.stringify(orderData)

});

}

}

Data Mapping: D365 → WooCommerce

Items to Products

D365 Field WooCommerce Notes
number sku Primary key for mapping
displayName name
unitPrice regular_price From price list
inventory stock_quantity Real-time critical
itemCategoryCode categories Map codes to WC category IDs
blocked status blocked=true → draft
gtin meta: _gtin For schema markup

Sales Orders

WooCommerce D365 Sales Order Notes
order.id externalDocumentNumber Cross-reference
billing.email customerNumber Match by email
line_items[].sku salesOrderLines[].itemId Match by item number
line_items[].quantity salesOrderLines[].quantity
line_items[].total salesOrderLines[].unitPrice Recalculate for discounts
shipping_total Add as separate line or freight charge

Handling D365’s Pagination

Business Central APIs return max 20,000 records and use @odata.nextLink for pagination:

async function getAllItems(client) {

let items = [];

let url = ${client.baseUrl}/items?$top=1000;

while (url) {

const response = await client.authenticatedFetch(url);

const data = await response.json();

items = items.concat(data.value);

url = data['@odata.nextLink'] || null;

}

return items;

}

Inventory Sync Strategy

D365 Business Central tracks inventory at the location (warehouse) level. Your sync must decide:

  • Sum all locations for a single WooCommerce stock count?
  • Sync specific locations (e.g., only the ecommerce warehouse)?
  • Reserve buffer stock (show 90% of actual stock to avoid overselling)?
async function syncInventory() {

const d365Items = await d365.getItems();

const updates = d365Items.value

.filter(item => !item.blocked)

.map(item => ({

sku: item.number,

stock_quantity: Math.floor(item.inventory * 0.95), // 5% buffer

stock_status: item.inventory > 0 ? 'instock' : 'outofstock'

}));

// Batch update WooCommerce

for (let i = 0; i < updates.length; i += 100) {

await wooApi.post('products/batch', {

update: updates.slice(i, i + 100).map(u => ({

sku: u.sku, // requires SKU lookup to get product ID

stock_quantity: u.stock_quantity,

stock_status: u.stock_status

}))

});

}

}

Common D365 Integration Pitfalls

  • OAuth token expiration: Tokens expire after 1 hour. Always refresh before API calls.
  • Rate limiting: Business Central has a 600 calls/minute limit per tenant. Batch your requests.
  • Number sequences: D365 auto-generates document numbers. Don’t try to set them manually.
  • Dimensions: D365’s financial dimensions (cost center, department) have no WooCommerce equivalent. Plan how to handle them.
  • Multi-currency: D365 handles multi-currency natively. WooCommerce needs a plugin for multi-currency. Map exchange rates carefully.

Conclusion

D365 Business Central + WooCommerce is a strong combination. Power Automate works for simple, low-volume integrations. Azure Functions suit Microsoft-stack teams needing reliability. Custom middleware gives you full control for complex scenarios. Regardless of the pattern, the fundamentals are the same: map your data carefully, handle inventory as the highest-priority sync, and build robust error handling from day one.

Leave a Reply

Your email address will not be published. Required fields are marked *

Close Search Window