🇹🇷 Türkçe: Bu yazının Türkçesini oku →

SAP Business One is one of the most widely used ERPs for mid-market businesses. Connecting it to WooCommerce creates a powerful combination: SAP’s robust back-office capabilities paired with WooCommerce’s flexible ecommerce frontend. But the integration is not trivial, and I have seen enough of these projects go sideways to be blunt about where the risk actually lives. It is almost never in the WooCommerce half. It is in the mapping, the session handling, and the assumptions you make about the SAP side before you have seen the client’s real data. Here is how I would build it.

Why SAP + WooCommerce?

Companies running SAP B1 that launch or migrate their ecommerce to WooCommerce typically need:

  • Inventory synced in real-time across retail and online channels
  • Orders from WooCommerce automatically created as sales orders in SAP
  • Customer data unified across both systems
  • Product catalog managed in SAP, displayed in WooCommerce
  • Pricing rules (volume discounts, customer-specific) controlled by SAP

Architecture: The Middleware Approach

Never connect WooCommerce directly to SAP’s database. SAP B1 exposes a Service Layer (REST-like API) that’s the proper integration point.

WooCommerce REST API <--> Middleware (Node.js/Python) <--> SAP Service Layer

Message Queue

Error Handling

& Audit Log

The middleware sits between both systems, handling:

  • Data transformation (SAP’s field names to WooCommerce’s schema)
  • Rate limiting and batching
  • Error recovery and retry logic
  • Logging and monitoring

SAP Service Layer Basics

// Authenticate with SAP B1 Service Layer

const login = await fetch('https://sap-server:50000/b1s/v1/Login', {

method: 'POST',

headers: { 'Content-Type': 'application/json' },

body: JSON.stringify({

CompanyDB: 'YOUR_DB',

UserName: 'manager',

Password: 'password'

})

});

// Session cookie for subsequent requests

const sessionId = login.headers.get('set-cookie');

// Fetch items (products)

const items = await fetch('https://sap-server:50000/b1s/v1/Items?$select=ItemCode,ItemName,QuantityOnStock&$filter=SalesItem eq \'Y\'', {

headers: { 'Cookie': sessionId }

});

Data Mapping

This is where most integrations break down. SAP and WooCommerce have fundamentally different data models.

I learned to respect the mapping table the hard way, and not on the web. In the late ’90s I built multi-language CD-ROM projects — the kind where one master source had to feed six languages onto a disc that could not be patched after it shipped. You kept one source of truth and transformed it into every target, and the discipline was absolute: get a field mapping wrong and there was no hotfix, just a coaster with your name on it. SAP field validation has that same unforgiving temperament. It will reject a sales order for a unit-of-measure mismatch you did not know existed, exactly the way a strict character encoding used to blow up a German string on a disc mastered for an English machine. The lesson carried over intact: the mapping table is the project. Everything else is plumbing around it. Build the table first, on paper, against the client’s real records, before you write a line of sync code.

Products

SAP B1 Field WooCommerce Field Notes
ItemCode sku Primary identifier
ItemName name
QuantityOnStock stock_quantity Sum across warehouses
ItemPrices (Price List) regular_price Multiple price lists in SAP
SalesItem (Y/N) status Y = publish, N = draft
Picture images[0].src SAP stores path, needs URL conversion
ItemGroup categories Map SAP groups to WC categories

Orders

WooCommerce Field SAP B1 Object Notes
order.id DocEntry (ref) Store WC order ID in SAP’s remarks
line_items DocumentLines Map by SKU
billing address AddressExtension BillTo address
shipping address AddressExtension ShipTo address
customer email BusinessPartner Match or create BP
payment_method Payment Terms Map WC gateway to SAP terms

Customers

WooCommerce Field SAP B1 Field Notes
email EmailAddress Unique identifier
first_name + last_name CardName Concatenate
billing.company CardName If B2B
billing.address_1 Addresses Address object in SAP
CardCode Auto-generated in SAP

Sync Flows

Product Sync (SAP → WooCommerce)

Frequency: Every 5 minutes or on-change webhook

  • Query SAP for items modified since last sync
  • For each item, check if SKU exists in WooCommerce
  • If exists: update stock, price, and status
  • If new: create product in WooCommerce with full details
  • Log the sync result

Critical consideration: SAP’s price lists support customer-group-specific pricing. Map SAP price lists to WooCommerce’s role-based pricing plugins or custom meta fields.

Order Sync (WooCommerce → SAP)

Trigger: WooCommerce webhook on order.created

  • Receive webhook payload
  • Find or create BusinessPartner in SAP (match by email)
  • Map line items to SAP ItemCodes (by SKU)
  • Create Sales Order in SAP
  • Store SAP DocEntry in WooCommerce order meta
  • Update WooCommerce order note: “Synced to SAP: SO-{DocEntry}”

Inventory Sync (SAP → WooCommerce)

Trigger: SAP UDF or addon fires on stock change, or poll every 60 seconds

  • Get stock levels from SAP (all warehouses or specific ones)
  • Calculate available-to-sell: OnHand - Committed
  • Update WooCommerce via batch endpoint
  • Handle multi-warehouse: sum or pick specific warehouse

Error Handling

SAP integrations are particularly error-prone because:

  • SAP Service Layer sessions expire after 30 minutes of inactivity
  • SAP field validation is strict (wrong UoM, missing required fields = rejection)
  • Network between your middleware and SAP server may be unreliable

Retry strategy:

async function sapRequest(endpoint, options, retries = 3) {

for (let i = 0; i < retries; i++) {

try {

await ensureSession(); // Re-login if session expired

const response = await fetch(${SAP_URL}${endpoint}, options);

if (response.status === 401) {

await login(); // Session expired

continue;

}

return await response.json();

} catch (error) {

if (i === retries - 1) throw error;

await sleep(Math.pow(2, i) * 1000);

}

}

}

Lessons from Production

  • Always use SAP’s Service Layer, never direct DB queries. SAP’s business logic lives in the application layer. Bypassing it will corrupt your data.
  • Handle SAP’s session management carefully. The Service Layer has a concurrent session limit. Pool and reuse sessions.
  • Test with SAP’s production-like data. SAP demo databases have simple structures. Real customer SAP instances have custom fields, user-defined tables, and approval workflows that break naive integrations.
  • Plan for SAP upgrades. SAP B1 updates can change Service Layer behavior. Version-lock your integration and test after each SAP update.
  • Monitor SAP license usage. Each Service Layer session consumes a SAP license. Confirm with the client that their license supports integration sessions.

Build vs. Buy: How I Actually Decide

Clients always ask whether they can skip the middleware and buy an off-the-shelf connector. My answer is a decision, not a survey, and it comes down to three questions.

  • How custom is the SAP instance? If the client runs close to a stock SAP B1 configuration — standard items, one or two price lists, a single warehouse — a packaged connector may genuinely be enough, and I will tell them to buy it. The moment there are user-defined fields, approval workflows, or UDTs feeding business logic, packaged connectors start silently dropping data, and silent data loss between an ERP and a storefront is the worst failure mode there is.
  • Who owns it at 2 a.m.? A connector you buy is a black box when a sync fails during a sale. Middleware you own has logs you can read and a retry queue you can replay. For any store where a stalled order sync means real money, I want the audit log in the diagram above to be mine.
  • Is the price model per-order? Several connectors bill per synced transaction. On a low-margin, high-volume store that math turns ugly fast. Model it against a busy month, not an average one.

My rule of thumb: buy for a near-stock SAP and a modest catalogue; build (or commission) middleware the moment the SAP side carries real customisation. The engineering cost of middleware is a one-time expense. Corrupted business-partner records are a recurring one.

Conclusion

SAP-WooCommerce integration is a middleware problem, not a plugin problem. Off-the-shelf connectors exist but rarely handle the complexity of real SAP implementations with custom fields, multiple price lists, and warehouse configurations. Invest in proper middleware architecture, comprehensive data mapping, and robust error handling. The payoff — automated order flow, real-time inventory, and unified customer data — is worth the engineering investment.

Leave a Reply

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

Close Search Window