Skip to content
Supply Chain · Warehousing

Making D365 and Your 3PL Agree on the Truth

Caf2Code Thought Leadership June 15, 2026 6 min read

The decision to hand a warehouse to a third-party logistics provider is usually made for good reasons. The reason it goes sideways is almost never the 3PL's operations.

It is that you now have two systems that each believe they hold the truth about your inventory — and they update on different clocks.

d365-3pl-handshake.edi
The D365 and 3PL handshake Dynamics 365 is the system of record and the 3PL warehouse system handles execution. D365 directs with the 940 warehouse shipping order and the 943 inbound shipment notice; the 3PL confirms with the 945 warehouse shipping advice and the 944 receipt confirmation. A daily on-hand snapshot reconciles the two within tolerance. DYNAMICS 365 SYSTEM OF RECORD 3PL WAREHOUSE EXECUTION 01 · OUTBOUND · D365 DIRECTS, 3PL CONFIRMS Warehouse shipping order 940 Warehouse shipping advice 945 short ships, substitutions, and damage surface here 02 · INBOUND · STOCK ARRIVING AT THE 3PL Inbound shipment notice 943 Receipt confirmation 944 03 · RECONCILIATION · THE SAFETY NET Daily on-hand snapshot DAILY reconcile to D365 on-hand within tolerance, one named owner

D365 directs the 3PL with the 940 and the 943; the 3PL confirms reality back with the 945 and the 944. A daily on-hand snapshot reconciles the two. The dashed line is periodic reconciliation, not a transaction.

The decision to hand a warehouse to a third-party logistics provider is usually made for good reasons: you do not want to run a building in a region you are growing into, or you need overflow capacity for a season, or the 3PL already has the labor and the equipment and you do not. None of those reasons are wrong.

The reason it goes sideways is almost never the 3PL's operations. It is that you now have two systems that each believe they hold the truth about your inventory, and they update on different clocks. D365 thinks it knows what is on hand. The 3PL's warehouse system actually knows. Between those two facts sits every late shipment, every oversell, and every reconciliation meeting nobody enjoys.

So the real question is not "should we use a 3PL." It is "how do D365 and the 3PL stay in agreement about what exists, where it is, and what just happened to it."

The first decision: who runs the warehouse system

Before any integration, settle who owns warehouse execution for each location.

If you run the building, D365's native Warehouse Management handles it: locations, wave and load processing, mobile device steps — the whole execution layer lives inside D365 and there is one system of record.

If a 3PL runs the building, their warehouse system handles execution and D365 steps back to being the system of record for inventory and finance. D365 does not pick or pack at that site. It tells the 3PL what to do and listens for what the 3PL did.

A lot of confusion on these projects comes from not drawing that line cleanly per site. You can absolutely run native WMS in your own DCs and integrate to 3PLs for others, in the same D365 instance — we do it regularly. But each location has to be unambiguously one model or the other, and the org structure in D365 (site, warehouse) has to reflect that.

Why it matters: The execution-ownership line is the decision the whole integration hangs on. Get it right per site and the EDI handshake below has a clean job to do. Leave it fuzzy — "D365 sort of manages on-hand and the 3PL sort of does too" — and no amount of message mapping will make the two systems agree.

The handshake that actually matters

When a 3PL runs the building, the integration is a conversation made of a few EDI documents, and getting that conversation right is most of the work.

The outbound order. D365 tells the 3PL to ship something. In EDI terms this is the 940, the warehouse shipping order. It carries the order, the items, the quantities, and the ship-to.

The confirmation back. The 3PL tells D365 what it actually shipped. This is the 945, the warehouse shipping advice. This is the document that lets D365 relieve inventory and move the order forward, and it is the one people underestimate, because shipped is not the same as ordered. Short ships, substitutions, and damage all show up here, and D365 has to be ready to receive a 945 that does not match the 940 it sent.

The inbound side mirrors it. A 943 tells the 3PL stock is coming; a 944 confirms what they received. And the 856, the advance ship notice, is how the 3PL tells your customer's systems (or yours) what is on the truck.

The exceptions are the entire game. The temptation is to treat these as a one-time mapping exercise. They are not. They are an ongoing agreement about message timing and exception handling. Anybody can map a 940 that matches a 945 perfectly — the engagement is worth it when the short ship, the partial receipt, and the damaged return are handled on purpose.

On-hand is a timing problem, not a data problem

Here is the thing that surprises people. Even with the messages mapped perfectly, D365 and the 3PL will disagree about on-hand — briefly, constantly, all day long. The 3PL picked an order ten minutes ago and the 945 has not flowed yet. A receipt landed on their dock and the 944 is queued. The data is not wrong; it is in flight.

Two practical consequences follow.

First, decide how D365 reflects inventory that is at the 3PL but not yet confirmed in or out. If you let sales commit against numbers that lag reality by an hour, you will oversell during your busiest hours — which are exactly the hours the lag is worst.

Second, build the reconciliation in from the start, not after the first bad month. A periodic on-hand file from the 3PL — often a daily inventory snapshot — compared against D365 on-hand, with a defined owner and a defined tolerance, is what catches drift before it becomes a writeoff. The integration handles the transactions. The reconciliation handles the truth.

Returns, the part everyone forgets

Returns flow backward through all of this, and they are where ghost inventory is born. A unit comes back to the 3PL, gets received, and if the status and the message handling are not defined, it either reappears as sellable when it is damaged or vanishes when it is fine. Decide the return disposition and the message that carries it before go-live, not after the first customer complaint.

What we would tell you on day one

A 3PL relationship runs on the integration, and the integration runs on exceptions, not the happy path. Anybody can map a 940 that matches a 945. The engagement is worth it when the short ship, the partial receipt, the damaged return, and the hour-long lag during peak are all handled on purpose.

Draw the execution-ownership line per site and make D365's org structure match it. Treat the 945 and the 944 as first-class citizens, because confirmation is where reality enters the system. Build the daily reconciliation before you need it. Define return disposition up front.

Do that, and D365 and your 3PL will agree on the truth often enough — and disagree predictably enough — that nobody has to dread the month-end meeting.

Frequently asked questions

Which EDI documents connect D365 to a 3PL warehouse?

On the outbound side, D365 sends the 940 (warehouse shipping order) to tell the 3PL what to ship, and the 3PL returns the 945 (warehouse shipping advice) to confirm what actually shipped. On the inbound side, the 943 (warehouse stock transfer shipment advice) tells the 3PL stock is coming, and the 944 (warehouse stock transfer receipt advice) confirms what was received. The 856 advance ship notice tells the customer's systems what is on the truck.

Why is the EDI 945 so important?

The 945 is the document that lets D365 relieve inventory and move the order forward — because shipped is not the same as ordered. Short ships, substitutions, and damage all surface in the 945, so D365 has to be ready to receive one that does not match the 940 it sent. Treat the 945 and the 944 as first-class citizens; confirmation is where reality enters the system.

Should D365 or the 3PL be the system of record for inventory?

When a 3PL runs the building, the 3PL's warehouse system owns execution and D365 is the system of record for inventory and finance. D365 does not pick or pack at that site; it directs and listens. Draw that line cleanly per site and make the D365 org structure — site and warehouse — reflect it. You can run native D365 Warehouse Management in your own DCs and integrate to 3PLs for others in the same instance, but each location has to be unambiguously one model or the other.

Why do D365 and a 3PL disagree about on-hand?

On-hand is a timing problem, not a data problem. Even with the messages mapped perfectly, the two systems disagree briefly and constantly all day because confirmations are in flight — a pick happened but the 945 has not flowed, or a receipt landed but the 944 is queued. The fix is to decide how D365 reflects unconfirmed inventory so sales does not oversell against lagging numbers, and to build a periodic on-hand reconciliation with a defined owner and tolerance.

How should returns be handled between D365 and a 3PL?

Returns flow backward through the integration and are where ghost inventory is born. A unit comes back, gets received, and if the status and message handling are not defined, it either reappears as sellable when it is damaged or vanishes when it is fine. Decide the return disposition and the message that carries it before go-live, not after the first customer complaint.

Caf2Code integrates Dynamics 365 Supply Chain Management with 3PL providers and native warehouse operations across distribution, manufacturing, and transportation clients. If your D365 and your 3PL are not telling the same story, we can help you find out why.

D365 and your 3PL not telling the same story?

We'll map the EDI handshake, draw the execution-ownership line per site, and build the daily reconciliation that keeps inventory honest — so the month-end meeting stops being a fight.