Shopify and Dynamics 365 Business Central On-Premise Integration
Learn how to integrate Shopify with Dynamics 365 Business Central On-Premise. A guide to APIs, webhooks, GraphQL, security and enterprise architecture.
· 35 min read

Shopify and Dynamics 365 Business Central On-Premises: the technical guide to an integration that holds up in daily operation
Shopify and Dynamics 365 Business Central are a strong combination for companies that want a fast and flexible e-commerce platform on one side and a robust ERP system on the other.
Shopify is the place where customers meet your products, prices, campaigns and checkout. Business Central is the place where the company keeps track of stock, finance, purchasing, deliveries, customers and day-to-day operations.
When the two systems work together properly, the result is not just fewer manual entries. You get a more coherent business, where order data, stock status, customer information and finance can move between the systems without employees having to copy and paste data all day long.
But there is a difference between an integration that works in a demo and an integration you can rely on during campaigns, seasonal peaks, system updates and a perfectly ordinary Monday morning.
A Shopify Business Central integration must be able to do more than create an order. It has to handle duplicate events, missing item numbers, multiple stock locations, partial deliveries, pricing logic, refunds, timeouts and the many small exceptions that arise in a real e-commerce business.
That applies in particular when Business Central runs On-Premises.
In an On-Premises installation, the ERP system often sits close to the company’s other internal landscape: SQL Server, custom extensions, Active Directory, reporting, local integrations, WMS, file servers and perhaps an older NAV history. That allows a great deal of flexibility, but it also means that the integration architecture has to be well thought through.
This guide goes into depth on how to build the integration correctly. Not as a simple point-to-point connection, but as a controlled, secure and scalable data backbone between Shopify and Business Central.
Integration starts with the business – not with an endpoint
It is tempting to start the integration project with the technical question:
“Can Shopify call Business Central?”
The short answer is yes. Shopify has APIs and webhooks. Business Central can expose REST APIs, OData web services, pages, queries and codeunits. The technology exists.
The right question, however, is:
“How should our order, stock and finance processes work when data moves between Shopify and Business Central?”
That question requires several clarifications.
Who owns product data?
Who decides what the customer is allowed to see and buy?
Which system determines the sellable stock?
When does a Shopify order become a sales order in Business Central?
Should a B2C customer be created as a customer account, or should the order be placed on a miscellaneous customer account?
How are discounts, shipping, gift cards and payment fees handled?
What do you do when an order contains an item that does not yet exist in Business Central?
If the answers are not clear, the rules often end up as hidden logic in code or as manual emergency routines in customer service and finance. That only works until the business grows.
A good integration makes data ownership clear.
Business Central is often the master for item number, cost price, stock, locations, purchasing and the accounting truth.
Shopify is often the master for product texts, images, collections, campaigns, SEO data and the checkout experience.
A PIM system can be the master for customer-facing product data if you need to work systematically with product information across channels. That is particularly relevant in system landscapes with many products, markets or sales channels. You can read more about that kind of unified landscape in Connectify’s guide to system architecture across e-commerce, PIM, DAM and 3PL.
That does not mean data may only exist in one place. It means there has to be one authoritative source for each area.
If both Shopify and Business Central are free to change product name, price or stock without a rule for priority, you will sooner or later get conflicts. Not because the systems are bad, but because they work from different purposes.
Shopify and Business Central must each have their own responsibility
Shopify is built to sell.
The platform handles product display, customer journeys, discounts, checkout, online payments, customer accounts, marketing integrations and the digital experience. A lot of changes can happen within a few minutes. A campaign goes live. A customer completes checkout. An order is updated. A product is put on sale. A return is created.
Business Central is built to run and record the business.
Here the focus is on correct inventory management, customer accounts, VAT, dimensions, purchasing, credit, deliveries, invoicing and financial reconciliation. An order is not just a list of items. It can be linked to locations, payment terms, customer posting groups, VAT setup, delivery rules and company-specific processes.
That gives a natural division of labour:
- Shopify typically owns the customer’s checkout and the first order confirmation.
- Business Central typically owns stock movements, financial order processing and posting.
- An integration layer owns mapping, traceability, error handling and the transport between the systems.
That is precisely why a Dynamics 365 Business Central integration should not be treated as an ordinary export and import of CSV files. It has to be a process that respects both e-commerce and ERP logic.
Why Business Central On-Premises requires more consideration
Business Central Online is built for cloud operation. Business Central On-Premises is built so that the company itself has greater control over operations, network, servers and customisations.
That can be an advantage. Many companies have strong and valuable processes built into their On-Premises solution. They may have particular codeunits, integration tables, reports, industry-specific extensions or dependencies on local systems.
But it also means that you should not simply open Business Central Server directly to the internet and let Shopify events call into the ERP.
Business Central, SQL Server and web services are often central parts of internal operations. They need to be protected against unnecessarily many calls, poorly validated traffic and public exposure.
The best practice is therefore normally to introduce an integration layer between Shopify and Business Central.
That integration layer can be a purpose-built service, an Azure-based solution or a unified integration platform. What matters is not the product name. What matters is that the integration gets a place where events can be received, validated, run asynchronously, monitored and re-run.
Shopify has to be able to be fast.
Business Central has to be able to be correct.
The integration layer has to ensure that the two qualities can work together.
The robust integration architecture
A stable solution normally consists of five logical parts.
First you have Shopify. That is the source of order events, customer data, product changes, refunds and a range of customer-facing actions. Shopify is also the target for stock updates, product data, fulfilment status and possibly B2B information.
Next you have a secure entry point to the integration. That is typically an HTTPS endpoint that receives webhooks from Shopify. That endpoint has to be fast. It has to verify that the event actually comes from Shopify, register it and immediately hand it over for further processing.
The third part is a queue. This is where events sit until they are processed. The queue means that a webshop order does not disappear if Business Central is under maintenance, a service restarts, or the ERP system is busy.
The fourth part is the integration engine. This is where Shopify data is mapped to the company’s internal model. This is where the order is validated, the customer is matched, item lines are translated, prices are checked, duplicates are avoided and errors are categorised.
The fifth part is Business Central. Here the integration has to use a deliberate integration surface – not write directly into SQL tables or bypass the business logic that keeps the ERP system consistent.
When the architecture is split up in this way, you get several benefits:
- Shopify webhooks can be acknowledged quickly.
- Business Central is protected against traffic peaks.
- Orders can be processed in a controlled way and re-run.
- Errors can be seen and handled instead of disappearing.
- New integrations can be added without rebuilding the whole solution.
- You can scale order processing without scaling everything else at the same time.
That is often the most significant difference between a solution that works in the beginning and a solution that continues to work when the company gets more stores, markets, items and orders.
API Pages: build an integration contract, not a shortcut
Business Central has several ways of exposing data. You can use standard APIs, published OData pages, API queries and codeunits. Each type has its place.
Microsoft recommends the REST API stack as the preferred integration route, and Business Central can use both built-in APIs and its own custom APIs. Microsoft’s overview of Business Central web services describes the difference between REST APIs, OData and SOAP as well as which object types are suited to each purpose.
When you are building a stable and long-term integration, API pages are often a strong starting point.
An API page is an AL page with PageType = API. It is built for integration use and not for ordinary display in the Business Central user interface. It can be version-controlled and exposed as an OData v4-enabled REST web service. Microsoft’s documentation on API pages describes API pages precisely as versioned integration endpoints.
What matters is not simply exposing a table.
What matters is defining a contract.
If Shopify is to fetch sellable products, you do not need to expose all the fields from the item table. You should expose the fields the integration actually needs:
- A stable external ID.
- Item number.
- Variant code.
- SKU and EAN.
- Status for online sales.
- Sellable stock.
- Price and currency, if the ERP owns the pricing logic.
- Last modified timestamp.
- Relevant product attributes.
An API contract should be well-defined, stable and understandable. It is perfectly fine for it to be smaller than the underlying table.
A simplified example might look like this:
page 50120 "Shopify Item API"
{
PageType = API;
APIPublisher = 'connectify';
APIGroup = 'shopify';
APIVersion = 'v1.0';
EntityName = 'shopifyItem';
EntitySetName = 'shopifyItems';
SourceTable = Item;
In a real solution you will typically use a separate integration table or supplementary logic if data such as sellable stock or online status does not exist directly on the item card.
The decisive point is that you do not turn an internal table structure into your public contract by accident.
APIs should be treated as products. They should be documented, versioned, tested and changed with care.
If you later need to change the field structure or business rules, it is far better to introduce version v2.0 than to change an endpoint that an operations-critical integration already depends on.
If you want a more basic introduction to Business Central’s API landscape, the Business Central API V2 guide is a natural place to start.
OData: effective for data extraction, but not the answer to everything
OData is an HTTP-based standard that Business Central can use to expose data as JSON. It is particularly useful when the integration needs to read well-defined data sets, filter on changes or look up particular records.
OData is good for things like:
- Item extracts.
- Stock extracts.
- Customer searches.
- Fetching changes since the last synchronisation.
- Status lookups.
- Reconciling data between systems.
Microsoft’s OData overview for Business Central is worth knowing, because Business Central’s implementation does not necessarily support all parts of the OData standard.
A targeted OData call can, for example, fetch only the fields and items that have actually changed:
GET /BC230/ODataV4/Company(Id=...)/ShopifyItems?
$select=No,Description,GTIN,Last_Modified_Date_Time
&$filter=Last_Modified_Date_Time gt 2026-08-01T00:00:00Z
&$orderby=Last_Modified_Date_Time asc
That is a far healthier strategy than fetching the whole item table every five minutes to discover a few changes.
With On-Premises you can control the size of OData pages and use Prefer: odata.maxpagesize to keep large data sets in controlled chunks. Microsoft describes how paging limits the risk of timeouts and high memory consumption in the guidance on server-driven OData paging.
Paging should be seen as part of the integration design.
Each page has to be able to be processed independently.
The integration should save its checkpoint.
An interrupted job has to be able to continue without starting over or creating duplicates.
OData is not always the best way to carry out a complex business action, however. It is rarely enough to POST an order directly to a generic sales order page. An order can require customer lookup, validation, VAT logic, discount allocation, credit control, dimension handling and special rules.
For that you often need a codeunit.
Codeunits: when the integration has to carry out a business process
A codeunit is the right tool when an integration has to carry out a process rather than simply create or read a data object.
That could, for example, be the “process Shopify order” process.
It might consist of:
- Check whether the order has already been processed.
- Find or create the customer.
- Find items and variants.
- Create the sales header.
- Create lines with Business Central’s normal validation.
- Allocate discounts and shipping.
- Set payment, delivery and dimension information.
- Save Shopify references.
- Return an unambiguous status.
A simplified example might look like this:
codeunit 50121 "Shopify Order Processor"
{
procedure Process(IntegrationOrder: Record "Shopify Integration Order")
var
SalesHeader: Record "Sales Header";
ShopifyOrderMgt: Codeunit "Shopify Order Management";
begin
if IntegrationOrder."Processing Status" =
IntegrationOrder."Processing Status"::Completed then
exit;
IntegrationOrder.TestField("Shopify Order Id");
ShopifyOrderMgt.EnsureNotProcessed(IntegrationOrder."Shopify Order Id");
ShopifyOrderMgt.ValidatePayload(IntegrationOrder);
ShopifyOrderMgt.CreateSalesOrder(IntegrationOrder, SalesHeader);
You do not necessarily have to expose the codeunit itself to Shopify. Often it is better for the integration layer to create an integration record via an endpoint, after which Business Central processes it in a controlled way in a job queue.
That gives better traceability, better error handling and less risk that an external call tries to complete a heavy ERP process synchronously.
If you work with custom APIs, Microsoft’s API developer overview is useful. Among other things, it distinguishes between API pages for read and write operations and API queries for read-only scenarios across several tables.
At Connectify there is also a more practical introduction to Business Central API endpoints, if you need to understand which endpoints suit which data flows.
Shopify GraphQL Admin API: the modern integration surface
On the Shopify side, new integrations should take the GraphQL Admin API as their starting point.
GraphQL makes it possible to fetch exactly the fields and relations the integration needs. That means fewer unnecessary calls and a more controlled volume of data.
Instead of fetching an order, then the customer, then the lines, then the discounts and then the delivery data in separate queries, you can often gather the necessary data in a single GraphQL query.
An example of an order extract might look like this:
query OrderForErp($id: ID!) {
order(id: $id) {
id
name
createdAt
updatedAt
displayFinancialStatus
displayFulfillmentStatus
currencyCode
email
customer {
id
email
firstName
lastName
}
lineItems(first: 250) {
nodes {
id
sku
title
quantity
discountedUnitPriceSet {
shopMoney {
amount
currencyCode
}
}
variant {
id
sku
barcode
}
}
}
}
}
Shopify GraphQL uses global IDs, often in the format gid://shopify/Order/.... They should be stored as technical references in the integration layer and, where it makes sense, in Business Central.
Shopify has detailed documentation for the GraphQL Admin API, but the most important architectural principle is simple: fetch only what you need.
An integration that fetches all products, all variants, all metafields and the entire customer history every time becomes slow and unnecessarily expensive in API consumption.
It is also important to understand Shopify’s rate limits. The GraphQL Admin API works with cost-based throttling. That means the load of a query depends on its complexity, not only on the number of calls. Shopify itself recommends caching, responsible retries and queue-based processing when throttling occurs. See the current documentation on Shopify API limits.
The integration engine should therefore:
- Monitor GraphQL cost.
- Limit parallel calls.
- Fetch few and relevant fields.
- Use cursor-based pagination.
- Wait when Shopify signals throttling.
- Use bulk extracts for large initial data sets.
For large product, customer or order extracts, Shopify’s asynchronous Bulk Operations are often a better choice than many small paginated calls. Shopify delivers results as JSONL once the operation has completed. Shopify’s documentation on Bulk Operations explains the asynchronous pattern and the subsequent handling of results.
Bulk Operations are good for the initial load.
Webhooks and targeted API calls are better for ongoing operation.
The two mechanisms should not compete. They should work together.
Webhooks: use them as a signal, not as the whole integration process
Webhooks are the foundation of a modern Shopify integration.
Instead of asking Shopify every minute whether something has happened, Shopify can send an event when a relevant change occurs. That could be a created order, a changed product, a stock-related event, a refund or a fulfilment.
Shopify’s current webhook documentation shows the available topics and the options for creating subscriptions through app configuration or the GraphQL Admin API.
But a webhook must not be understood as a guarantee that the work has been completed.
A webhook is a message that something has happened.
It is not necessarily the only message you will get about the same object.
An order can be created, paid, edited, cancelled, fulfilled and refunded. A product variant can be updated several times within a short period. A webhook can be delivered again if your endpoint does not acknowledge correctly, or if delivery has to be retried.
The webhook endpoint should therefore do as little as possible:
- Receive the event.
- Verify the sender.
- Store the event and metadata.
- Deduplicate.
- Put the event in a queue.
- Acknowledge quickly.
That endpoint should not create a sales order directly in Business Central. If the ERP system is slow or briefly unavailable, the received order must not be lost or make Shopify wait.
Webhook security is crucial. Shopify sends HMAC signatures in the headers, and the integration has to verify them against the raw request body before the payload is changed or processed. Shopify documents the HMAC header, event ID and webhook ID in its guidance on events and delivery.
As a minimum, store the following data on receipt:
- Shopify shop domain.
- Topic.
- Webhook ID.
- Event ID.
- Timestamp.
- API version.
- Raw payload or a secure reference to the payload.
- HMAC validation result.
- Processing status.
- Correlation ID.
When a customer or an employee asks why a particular order has not landed in the ERP, you have to be able to follow it from event to queue, on to Business Central and possibly back to Shopify.
That is not a luxury. It is basic operational discipline.
Queues: what makes the integration robust
A queue creates distance between Shopify and Business Central.
That sounds technical, but the value is very close to the business.
Shopify can receive many orders within a few minutes. Business Central may be in the middle of month-end closing, backup, reporting or normal user traffic. If Shopify is forced to wait for Business Central, the integration becomes fragile.
When the webhook puts the work in a queue, Business Central can process jobs at the pace the ERP environment can handle.
You can, for example, have separate job types for:
- Order import.
- Customer creation.
- Product changes.
- Stock updates.
- Fulfilment status.
- Refunds.
- Reconciliations.
That makes a big difference. A comprehensive product import must not block new orders. An error in a refund must not hold back stock updates.
For order data you should also think about sequencing.
If an order is created, then cancelled and later refunded, the processes must not be handled in arbitrary order. A practical approach is to let events for the same Shopify order ID be processed sequentially, while orders with different IDs can be processed in parallel.
That way you get both consistency and capacity.
A queue should have clear states:
- Received.
- Queued.
- Processing.
- Completed.
- Retry scheduled.
- Needs attention.
- Dead letter.
Dead letter means that a job should no longer be retried automatically. That could, for example, be because the SKU does not exist in Business Central, or because a setting is missing. That kind of error requires a person – not ten extra technical attempts.
Idempotency: the most important protection against duplicates
Idempotency means that the same operation can be carried out several times without creating several results.
That is crucial in integrations.
Imagine that the integration engine creates a sales order in Business Central. The order is created, but the network connection drops before the integration engine receives the response. It now does not know whether the order exists or not.
If it simply tries again, you risk a duplicate order.
The same can happen with a timeout, a worker crash, a service restart, redelivered webhooks or manual re-runs.
An order integration therefore has to have at least two layers of idempotency.
First, technical deduplication. It uses the webhook ID or the event ID to ensure that the same delivery is not processed several times.
Second, business deduplication. It uses the Shopify order ID as a stable key and ensures that the same order is never created as several Business Central documents.
A good Business Central integration stores the Shopify order ID in a dedicated integration table or on the sales order itself. Before a new order is created, the process checks whether it has already been processed.
The check has to be atomic. Two concurrent workers must not both conclude that the order is missing and then both create it.
A similar principle applies to stock.
Instead of sending “subtract one unit”, the integration layer should normally update an absolute value:
“Sellable stock for this variant and location is now 42.”
That is more robust, because events can arrive twice or in the wrong order. An absolute state can be replaced. A delta can accumulate incorrectly.
Retry strategy: retry with care
Errors will occur. That is not a sign of a bad integration. It is a fact of life when several systems, networks and dependencies work together.
What matters is how the integration reacts.
Temporary errors should typically be retried. That could be:
- Shopify throttling.
- Timeout.
- A brief network outage.
- A temporary error in Business Central Server.
- A planned restart.
- HTTP 502, 503 or similar technical responses.
Permanent errors, on the other hand, normally require clarification. That could be:
- An unknown SKU.
- Missing VAT posting setup.
- A closed accounting period.
- An invalid country code.
- A missing customer match.
- Insufficient access rights.
- An invalid payment or delivery setup.
A good retry strategy uses exponential backoff. That means the integration waits longer between each attempt. For example after 30 seconds, then two minutes, ten minutes and an hour.
Do add some variation to the waiting time, so that many jobs do not retry at the same moment and create a new load peak.
With Shopify throttling, the integration has to follow the API budget Shopify reports. A throttle response is not an invitation to send more calls. It is a signal to wait.
With business errors, the job should go to a clear clarification queue. The error has to be understandable to the person who has to resolve it:
“Order #10432 could not be created because Shopify SKU
ABC-RED-XLdoes not exist as an item or variant in Business Central.”
That is far more usable than:
“HTTP 400 – validation error.”
Master data: the products and customers determine whether the order flow succeeds
Many integration projects start with orders. That makes good sense, because the order is visible and directly linked to revenue.
But master data is often the real key to stable operation.
If the item cannot be matched, the order cannot be processed correctly.
If the customer cannot be identified, the order cannot be placed correctly.
If country codes, VAT rules or delivery methods are not consistent, errors arise later in the process.
Product identity therefore has to be unambiguous.
Shopify works with products and variants. Business Central can work with item number, variant code, units, bills of materials and different item structures.
A typical model might be:
- Shopify Product: the customer-facing product.
- Shopify Variant: the concrete purchasable and stocked variant.
- Business Central Item: item or product family.
- Business Central Item Variant: for example colour or size.
But the model depends on your business. Some companies use one item number per physical variant. Others use item number plus variant code.
What matters is that the Shopify SKU can be mapped unambiguously to the sellable unit in Business Central.
Avoid using product names as a key. Names change.
Also avoid assuming that a Shopify product ID is automatically the right business key in the ERP. Shopify IDs are good technical references, but employees, purchasing and the warehouse often work with item number, EAN and variant.
For customers you need to define a deliberate model.
In B2C, a miscellaneous customer account can be a simple and correct solution if customer data is primarily to stay in Shopify, and Business Central only needs the financial order.
In B2B you will often need an actual customer account relationship in Business Central. Here email can be a useful indicator, but rarely enough as the only key. The company registration number, the Shopify Company ID, the customer account’s external reference and approved relationship tables can be more robust.
If you have customer-specific prices, credit control, payment terms or several delivery addresses, you should treat B2B as a separate integration area. Connectify’s guide to Shopify B2B and Shopify Plus is a relevant next step if your webshop has to reflect Business Central customer data and pricing logic.
Product synchronisation: do not mirror everything
Shopify and Business Central use product data for different things.
Shopify has to present and sell the product. That is why the platform works with images, collections, tags, descriptions, metafields, SEO and merchandising.
Business Central has to buy, store and post the item. That is why the ERP system works with cost prices, inventory posting groups, vendor relations, reordering, locations and item ledger entries.
You should not try to mirror all fields between the systems.
You should define who owns which fields.
Business Central can, for example, own:
- SKU and item number.
- Variant structure.
- EAN.
- Weight and dimensions, if they are used in logistics.
- Sales unit.
- Sellable status.
- Stock status.
- Standard price, if prices are managed in the ERP.
Shopify can, for example, own:
- Product descriptions.
- Images.
- Collections.
- Tags.
- SEO title and meta description.
- Campaign texts.
- Customer-facing metafields.
If you work with PIM, the PIM system can become the master for product content, while Business Central continues to own the logistical and financial item data.
It is also important to distinguish between:
- The item exists in Business Central.
- The item is active in Business Central.
- The item may be sold in Shopify.
- The item may be sold on this specific Shopify channel or in this market.
An active ERP item is not always ready for the webshop. It may be an internal spare part, an item that is being created, a discontinued article, a B2B-only item or a product without approved content.
“Can be sold online” should therefore be an explicit business rule.
Stock synchronisation: synchronise sellable stock
Stock is one of the most critical flows in the entire integration.
If the stock level is too high in Shopify, you can oversell.
If the stock level is too low, you lose sales.
If the stock level is incomprehensible, employees lose trust in both the webshop and the ERP.
That is why you should not simply send physical stock from Business Central to Shopify. You have to calculate a sellable stock figure.
A simplified formula might be:
Sellable stock =
physical stock
- reserved stock
- safety stock
- stock at non-sellable locations
But the specific rule depends on your operation.
Do you have several warehouses?
Do you have physical stores?
Do you sell from a 3PL?
Do you have goods on their way in?
Do you accept back orders?
Do you reserve items in Business Central at order import?
Do you sell the same items on Shopify, a B2B portal, marketplaces and a physical POS?
All of those questions affect what Shopify should show as purchasable stock.
Sellable stock should normally be updated as an absolute value. If Business Central calculates that 17 units may be sold, Shopify should receive the value 17. That is more robust than sending small plus and minus changes.
A modern solution typically uses two mechanisms at the same time:
- Event-driven synchronisation when stock changes.
- Periodic reconciliation that finds and corrects discrepancies.
Event-driven stock gives speed.
Reconciliation gives trust.
A nightly or hourly reconciliation can fetch the calculated stock from Business Central, compare it with Shopify and only update the items where there is a genuine discrepancy.
It is also a good way to detect errors that are not caused directly by the integration, for example manual stock adjustments or unexpected changes in a third-party system.
Connectify’s Shopify integration page already describes stock reconciliation across the ERP and Shopify as a central flow. The deep stock logic should, however, always reflect your specific locations, reservations and customer promises.
Order import: from Shopify checkout to a correct ERP process
An order in Shopify is not automatically the same as a sales order in Business Central.
Some companies want to create a sales order that is later picked, delivered and invoiced in the ERP.
Others want to create an invoice or a more simplified document process.
Some use a miscellaneous customer account for B2C.
Others create all customers as separate customer accounts.
Some post at fulfilment.
Others post after payment capture or in a separate reconciliation process.
There is no single correct model. But the model has to be deliberate.
A robust order process typically does the following:
- Receives the Shopify event.
- Checks idempotency.
- Fetches the necessary, up-to-date order data via GraphQL.
- Finds the correct Business Central company.
- Matches or creates the customer.
- Matches items and variants.
- Creates the sales document through BC validation.
- Handles discount, shipping, VAT and payment.
- Saves the Shopify order ID and relevant transaction references.
- Logs the result and makes the status traceable.
Price and discount have to be designed particularly carefully.
Shopify can have discount codes, automatic discounts, line discounts, order-level discounts, gift cards and rounding. Business Central can have its own pricing and discount logic.
You have to decide whether Business Central should recalculate the price, or whether the commercial result of the Shopify order is decisive.
For many B2C businesses it is crucial that the ERP reflects the amount the customer has actually paid. In B2B it can be more important that Business Central’s contract prices are decisive.
It is rarely wise to let that decision arise by chance in the mapping code.
Shipping has to be handled as a clear line or a clear business rule. The same applies to gift cards, payment fees and discounts. The better you can explain every amount in Business Central, the easier financial reconciliation becomes.
If payment data has to be matched and settled automatically, a separate payment integration can be relevant. Connectify’s Billwerk integration shows, for example, how Shopify payments and Business Central can be linked in a process with automatic settlement.
Fulfilment, cancellations and refunds are part of the order
An integration does not end when the order has been created.
If Business Central or a WMS system controls picking and shipping, the fulfilment status normally has to be sent back to Shopify. The customer has to be able to see whether the order has been processed, shipped or partially delivered.
That requires a clear decision about where the fulfilment truth sits.
If a 3PL system physically packs and ships the order, the 3PL can be the primary source of tracking number and delivery time. Business Central and Shopify then receive the same operational information through the integration layer.
Partial deliveries require extra consideration. An order with five lines can be delivered in two rounds. The integration has to be able to keep track of the specific line item IDs and quantities, not only the whole order.
Cancellations also need a process.
If the customer cancels in Shopify before the warehouse has processed the order, the corresponding BC order may have to be cancelled or stopped.
If the item has already been picked, there may be an internal process.
If the item has been delivered, it is often no longer a cancellation, but a return and a credit note.
Refunds have to be traceable back to the original order and the specific order lines. Store the Shopify refund ID, amount, VAT, item lines and any return reasons, if they are relevant to your process.
Security: protect data and protect the ERP environment
A Shopify-Business Central integration often handles personal data, order information, API tokens and access to a business-critical ERP system.
Security therefore has to be part of the architecture from the start.
Business Central On-Premises should not be broadly exposed to the internet if it can be avoided. Instead, use a controlled connection route between the integration layer and the company’s network.
That can be a VPN, a reverse proxy with strict access control, private network connections or a local connector that itself establishes an outgoing connection.
Use HTTPS all the way.
Do not store API keys and secrets in source code, spreadsheets or unencrypted configuration files. Shopify access tokens, webhook secrets, Business Central credentials and certificates should be handled in a secrets management system with clear access rights and the option of rotation.
Apply the least possible privileges.
The Shopify app should only have the scopes it needs.
The Business Central integration user should only be able to carry out the operations the integration needs.
An integration user with full administrator rights can be quick to set up during development, but it is a poor operating model.
For On-Premises you also need to remember that APIs and web services have to be enabled on the server. If API, OData or SOAP services are switched off, endpoints can return errors such as HTTP 405. Microsoft describes this in its documentation on enabling Business Central APIs in On-Premises environments.
Security is also about data retention.
Only store personal data when there is a legitimate operational need.
Define how long raw webhook payloads are retained.
Limit access to error views and logs.
Make sure you can handle deletion and data requests in the systems where you store information.
Monitoring: you have to be able to see what the integration is doing
An integration without monitoring is a black box.
When everything works, nobody thinks about it.
When something fails, it suddenly becomes the centre of attention for customer service, the warehouse, finance and the e-commerce team.
That is why the solution has to have logs, metrics and traceability.
Logs tell you what happened.
Metrics tell you how the solution is doing.
Traceability connects them.
Every order flow should have a correlation ID, so that you can follow the process from Shopify event to integration job, Business Central document and any fulfilment update.
Relevant metrics can be:
- The number of webhooks received.
- The number of orders fully processed.
- Average processing time.
- The number of retries.
- Jobs in the dead-letter queue.
- Shopify API cost.
- Shopify throttle events.
- Business Central response time.
- The number of stock discrepancies.
- Orders waiting for manual clarification.
Alerts have to be meaningful.
There is not much value in getting a message about every single retry. There is value in getting an alert if order import has been stopped for 15 minutes, if the dead-letter queue is growing, or if stock reconciliation finds significant discrepancies.
Business Central API calls should also be measured. Microsoft has concrete recommendations for targeted data extraction, paging and efficient client behaviour in its guidance on API and OData performance.
An operations view should be usable by more than developers. An ERP consultant or an e-commerce manager should be able to see:
- Whether the integration is running.
- Which orders have been completed.
- Which errors require action.
- Why a specific job failed.
- Whether stock is reconciled.
- Which Business Central order corresponds to a Shopify order.
That makes the company less dependent on individuals and far faster at reacting to discrepancies.
Performance: go easy on Business Central and respect Shopify
Performance is not only about achieving a low response time figure.
It is about using the systems sensibly.
Business Central On-Premises is often shared between integrations, users, reports, background jobs and other systems. A poor integration query can therefore affect more than just the webshop.
On the Business Central side you should:
- Filter data as close to the source as possible.
- Fetch few fields.
- Use paging.
- Save checkpoints.
- Limit parallel write operations.
- Avoid very long transactions.
- Use API queries for read-only extracts where that fits.
- Measure response times and errors for each endpoint.
On the Shopify side you should:
- Fetch precisely the fields that are used.
- Keep GraphQL queries small and targeted.
- Respect the cost budget.
- Use webhooks rather than aggressive polling.
- Use Bulk Operations for historical and large extracts.
- Cache data when the freshness requirement allows it.
The initial load and ongoing synchronisation should be two different processes.
The initial load is about fetching a large base data set – for example all products, variants or historical orders. It is a planned batch process.
Ongoing synchronisation is about changes since last time. It is webhook- and delta-driven.
If you use the same method for both, the solution often ends up either slow in everyday use or fragile with large volumes of data.
Test the real world – not just the test order
A single test order with one item and a Danish address proves almost nothing.
A production-ready integration has to be tested with the situations that actually arise:
- Multiple order lines.
- Variant items.
- Discount codes.
- Automatic discounts.
- Shipping lines.
- Gift cards.
- Partial deliveries.
- Full and partial refunds.
- An unknown SKU.
- An out-of-stock item.
- Existing and new customers.
- A B2B customer with a price group.
- Several stock locations.
- A duplicate webhook.
- Events in the wrong order.
- A timeout after creation.
- A temporary breakdown in Business Central.
- Shopify throttling.
- A manual re-run of a failed job.
The best test is often to create errors deliberately in a controlled test environment.
Stop access to Business Central for a short while.
See whether the event stays in the queue.
See whether the process is re-run.
See whether the result is still only one sales order.
How you should implement the solution
A strong project can certainly be carried out in phases.
The first phase is scoping. Here you describe data ownership, processes, exceptions, system boundaries and success criteria. The warehouse, finance, e-commerce, customer service and the ERP side all have to be represented.
The second phase is the basic architecture. Here you settle API contracts, network access, security, queues, logging, data identities and error handling.
The third phase is master data. Products, variants, customer matching, locations and stock rules have to be in place before the order business becomes complex.
The fourth phase is order import. Start with the most common order type. Build idempotency, retry and error visibility in from the beginning.
The fifth phase is the order lifecycle: fulfilment, tracking, cancellation, return and refund.
The sixth phase is operational maturity: reconciliation, dashboards, alerts, support responsibility and ongoing optimisation.
A good runbook is part of the delivery. It has to describe what the company does when:
- An item is missing in Business Central.
- An order cannot be matched to a customer.
- Stock levels differ.
- The Shopify token has been revoked.
- Business Central does not respond.
- A job is sitting in dead letter.
- A customer asks about an order that cannot yet be seen in the ERP.
That is how you turn the integration into an operational solution rather than a development project.
Ready to get Shopify and Business Central under control?
A stable Shopify and Business Central integration is not only about moving data. It is about getting order flow, stock, finance and customer data to work together in real everyday operation.
That requires your integration to fit your systems, your workflows and the way you want to grow.
At Connectify we help companies create stable data flows between Shopify, Dynamics 365 Business Central and the rest of the system landscape – without you having to spend your time on manual corrections, stock discrepancies and unclear error messages.
See how other companies use Connectify, or get in touch with us if you want to clarify how your Shopify and Business Central setup can fit together better.