Shopify og Dynamics 365 Business Central On-Premises: den tekniske guide til en integration, der holder i drift
Shopify og Dynamics 365 Business Central er en stærk kombination for virksomheder, der vil have en hurtig og fleksibel e-commerce-platform på den ene side og et robust ERP-system på den anden.
Shopify er stedet, hvor kunder møder jeres produkter, priser, kampagner og checkout. Business Central er stedet, hvor virksomheden holder styr på lager, økonomi, indkøb, leverancer, kunder og den daglige drift.
Når de to systemer arbejder rigtigt sammen, bliver resultatet ikke bare færre manuelle indtastninger. I får en mere sammenhængende forretning, hvor ordredata, lagerstatus, kundeoplysninger og økonomi kan bevæge sig mellem systemerne uden, at medarbejdere skal kopiere og indsætte data dagen lang.
Men der er forskel på en integration, der virker til en demo, og en integration, I kan stole på under kampagner, sæsonspidser, systemopdateringer og helt almindelig mandag morgen.
En Shopify Business Central-integration skal ikke kun kunne oprette en ordre. Den skal kunne håndtere dobbelte events, manglende varenummer, flere lagerlokationer, delvise leveringer, prislogik, refunderinger, tidsudfald og de mange små undtagelser, som opstår i en rigtig e-commerce-forretning.
Det gælder særligt, når Business Central kører On-Premises.
I en On-Premises-installation ligger ERP-systemet ofte tæt på virksomhedens øvrige interne landskab: SQL Server, tilpassede extensions, Active Directory, rapportering, lokale integrationer, WMS, filservere og måske en ældre NAV-historik. Det giver mulighed for stor fleksibilitet, men det betyder også, at integrationsarkitekturen skal være gennemtænkt.
Denne guide går i dybden med, hvordan I bygger integrationen rigtigt. Ikke som en simpel punkt-til-punkt-forbindelse, men som en kontrolleret, sikker og skalerbar datarygrad mellem Shopify og Business Central.
Integration starter med forretningen – ikke med et endpoint
Det er fristende at starte integrationsprojektet med det tekniske spørgsmål:
“Kan Shopify kalde Business Central?”
Det korte svar er ja. Shopify har API’er og webhooks. Business Central kan eksponere REST API’er, OData-webservices, pages, queries og Codeunits. Teknologien findes.
Det rigtige spørgsmål er dog:
“Hvordan skal vores ordre-, lager- og økonomiproces fungere, når data bevæger sig mellem Shopify og Business Central?”
Det spørgsmål kræver flere afklaringer.
Hvem ejer produktdata?
Hvem bestemmer, hvad kunden må se og købe?
Hvilket system bestemmer det salgsklare lager?
Hvornår bliver en Shopify-ordre til en salgsordre i Business Central?
Skal en B2C-kunde oprettes som debitor, eller skal ordren placeres på en diverse debitor?
Hvordan behandles rabat, fragt, gavekort og betalingsgebyrer?
Hvad gør I, når en ordre indeholder en vare, der endnu ikke findes i Business Central?
Hvis svarene ikke er klare, ender reglerne ofte som skjult logik i kode eller som manuelle nødrutiner hos kundeservice og økonomi. Det virker kun, indtil forretningen vokser.
En god integration gør dataansvar tydeligt.
Business Central er ofte master for varenummer, kostpris, lager, lokationer, indkøb og den bogføringsmæssige sandhed.
Shopify er ofte master for produkttekster, billeder, collections, kampagner, SEO-data og checkoutoplevelsen.
Et PIM-system kan være master for kundevendte produktdata, hvis I har behov for at arbejde systematisk med produktinformation på tværs af kanaler. Det er særligt relevant i systemlandskaber med mange produkter, markeder eller salgskanaler. I kan læse mere om den type samlede landskab i Connectifys guide til systemarkitektur på tværs af e-commerce, PIM, DAM og 3PL.
Det betyder ikke, at data kun må ligge ét sted. Det betyder, at der skal være én autoritativ kilde for hvert område.
Hvis både Shopify og Business Central frit kan ændre produktnavn, pris eller lager uden en regel for prioritet, får I før eller siden konflikter. Ikke fordi systemerne er dårlige, men fordi de arbejder ud fra forskellige formål.
Shopify og Business Central skal have hver deres ansvar
Shopify er skabt til at sælge.
Platformen håndterer produktvisning, kunderejser, rabatter, checkout, onlinebetalinger, kundekonti, marketingintegrationer og den digitale oplevelse. Der kan ske mange ændringer på få minutter. En kampagne går live. En kunde gennemfører checkout. En ordre opdateres. Et produkt bliver sat på tilbud. En retur oprettes.
Business Central er skabt til at drive og bogføre forretningen.
Her er fokus på korrekt lagerstyring, debitorer, moms, dimensioner, indkøb, kredit, leverancer, fakturering og finansiel afstemning. En ordre er ikke bare en liste over varer. Den kan være knyttet til lokationer, betalingsbetingelser, kundebogføringsgrupper, momsopsætning, leveringsregler og virksomhedsspecifikke processer.
Det giver en naturlig arbejdsdeling:
- Shopify ejer typisk kundens checkout og den første ordrebekræftelse.
- Business Central ejer typisk lagerbevægelser, økonomisk ordrebehandling og bogføring.
- Et integrationslag ejer mapping, sporbarhed, fejlhåndtering og transporten mellem systemerne.
Det er netop derfor, en Dynamics 365 Business Central-integration ikke bør behandles som en almindelig eksport og import af CSV-filer. Den skal være en proces, der respekterer både e-commerce- og ERP-logik.
Hvorfor Business Central On-Premises kræver mere omtanke
Business Central Online er bygget til cloud-drift. Business Central On-Premises er bygget til, at virksomheden selv har større kontrol over drift, netværk, servere og tilpasninger.
Det kan være en fordel. Mange virksomheder har stærke og værdifulde processer bygget ind i deres On-Premises-løsning. De kan have særlige Codeunits, integrationstabeller, rapporter, branchespecifikke extensions eller afhængigheder til lokale systemer.
Men det betyder også, at man ikke bare bør åbne Business Central Server direkte mod internettet og lade Shopify-events kalde ind i ERP.
Business Central, SQL Server og webservices er ofte centrale dele af den interne drift. De skal beskyttes mod unødigt mange kald, dårligt valideret trafik og offentlig eksponering.
Den bedste praksis er derfor normalt at indføre et integrationslag mellem Shopify og Business Central.
Det integrationslag kan være en specialbygget service, en Azure-baseret løsning eller en samlet integrationsplatform. Det vigtige er ikke produktnavnet. Det vigtige er, at integrationen får et sted, hvor hændelser kan modtages, valideres, køres asynkront, overvåges og genkøres.
Shopify skal kunne være hurtigt.
Business Central skal kunne være korrekt.
Integrationslaget skal sikre, at de to kvaliteter kan fungere sammen.
Den robuste integrationsarkitektur
En stabil løsning består normalt af fem logiske dele.
Først har I Shopify. Det er kilden til ordre-events, kundedata, produktændringer, refunderinger og en række kundevendte handlinger. Shopify er også målet for lageropdateringer, produktdata, fulfillment-status og eventuelt B2B-information.
Dernæst har I en sikker indgang til integrationen. Det er typisk et HTTPS-endpoint, som modtager webhooks fra Shopify. Det endpoint skal være hurtigt. Det skal verificere, at eventet faktisk kommer fra Shopify, registrere det og straks aflevere det til videre behandling.
Tredje del er en kø. Her ligger hændelser, indtil de behandles. Køen betyder, at en webshopordre ikke forsvinder, hvis Business Central er under vedligeholdelse, en service genstarter, eller ERP-systemet er travlt.
Fjerde del er integrationsmotoren. Det er her, Shopify-data mappes til virksomhedens interne model. Det er her, ordren valideres, kunden matches, varelinjer oversættes, priser kontrolleres, dubletter undgås og fejl kategoriseres.
Femte del er Business Central. Her skal integrationen bruge en bevidst integrationsflade – ikke skrive direkte i SQL-tabeller eller omgå den forretningslogik, som holder ERP-systemet konsistent.
Når arkitekturen er delt op på denne måde, får I flere fordele:
- Shopify-webhooks kan kvitteres hurtigt.
- Business Central beskyttes mod trafikspidser.
- Ordrer kan behandles kontrolleret og genkøres.
- Fejl kan ses og håndteres i stedet for at forsvinde.
- Nye integrationer kan tilføjes uden at bygge hele løsningen om.
- I kan skalere ordrebehandling uden at skalere alt andet samtidig.
Det er ofte den væsentligste forskel mellem en løsning, der fungerer i begyndelsen, og en løsning, der fortsat fungerer, når virksomheden får flere butikker, markeder, varer og ordrer.
API Pages: byg en integrationskontrakt, ikke en genvej
Business Central har flere måder at eksponere data på. I kan bruge standard-API’er, publicerede OData-pages, API Queries og Codeunits. Hver type har sin plads.
Microsoft anbefaler REST API-stakken som den foretrukne integrationsvej, og Business Central kan både bruge indbyggede API’er og egne custom API’er. Microsofts overblik over Business Central-webservices beskriver forskellen mellem REST API’er, OData og SOAP samt hvilke objekt-typer der egner sig til de enkelte formål.
Når I skal bygge en stabil og langsigtet integration, er API Pages ofte et stærkt udgangspunkt.
En API Page er en AL-page med PageType = API. Den er skabt til integrationsbrug og ikke til almindelig visning i Business Central-brugerfladen. Den kan versionsstyres og eksponeres som en OData v4-aktiveret REST-webservice. Microsofts dokumentation om API Pages beskriver netop API Pages som versionerede integrationsendpoints.
Det vigtige er ikke blot at eksponere en tabel.
Det vigtige er at definere en kontrakt.
Hvis Shopify skal hente salgsklare produkter, behøver I ikke eksponere alle felter fra varetabellen. I bør eksponere de felter, integrationen faktisk har brug for:
- Stabilt eksternt ID.
- Varenummer.
- Variantkode.
- SKU og EAN.
- Status for online-salg.
- Salgsklart lager.
- Pris og valuta, hvis ERP ejer prislogikken.
- Sidst ændret-tidspunkt.
- Relevante produktattributter.
En API-kontrakt bør være afgrænset, stabil og forståelig. Den må gerne være mindre end den underliggende tabel.
Et forenklet eksempel kan se sådan ud:
page 50120 "Shopify Item API"
{
PageType = API;
APIPublisher = 'connectify';
APIGroup = 'shopify';
APIVersion = 'v1.0';
EntityName = 'shopifyItem';
EntitySetName = 'shopifyItems';
SourceTable = Item;
layout
{
area(content)
{
field(id; Rec.SystemId) { Caption = 'id'; }
field(number; Rec."No.") { Caption = 'number'; }
field(description; Rec.Description) { Caption = 'description'; }
field(gtin; Rec.GTIN) { Caption = 'gtin'; }
field(lastModifiedAt; Rec.SystemModifiedAt) { Caption = 'lastModifiedAt'; }
}
}
}
I en rigtig løsning vil I typisk bruge en særskilt integrationstabel eller supplerende logik, hvis data som salgsklart lager eller online-status ikke findes direkte på varekortet.
Det afgørende er, at I ikke gør en intern tabelstruktur til jeres offentlige kontrakt ved et tilfælde.
API’er skal behandles som produkter. De skal dokumenteres, versioneres, testes og ændres med omtanke.
Hvis I senere får brug for at ændre feltstruktur eller forretningsregler, er det langt bedre at introducere version v2.0 end at ændre et endpoint, som en driftskritisk integration allerede afhænger af.
Hvis I vil have en mere grundlæggende introduktion til Business Centrals API-landskab, er Business Central API V2-guiden et naturligt sted at starte.
OData: effektivt til dataudtræk, men ikke svaret på alt
OData er en HTTP-baseret standard, som Business Central kan bruge til at eksponere data som JSON. Den er særligt nyttig, når integrationen skal læse afgrænsede datasæt, filtrere på ændringer eller slå bestemte records op.
OData er for eksempel godt til:
- Vareudtræk.
- Lagerudtræk.
- Kundesøgning.
- Hentning af ændringer siden sidste synkronisering.
- Statusopslag.
- Afstemning af data mellem systemer.
Microsofts OData-oversigt for Business Central er værd at kende, fordi Business Centrals implementering ikke nødvendigvis understøtter alle dele af OData-standarden.
Et målrettet OData-kald kan eksempelvis kun hente de felter og varer, som faktisk er ændret:
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
Det er en langt sundere strategi end at hente hele varetabellen hvert femte minut for at opdage få ændringer.
Ved On-Premises kan I styre størrelsen på OData-sider og anvende Prefer: odata.maxpagesize for at holde store datasæt i kontrollerede bidder. Microsoft beskriver, hvordan paging begrænser risikoen for timeouts og højt hukommelsesforbrug i vejledningen om serverstyret OData-paging.
Paging bør ses som en del af integrationsdesignet.
Hver side skal kunne behandles selvstændigt.
Integrationen bør gemme sit checkpoint.
Et afbrudt job skal kunne fortsætte uden at starte forfra eller oprette dubletter.
OData er dog ikke altid den bedste måde at udføre en kompleks forretningshandling på. Det er sjældent nok at POSTe en ordre direkte til en generisk salgsordre-page. En ordre kan kræve kundeopslag, validering, momslogik, rabatfordeling, kreditkontrol, dimensionsstyring og særregler.
Der skal I ofte bruge en Codeunit.
Codeunits: når integrationen skal udføre en forretningsproces
En Codeunit er det rigtige værktøj, når en integration skal udføre en proces frem for blot at oprette eller læse et dataobjekt.
Det kan eksempelvis være processen “behandl Shopify-ordre”.
Den kan bestå af:
- Kontrollér, om ordren allerede er behandlet.
- Find eller opret kunden.
- Find varer og varianter.
- Opret salgsheader.
- Opret linjer med Business Centrals normale validering.
- Fordel rabatter og fragt.
- Sæt betalings-, leverings- og dimensionsoplysninger.
- Gem Shopify-referencer.
- Returnér en entydig status.
Et forenklet eksempel kan se sådan ud:
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);
IntegrationOrder."BC Document No." := SalesHeader."No.";
IntegrationOrder."Processing Status" :=
IntegrationOrder."Processing Status"::Completed;
IntegrationOrder."Processed At" := CurrentDateTime;
IntegrationOrder.Modify(true);
end;
}
I behøver ikke nødvendigvis at eksponere selve Codeunit’en direkte mod Shopify. Ofte er det bedre, at integrationslaget opretter en integrationsrecord via et endpoint, hvorefter Business Central behandler den kontrolleret i en Job Queue.
Det giver bedre sporbarhed, bedre fejlhåndtering og mindre risiko for, at et eksternt kald forsøger at gennemføre en tung ERP-proces synkront.
Hvis I arbejder med custom API’er, er Microsofts API-udvikleroversigt nyttig. Den skelner blandt andet mellem API Pages til læse- og skriveoperationer og API Queries til read-only-scenarier på tværs af flere tabeller.
På Connectify findes også en mere praksisnær introduktion til Business Central API-endpoints, hvis I skal forstå, hvilke endpoints der passer til hvilke dataflows.
Shopify GraphQL Admin API: den moderne integrationsflade
På Shopify-siden bør nye integrationer tage udgangspunkt i GraphQL Admin API.
GraphQL gør det muligt at hente præcis de felter og relationer, integrationen har brug for. Det betyder færre unødige kald og en mere kontrolleret datamængde.
I stedet for at hente en ordre, derefter kunden, derefter linjerne, derefter rabatterne og derefter leveringsdata i separate forespørgsler, kan I ofte samle de nødvendige data i én GraphQL-query.
Et eksempel på et ordreudtræk kan se sådan ud:
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 bruger globale ID’er, ofte på formatet gid://shopify/Order/.... De bør gemmes som tekniske referencer i integrationslaget og, når det giver mening, i Business Central.
Shopify har detaljeret dokumentation for GraphQL Admin API, men det vigtigste arkitekturprincip er enkelt: Hent kun det, I behøver.
En integration, der hver gang henter alle produkter, alle varianter, alle metafields og hele kundehistorikken, bliver langsom og unødigt dyr i API-forbrug.
Det er også vigtigt at forstå Shopifys rate limits. GraphQL Admin API arbejder med cost-baseret throttling. Det betyder, at en forespørgsels belastning afhænger af kompleksiteten, ikke kun af antallet af kald. Shopify anbefaler selv caching, ansvarlig retry og købaseret behandling ved throttling. Se den aktuelle dokumentation om Shopify API-limits.
Integrationsmotoren bør derfor:
- Overvåge GraphQL cost.
- Begrænse parallelle kald.
- Hente få og relevante felter.
- Bruge cursor-baseret pagination.
- Vente, når Shopify signalerer throttling.
- Bruge bulk-udtræk til store initiale datasæt.
Til store produkt-, kunde- eller ordreudtræk er Shopifys asynkrone Bulk Operations ofte et bedre valg end mange små paginerede kald. Shopify leverer resultater som JSONL, når operationen er gennemført. Shopifys dokumentation om Bulk Operations forklarer det asynkrone mønster og den efterfølgende resultathåndtering.
Bulk Operations er gode til initial load.
Webhooks og målrettede API-kald er bedre til løbende drift.
De to mekanismer skal ikke konkurrere. De skal arbejde sammen.
Webhooks: brug dem som signal, ikke som hele integrationsprocessen
Webhooks er fundamentet i en moderne Shopify-integration.
I stedet for at spørge Shopify hvert minut, om der er sket noget, kan Shopify sende en hændelse, når en relevant ændring opstår. Det kan være en oprettet ordre, ændret produkt, lagerrelateret hændelse, refundering eller fulfillment.
Shopifys aktuelle webhook-dokumentation viser de tilgængelige topics og mulighederne for at oprette subscriptions gennem app-konfiguration eller GraphQL Admin API.
Men et webhook må ikke forstås som en garanti for, at arbejdet er fuldført.
Et webhook er en besked om, at noget er sket.
Det er ikke nødvendigvis den eneste besked, I får om det samme objekt.
En ordre kan blive oprettet, betalt, redigeret, annulleret, fulfillede og refunderet. En produktvariant kan blive opdateret flere gange på kort tid. Et webhook kan blive leveret igen, hvis jeres endpoint ikke kvitterer korrekt, eller hvis leveringen skal genforsøges.
Derfor bør webhook-endpointet gøre så lidt som muligt:
- Modtag eventet.
- Verificér afsenderen.
- Gem event og metadata.
- Deduplikér.
- Læg eventet i en kø.
- Kvittér hurtigt.
Det endpoint bør ikke oprette en salgsordre direkte i Business Central. Hvis ERP-systemet er langsomt eller kortvarigt utilgængeligt, må den modtagne ordre ikke gå tabt eller få Shopify til at vente.
Webhook-sikkerhed er afgørende. Shopify sender HMAC-signaturer i headers, og integrationen skal verificere dem mod den rå request-body, før payloaden ændres eller behandles. Shopify dokumenterer både HMAC-header, event-ID og webhook-ID i sin vejledning om events og levering.
Gem som minimum følgende data ved modtagelse:
- Shopify-shopdomæne.
- Topic.
- Webhook-ID.
- Event-ID.
- Tidspunkt.
- API-version.
- Rå payload eller sikker reference til payload.
- HMAC-valideringsresultat.
- Behandlingsstatus.
- Correlation ID.
Når en kunde eller medarbejder spørger, hvorfor en bestemt ordre ikke er landet i ERP, skal I kunne følge den fra event til kø, videre til Business Central og eventuelt tilbage til Shopify.
Det er ikke luksus. Det er grundlæggende driftsdisciplin.
Køer: det, der gør integrationen robust
En kø skaber afstand mellem Shopify og Business Central.
Det lyder teknisk, men værdien er meget forretningsnær.
Shopify kan modtage mange ordrer på få minutter. Business Central kan være i gang med månedsafslutning, backup, rapportering eller normal brugertrafik. Hvis Shopify tvinges til at vente på Business Central, bliver integrationen skrøbelig.
Når webhooken lægger arbejdet i kø, kan Business Central behandle jobs i det tempo, som ERP-miljøet kan håndtere.
I kan for eksempel have separate jobtyper for:
- Ordreimport.
- Kundeoprettelse.
- Produktændringer.
- Lageropdateringer.
- Fulfillment-status.
- Refunderinger.
- Afstemninger.
Det gør en stor forskel. En omfattende produktimport må ikke blokere for nye ordrer. En fejl i en refundering må ikke holde lageropdateringer tilbage.
For ordredata bør I også tænke på rækkefølge.
Hvis en ordre oprettes, derefter annulleres og senere refunderes, må processerne ikke behandles i vilkårlig rækkefølge. En praktisk tilgang er at lade events for samme Shopify Order ID blive behandlet sekventielt, mens ordrer med forskellige ID’er godt kan behandles parallelt.
På den måde får I både konsistens og kapacitet.
En kø bør have tydelige tilstande:
- Received.
- Queued.
- Processing.
- Completed.
- Retry scheduled.
- Needs attention.
- Dead letter.
Dead letter betyder, at et job ikke længere skal genforsøges automatisk. Det kan eksempelvis være, fordi SKU’en ikke findes i Business Central, eller fordi en opsætning mangler. Den type fejl kræver en medarbejder – ikke ti ekstra tekniske forsøg.
Idempotens: den vigtigste beskyttelse mod dubletter
Idempotens betyder, at samme operation kan udføres flere gange uden at skabe flere resultater.
Det er afgørende i integrationer.
Forestil jer, at integrationsmotoren opretter en salgsordre i Business Central. Ordren når at blive oprettet, men netværksforbindelsen falder ud, før integrationsmotoren modtager svaret. Den ved nu ikke, om ordren findes eller ej.
Hvis den bare prøver igen, risikerer I en dubletordre.
Det samme kan ske ved timeout, worker-crash, servicegenstart, genleverede webhooks eller manuelle genkørsler.
Derfor skal en ordreintegration have mindst to lag af idempotens.
Først teknisk deduplikering. Den bruger webhook-ID eller event-ID til at sikre, at samme levering ikke behandles flere gange.
Dernæst forretningsmæssig deduplikering. Den bruger Shopify Order ID som stabil nøgle og sikrer, at samme ordre aldrig bliver oprettet som flere Business Central-dokumenter.
En god Business Central-integration gemmer Shopify Order ID i en dedikeret integrationstabel eller på selve salgsordren. Før en ny ordre oprettes, undersøger processen, om den allerede er behandlet.
Kontrollen skal ske atomisk. To samtidige workers må ikke begge nå frem til, at ordren mangler, og derefter begge oprette den.
For lager gælder et lignende princip.
I stedet for at sende “træk én enhed fra”, bør integrationslaget normalt opdatere en absolut værdi:
“Salgsklart lager for denne variant og lokation er nu 42.”
Det er mere robust, fordi events kan komme to gange eller i forkert rækkefølge. En absolut tilstand kan erstattes. Et delta kan akkumuleres forkert.
Retry-strategi: genforsøg med omtanke
Der vil opstå fejl. Det er ikke et tegn på en dårlig integration. Det er et vilkår, når flere systemer, netværk og afhængigheder arbejder sammen.
Det afgørende er, hvordan integrationen reagerer.
Midlertidige fejl skal typisk genforsøges. Det kan være:
- Shopify throttling.
- Timeout.
- Kortvarigt netværksudfald.
- Midlertidig fejl i Business Central Server.
- Planlagt genstart.
- HTTP 502, 503 eller lignende tekniske svar.
Permanente fejl kræver derimod normalt afklaring. Det kan være:
- Ukendt SKU.
- Manglende momsbogføringsopsætning.
- Lukket regnskabsperiode.
- Ugyldig landekode.
- Manglende kundematch.
- Utilstrækkelige adgangsrettigheder.
- Ugyldigt betalings- eller leveringssetup.
En god retry-strategi bruger eksponentiel backoff. Det betyder, at integrationen venter længere mellem hvert forsøg. For eksempel efter 30 sekunder, derefter to minutter, ti minutter og en time.
Læg gerne variation ind i ventetiden, så mange jobs ikke forsøger igen samtidigt og skaber en ny belastningsspids.
Ved Shopify-throttling skal integrationen følge det API-budget, Shopify oplyser. Et throttle-svar er ikke en invitation til at sende flere kald. Det er et signal om at vente.
Ved forretningsfejl bør jobbet gå til en tydelig afklaringskø. Fejlen skal kunne forstås af den person, der skal løse den:
“Ordre #10432 kunne ikke oprettes, fordi Shopify SKU
ABC-RED-XLikke findes som vare eller variant i Business Central.”
Det er langt mere brugbart end:
“HTTP 400 – validation error.”
Master data: produkterne og kunderne afgør, om ordreflowet lykkes
Mange integrationsprojekter starter med ordrer. Det giver god mening, fordi ordren er synlig og direkte knyttet til omsætning.
Men master data er ofte den egentlige nøgle til stabil drift.
Hvis varen ikke kan matches, kan ordren ikke behandles korrekt.
Hvis kunden ikke kan identificeres, kan ordren ikke placeres rigtigt.
Hvis landekoder, momsregler eller leveringsmetoder ikke er konsistente, opstår fejl senere i processen.
Produktidentitet skal derfor være entydig.
Shopify arbejder med produkter og varianter. Business Central kan arbejde med varenummer, variantkode, enheder, styklister og forskellige varestrukturer.
En typisk model kan være:
- Shopify Product: kundevendt produkt.
- Shopify Variant: konkret købbar og lagerført variant.
- Business Central Item: vare eller produktfamilie.
- Business Central Item Variant: eksempelvis farve eller størrelse.
Men modellen afhænger af jeres forretning. Nogle virksomheder bruger ét varenummer pr. fysisk variant. Andre bruger varenummer plus variantkode.
Det vigtige er, at Shopify SKU kan mappes entydigt til den salgbare enhed i Business Central.
Undgå at bruge produktnavne som nøgle. Navne ændrer sig.
Undgå også at antage, at en Shopify-produkt-ID automatisk er den rigtige forretningsnøgle i ERP. Shopify-ID’er er gode tekniske referencer, men medarbejdere, indkøb og lager arbejder ofte med varenummer, EAN og variant.
For kunder skal I definere en bevidst model.
I B2C kan en diverse debitor være en enkel og korrekt løsning, hvis kundedata primært skal blive i Shopify, og Business Central kun har brug for den økonomiske ordre.
I B2B vil I ofte have behov for en faktisk debitorrelation i Business Central. Her kan e-mail være en nyttig indikator, men sjældent nok som eneste nøgle. CVR-nummer, Shopify Company ID, debitorens eksterne reference og godkendte relationstabeller kan være mere robuste.
Hvis I har kundespecifikke priser, kreditkontrol, betalingsbetingelser eller flere leveringsadresser, bør I behandle B2B som et selvstændigt integrationsområde. Connectifys guide til Shopify B2B og Shopify Plus er et relevant næste skridt, hvis jeres webshop skal afspejle Business Central-kundedata og prislogik.
Produktsynkronisering: spejl ikke alt
Shopify og Business Central bruger produktdata til forskellige ting.
Shopify skal præsentere og sælge produktet. Derfor arbejder platformen med billeder, collections, tags, beskrivelser, metafields, SEO og merchandising.
Business Central skal købe, lagre og bogføre varen. Derfor arbejder ERP-systemet med kostpriser, varebogføringsgrupper, leverandørrelationer, genbestilling, lokationer og lagerposter.
I bør ikke forsøge at spejle alle felter mellem systemerne.
I bør definere, hvem der ejer hvilke felter.
Business Central kan eksempelvis eje:
- SKU og varenummer.
- Variantstruktur.
- EAN.
- Vægt og mål, hvis de bruges i logistik.
- Salgsenhed.
- Salgsklar status.
- Lagerstatus.
- Standardpris, hvis priser styres i ERP.
Shopify kan eksempelvis eje:
- Produktbeskrivelser.
- Billeder.
- Collections.
- Tags.
- SEO-titel og metabeskrivelse.
- Kampagnetekster.
- Kundevendte metafields.
Hvis I arbejder med PIM, kan PIM-systemet blive master for produktindhold, mens Business Central fortsat ejer den logistiske og økonomiske varedata.
Det er også vigtigt at skelne mellem:
- Varen findes i Business Central.
- Varen er aktiv i Business Central.
- Varen må sælges i Shopify.
- Varen må sælges på denne specifikke Shopify-kanal eller i dette marked.
En aktiv ERP-vare er ikke altid klar til webshoppen. Den kan være en intern reservedel, en vare under oprettelse, en udgået artikel, en B2B-only-vare eller et produkt uden godkendt content.
“Kan sælges online” bør derfor være en eksplicit forretningsregel.
Lagersynkronisering: synkronisér salgsklar beholdning
Lager er en af de mest kritiske strømme i hele integrationen.
Hvis lageret er for højt i Shopify, kan I oversælge.
Hvis lageret er for lavt, mister I salg.
Hvis lageret er uforståeligt, mister medarbejderne tillid til både webshop og ERP.
Derfor skal I ikke bare sende fysisk beholdning fra Business Central til Shopify. I skal beregne et salgsklart lager.
En forenklet formel kan være:
Salgsklart lager =
fysisk beholdning
- reserveret beholdning
- sikkerhedslager
- beholdning på ikke-salgbare lokationer
Men den konkrete regel afhænger af jeres drift.
Har I flere lagre?
Har I fysiske butikker?
Sælger I fra 3PL?
Har I varer på vej hjem?
Accepterer I backorders?
Reserverer I varer i Business Central ved ordreimport?
Sælger I de samme varer på Shopify, B2B-portal, markedspladser og fysisk POS?
Alle de spørgsmål påvirker, hvad Shopify skal vise som købbar beholdning.
Salgsklart lager bør normalt opdateres som en absolut værdi. Hvis Business Central beregner, at der må sælges 17 enheder, skal Shopify modtage værdien 17. Det er mere robust end at sende små plus- og minusændringer.
En moderne løsning bruger typisk to mekanismer samtidig:
- Eventdrevet synkronisering, når lager ændrer sig.
- Periodisk afstemning, der finder og retter afvigelser.
Eventdrevet lager giver hurtighed.
Afstemning giver tillid.
En natlig eller timebaseret afstemning kan hente den beregnede beholdning fra Business Central, sammenligne med Shopify og kun opdatere de varer, hvor der findes en reel afvigelse.
Det er også en god måde at opdage fejl, der ikke skyldes integrationen direkte, eksempelvis manuelle lagerreguleringer eller uventede ændringer i et tredjepartssystem.
Connectifys Shopify-integrationsside beskriver allerede lagerafstemning på tværs af ERP og Shopify som et centralt flow. Den dybe lagerlogik bør dog altid afspejle jeres konkrete lokationer, reservationer og kundeløfter.
Ordreimport: fra Shopify checkout til korrekt ERP-proces
En ordre i Shopify er ikke automatisk det samme som en salgsordre i Business Central.
Nogle virksomheder vil oprette en salgsordre, som senere plukkes, leveres og faktureres i ERP.
Andre vil oprette en faktura eller en mere forenklet dokumentproces.
Nogle bruger diverse debitor til B2C.
Andre opretter alle kunder som selvstændige debitorkonti.
Nogle bogfører ved fulfillment.
Andre bogfører efter payment capture eller i en særskilt afstemningsproces.
Der findes ikke én korrekt model. Men modellen skal være bevidst.
En robust ordreproces gør typisk følgende:
- Modtager Shopify-eventet.
- Kontrollerer idempotens.
- Henter nødvendig, opdateret ordredata via GraphQL.
- Finder korrekt Business Central-selskab.
- Matcher eller opretter kunden.
- Matcher varer og varianter.
- Opretter salgsdokumentet gennem BC-validering.
- Håndterer rabat, fragt, moms og betaling.
- Gemmer Shopify Order ID og relevante transaktionsreferencer.
- Logger resultatet og gør status sporbar.
Pris og rabat skal designes særligt omhyggeligt.
Shopify kan have rabatkoder, automatiske rabatter, linjerabatter, rabat på ordreniveau, gavekort og afrunding. Business Central kan have sin egen pris- og rabatlogik.
I skal beslutte, om Business Central skal genberegne pris, eller om Shopify-ordrens kommercielle resultat er styrende.
For mange B2C-forretninger er det afgørende, at ERP afspejler det beløb, kunden faktisk har betalt. I B2B kan det være vigtigere, at Business Centrals kontraktpriser styrer.
Det er sjældent klogt at lade denne beslutning opstå tilfældigt i mapping-koden.
Fragt skal behandles som en tydelig linje eller en tydelig forretningsregel. Det samme gælder gavekort, betalingsgebyrer og rabatter. Jo bedre I kan forklare hvert beløb i Business Central, desto lettere bliver økonomisk afstemning.
Hvis betalingsdata skal matches og udlignes automatisk, kan en særskilt betalingsintegration være relevant. Connectifys Billwerk-integration viser eksempelvis, hvordan Shopify-betalinger og Business Central kan kobles i en proces med automatisk udligning.
Fulfillment, annulleringer og refunderinger er en del af ordren
En integration slutter ikke, når ordren er oprettet.
Hvis Business Central eller et WMS-system styrer pluk og afsendelse, skal fulfillment-status normalt sendes tilbage til Shopify. Kunden skal kunne se, om ordren er behandlet, sendt eller delvist leveret.
Det kræver en klar beslutning om, hvor fulfillment-sandheden ligger.
Hvis et 3PL-system fysisk pakker og sender ordren, kan 3PL være den primære kilde til trackingnummer og leveringstidspunkt. Business Central og Shopify modtager derefter den samme operationelle information gennem integrationslaget.
Delvise leveringer kræver ekstra omtanke. En ordre med fem linjer kan være leveret i to omgange. Integrationen skal kunne holde styr på de konkrete line item IDs og mængder, ikke kun hele ordren.
Annulleringer skal også have en proces.
Hvis kunden annullerer i Shopify, før lageret har behandlet ordren, skal den tilhørende BC-ordre måske annulleres eller stoppes.
Hvis varen allerede er plukket, kan der være en intern proces.
Hvis varen er leveret, er det ofte ikke længere en annullering, men en retur og en kreditnota.
Refunderinger skal kunne følges tilbage til den oprindelige ordre og de konkrete ordrelinjer. Gem derfor Shopify refund ID, beløb, moms, varelinjer og eventuelle returårsager, hvis de er relevante for jeres proces.
Sikkerhed: beskyt data og beskyt ERP-miljøet
En Shopify-Business Central-integration håndterer ofte persondata, ordreinformation, API-tokens og adgang til et forretningskritisk ERP-system.
Sikkerhed skal derfor ligge i arkitekturen fra starten.
Business Central On-Premises bør ikke eksponeres bredt mod internettet, hvis det kan undgås. Brug i stedet en kontrolleret forbindelsesvej mellem integrationslaget og virksomhedens netværk.
Det kan være VPN, reverse proxy med stram adgangskontrol, private netværksforbindelser eller en lokal connector, der selv etablerer en udgående forbindelse.
Brug HTTPS hele vejen.
Gem ikke API-nøgler og secrets i kildekode, regneark eller ukrypterede konfigurationsfiler. Shopify access tokens, webhook secrets, Business Central-legitimationsoplysninger og certifikater bør håndteres i et secrets management-system med tydelige adgangsrettigheder og mulighed for rotation.
Anvend mindst mulige rettigheder.
Shopify-appen skal kun have de scopes, den behøver.
Business Central-integrationsbrugeren skal kun kunne udføre de operationer, integrationen har behov for.
En integrationsbruger med fulde administratorrettigheder kan være hurtig at sætte op under udvikling, men er en dårlig driftsmodel.
For On-Premises skal I også huske, at API’er og webservices skal være aktiveret på serveren. Hvis API-, OData- eller SOAP-tjenester er slået fra, kan endpoints returnere fejl som HTTP 405. Microsoft beskriver det i sin dokumentation om aktivering af Business Central API’er i On-Premises-miljøer.
Sikkerhed handler også om dataopbevaring.
Gem kun persondata, når der er et legitimt driftsbehov.
Definér, hvor længe rå webhookpayloads opbevares.
Begræns adgangen til fejlvisning og logs.
Sørg for, at I kan håndtere sletning og dataanmodninger i de systemer, hvor I opbevarer oplysninger.
Monitoring: I skal kunne se, hvad integrationen laver
En integration uden overvågning er en sort boks.
Når alt fungerer, tænker ingen over den.
Når noget fejler, bliver den pludselig centrum for kundeservice, lager, økonomi og e-commerce-teamet.
Derfor skal løsningen have logs, metrics og sporbarhed.
Logs fortæller, hvad der skete.
Metrics fortæller, hvordan løsningen har det.
Sporbarhed forbinder dem.
Hvert ordreflow bør have et correlation ID, så I kan følge processen fra Shopify-event til integrationsjob, Business Central-dokument og eventuel fulfillment-opdatering.
Relevante målepunkter kan være:
- Antal modtagne webhooks.
- Antal færdigbehandlede ordrer.
- Gennemsnitlig behandlingstid.
- Antal retries.
- Jobs i dead-letter-kø.
- Shopify API-cost.
- Shopify throttle-hændelser.
- Business Central-responstid.
- Antal lagerafvigelser.
- Ordrer, der venter på manuel afklaring.
Alarmer skal være meningsfulde.
Det giver ikke meget værdi at få en besked om hvert enkelt genforsøg. Det giver værdi at få en alarm, hvis ordreimporten har været stoppet i 15 minutter, hvis dead-letter-køen vokser, eller hvis lagerafstemningen finder væsentlige afvigelser.
Business Central API-kald bør også måles. Microsoft har konkrete anbefalinger til målrettede dataudtræk, paging og effektiv klientadfærd i sin vejledning om API- og OData-performance.
En driftsflade bør kunne bruges af mere end udviklere. En ERP-konsulent eller e-commerce-ansvarlig bør kunne se:
- Om integrationen kører.
- Hvilke ordrer der er gennemført.
- Hvilke fejl der kræver handling.
- Hvorfor et specifikt job fejlede.
- Om lageret er afstemt.
- Hvilken Business Central-ordre der svarer til en Shopify-ordre.
Det gør virksomheden mindre afhængig af enkeltpersoner og langt hurtigere til at reagere på afvigelser.
Performance: skån Business Central og respekter Shopify
Performance handler ikke kun om at få et lavt svartidstal.
Det handler om at bruge systemerne fornuftigt.
Business Central On-Premises deles ofte mellem integrationer, brugere, rapporter, baggrundsjob og andre systemer. En dårlig integrationsforespørgsel kan derfor påvirke mere end bare webshoppen.
På Business Central-siden bør I:
- Filtrere data så tæt på kilden som muligt.
- Hente få felter.
- Bruge paging.
- Gemme checkpoints.
- Begrænse parallelle skriveoperationer.
- Undgå meget lange transaktioner.
- Bruge API Queries til read-only-udtræk, hvor det passer.
- Måle svartider og fejl for hvert endpoint.
På Shopify-siden bør I:
- Hente præcis de felter, der bruges.
- Holde GraphQL-queries små og målrettede.
- Respektere cost-budget.
- Bruge webhooks frem for aggressiv polling.
- Bruge Bulk Operations til historiske og store udtræk.
- Cache data, når friskhedskravet tillader det.
Initial load og løbende synkronisering bør være to forskellige processer.
Initial load handler om at hente et stort grunddatasæt – eksempelvis alle produkter, varianter eller historiske ordrer. Det er en planlagt batchproces.
Løbende synkronisering handler om ændringer siden sidst. Det er webhook- og delta-drevet.
Hvis I bruger samme metode til begge dele, bliver løsningen ofte enten langsom i hverdagen eller skrøbelig ved store datamængder.
Test den virkelige verden – ikke kun testordren
En enkelt testordre med én vare og dansk adresse beviser næsten ingenting.
En driftsklar integration skal testes med de situationer, der faktisk opstår:
- Flere ordrelinjer.
- Variantvarer.
- Rabatkoder.
- Automatiske rabatter.
- Fragtlinjer.
- Gavekort.
- Delvise leveringer.
- Fuld og delvis refundering.
- Ukendt SKU.
- Udsolgt vare.
- Eksisterende og nye kunder.
- B2B-kunde med prisgruppe.
- Flere lagerlokationer.
- Dubletwebhook.
- Events i forkert rækkefølge.
- Timeout efter oprettelse.
- Midlertidigt nedbrud i Business Central.
- Shopify throttling.
- Manuel genkørsel af et fejlet job.
Den bedste test er ofte at skabe fejl med vilje i et kontrolleret testmiljø.
Stop adgangen til Business Central i kort tid.
Se, om eventet bliver liggende i kø.
Se, om processen genkøres.
Se, om resultatet stadig kun bliver én salgsordre.
Det er den type test, der beviser, om integrationen er robust.
Sådan bør I implementere løsningen
Et stærkt projekt kan godt gennemføres i faser.
Første fase er afklaring. Her beskriver I dataansvar, processer, undtagelser, systemgrænser og succeskriterier. Lager, økonomi, e-commerce, kundeservice og ERP skal være repræsenteret.
Anden fase er grundarkitektur. Her fastlægges API-kontrakter, netværksadgang, sikkerhed, køer, logging, dataidentiteter og fejlhåndtering.
Tredje fase er master data. Produkter, varianter, kundematch, lokationer og lagerregler skal være på plads, før ordreforretningen bliver kompleks.
Fjerde fase er ordreimport. Start med den mest almindelige ordretype. Byg idempotens, retry og fejlvisning ind fra begyndelsen.
Femte fase er ordrelivscyklussen: fulfillment, tracking, annullering, retur og refundering.
Sjette fase er driftsmodning: afstemning, dashboards, alarmer, supportansvar og løbende optimering.
En god runbook er en del af leverancen. Den skal beskrive, hvad virksomheden gør, når:
- En vare mangler i Business Central.
- En ordre ikke kan matches til en kunde.
- Lageret afviger.
- Shopify-token er tilbagekaldt.
- Business Central ikke svarer.
- Et job ligger i dead letter.
- En kunde efterlyser en ordre, som endnu ikke kan ses i ERP.
Det er sådan, I gør integrationen til en driftsløsning frem for et udviklingsprojekt.
Ja — afslut i stedet med en handlingsorienteret overgang til Connectify, uden at opsummere artiklen.
Klar til at få styr på Shopify og Business Central?
En stabil Shopify- og Business Central-integration handler ikke kun om at flytte data. Den handler om at få ordreflow, lager, økonomi og kundedata til at arbejde sammen i den virkelige hverdag.
Det kræver, at jeres integration passer til jeres systemer, jeres arbejdsgange og den måde, I vil vokse på.
Hos Connectify hjælper vi virksomheder med at skabe stabile dataflows mellem Shopify, Dynamics 365 Business Central og resten af systemlandskabet – uden at I skal bruge tiden på manuelle rettelser, lagerafvigelser og uklare fejlmeldinger.
Se hvordan andre virksomheder bruger Connectify, eller tag fat i os, hvis I vil have afklaret, hvordan jeres Shopify- og Business Central-setup kan hænge bedre sammen.