Legacy Integration — Zwerfkei Backoffice (legacy) & Navision 2018¶
This page documents how the current (legacy) Zwerfkei platform integrates with Microsoft Dynamics Navision 2018 via the K3 Retail / LS Retail extension. It serves as reference material during the migration to the new architecture.
Legacy system
This integration belongs to Zwerfkei Backoffice (legacy) (CodeIgniter PHP). It uses SOAP web services against Navision 2018, which reaches end-of-support in 2026. The new platform will use the Business Central REST API instead.
Architecture¶
The integration is a two-way, SOAP-based sync between Zwerfkei Backoffice (legacy) and Navision. Two separate patterns are used:
- Inbound (NAV → Web): Continuous polling — a cron job calls Navision's sync buffer every minute and pulls any changed records.
- Outbound (Web → NAV): Queue-based — the application writes a pending record to the
k3_synchronizationtable; a separate cron processes the queue and calls the appropriate SOAP operation.
sequenceDiagram
participant Cron as Cron: k3retail_webservices
participant Buffer as NAV Sync Buffer
(GetSyncBuffer)
participant NAV as Navision 2018 SOAP
participant DB as Zwerfkei DB
(k3_* tables)
participant Queue as k3_synchronization
(outbound queue)
participant Sender as Cron: k3retail_sync
loop Every minute (50 sec inner loop)
Cron->>Buffer: GetSyncBuffer
Buffer-->>Cron: Changed record list
loop For each changed record
Cron->>NAV: GetProduct / GetSalesPrice / etc.
NAV-->>Cron: Record data
Cron->>DB: Upsert k3_* table
end
end
Note over Queue,Sender: Outbound queue processing
DB->>Queue: App writes pending record
(model, action, reference)
loop Every 5 minutes
Sender->>Queue: Read pending records
Sender->>NAV: SubmitOrder / SetMemberAccount / etc.
NAV-->>Sender: nav_id / confirmation
Sender->>Queue: Mark status = ok
end
Three WSDL services¶
The integration uses three separate SOAP endpoints on the Navision server:
| Service | Config key | Used for |
|---|---|---|
| LS Retail | wsdlLs |
Products, prices, discounts, stock, order status, sync buffer |
| NAV | wsdlNav |
Core Dynamics NAV operations |
| Kei | wdslKei |
Transactions, member accounts, purchases, value entries |
WSDL definitions are cached locally and refreshed hourly.
Data flows¶
Endpoint inventory (Google Sheets — Olaf)
Olaf logged all NAV calls over a one-week period to determine which endpoints are actually active in production. The sheet includes an "In use" column (confirmed via log analysis) and a "New webshop use" column listing the endpoints expected to be needed for the new platform.
The table below is the complete list from the codebase — not all calls present in the code are active in production. Use the sheet as the authoritative source.
| Entity | Direction | Trigger | SOAP operation |
|---|---|---|---|
| Products & variants | NAV → Web | Buffer cron | GetProduct |
| Sales prices | NAV → Web | Buffer cron | GetSalesPrice |
| Line discounts | NAV → Web | Buffer cron | GetSalesLineDiscount |
| Periodic discounts / bundles | NAV ↔ Web | Buffer cron + queue | GetPeriodicDiscount / SubmitPeriodicDiscount |
| Stock / availability | NAV ↔ Web | Buffer cron + manual | GetItemAvailability / StoreStockRequest |
| Item status | NAV → Web | Buffer cron | GetItemStatus |
| Order status updates | NAV → Web | Buffer cron | GetOrderStatus |
| Orders | Web → NAV | Outbound queue | SubmitOrder |
| Customers / members | NAV ↔ Web | Scheduled cron + queue | GetMemberAccount / SetMemberAccount |
| POS transactions | NAV → Web | Scheduled cron | GetTransactions |
| Purchase orders | NAV → Web | Scheduled cron | GetPurchaseHeader / GetPurchaseLine |
| Value entries (ledger) | NAV → Web | Scheduled cron | GetValueEntries |
| Member loyalty points | NAV → Web | Scheduled cron | GetMemberPointEntries |
Endpoint documentation (GetProduct / SubmitOrder / core webshop set)
There is no official documentation for these Navision 2018 / K3 Retail SOAP endpoints, so request/response formats are being worked out and written up manually as they're needed. SubmitOrder, GetProduct, GetSalesPrice and GetRealStock are now documented on this site with real schemas and live example payloads from the NAV test sandbox; GetPeriodicDiscount and GetOrderStatus have real schemas but still need a live example payload captured.
SubmitOrder (this site) Core Webshop Endpoints (this site) GetProduct (Google Doc, access pending) SubmitOrder (original Google Doc)
SubmitOrder test tooling (GitHub repo)
A small toolkit built while testing the SubmitOrder call directly against a NAV test environment: connection diagnostics, an operation lister, and dry-run-by-default scripts for SubmitCustomer / GetProduct / SubmitOrder. Useful as a hands-on starting point for debugging or exploring the SOAP integration — not required reading for the conceptual overview on this page. Private repo — requires access to the zwerfkei-flooris GitHub organisation.
Inbound sync — buffer pattern¶
All inbound sync flows through the GetSyncBuffer call. Navision queues every changed record internally; the website polls this queue continuously.
- Call
GetSyncBuffer→ NAV returns a list of changed records with table number and record ID. - For each record, call the appropriate
Get*operation by table number:
| NAV table number | Entity | SOAP call |
|---|---|---|
| 27 | Item (product) | GetProduct |
| 7002 | Sales Price | GetSalesPrice |
| 99001453 | Periodic Discount | GetPeriodicDiscount |
| 11176114 | Item Availability / Status | GetItemAvailability |
| 11176106 | Order Status | GetOrderStatus |
- Map the response to the local
k3_*model and upsert in the database. - Acknowledge the buffer entry so Navision doesn't resend it.
Outbound sync — queue pattern¶
Changes that need to be sent to Navision (orders, customer updates, discount edits) follow a queue pattern:
- The application creates a row in
k3_synchronizationwithstatus = pending. - The
k3retail_synccron reads pending rows and calls the appropriate SOAP operation. - On success:
status = ok,nav_idis stored back on the record. - On failure: retry counter incremented; up to 10 attempts before marking as error.
A database lock (GET_LOCK('k3_sync', 1)) prevents concurrent outbound runs.
Connection & error handling¶
- Authentication: HTTP Basic Auth (username + password) via
SoapClient. - Timeout: 30-second socket timeout per call.
- Retries: Up to 10 attempts per call.
- Error locking: On SOAP fault, a 5-minute cooldown lock prevents retry storms.
- Monitoring:
checkK3Synccron validates queue completeness and sends an alert email if records are stuck.
Kei endpoints — relevance decision¶
Per ZWE-392's DoD, the checked Kei endpoints (real usage evidence from the ERP administrator's log-based inventory) were reviewed for new-webshop relevance:
- Rejected as not webshop-relevant:
PhysInventory,GetOpenPhysInventory,GetPurchaseHeader,GetPurchaseLine,CreateMembershipCards— purchasing and physical-inventory administration, not webshop concerns. - Confirmed real, but out of scope for now:
GetMemberAccount,SetMemberAccount,CreateMemberAccount,GetMemberPointEntry— genuinely active loyalty/membership infrastructure (see Core Webshop Endpoints's note onGetPeriodicDiscount'sMemberPointslink), but decoupled from the current order-submit/order-status scope. Whether/how membership integrates with the new backend is deferred as a future migration decision, not part of this milestone.
Related pages¶
Sync Triggers & Cron Methods K3 Data Models ERP Sync Diagrams Business Central (new platform)