A six-endpoint Azure Function gateway between Dynamics 365 CE and an external asset-leasing platform
Sales needed finance proposals raised against an external asset-leasing platform without leaving Dynamics 365. The two systems had no common ground: different identity, different data model, different lifecycle, and a lender that reports status changes by calling back rather than being polled.
I built an Azure Function gateway with six endpoints that sits between them. It brokers OAuth in both directions, reads every secret from Key Vault via managed identity, receives status webhooks from the lender, and produces the proposal documents that come back to the record. Dynamics calls one internal surface; the gateway owns every detail of the external one.
The tempting shortcut is to let Power Automate call the external API directly. It works in a demo and it is a liability in production: the credentials end up in connection configuration, the token lifecycle ends up hand-rolled inside flow expressions, and every change the third party makes to their contract becomes an edit across however many flows happen to touch it.
There was also an inbound problem that flows are the wrong tool for. The leasing platform reports progress by calling you, webhooks arriving at unpredictable times, needing verification, needing to be matched to the right proposal record, and needing to be idempotent because a delivery can arrive more than once.
Both problems point the same way: one component that owns the integration, with a contract Dynamics can depend on and the third party cannot see through.
The gateway is a single Azure Function app exposing six HTTP endpoints, split across three concerns. Dynamics 365 talks only to the gateway. The gateway talks to the leasing platform, and absorbs every difference between the two.
Power Automate invokes the gateway from Dynamics 365. The gateway calls the leasing platform over OAuth and REST, receives status webhooks back on its own endpoints, and reads every credential from Key Vault using the function app's managed identity, there is no secret in application configuration for anyone to find.
The asymmetry is deliberate. Outbound is request/response and synchronous; inbound is a webhook that can arrive at any time, twice. Treating those as two different problems, rather than forcing both through one pattern, is what keeps the retry and idempotency logic comprehensible.
Sales raise and track finance proposals without leaving the CRM record, and the finished document arrives back on it. The integration detail (tokens, retries, webhook verification, the third party's data model) stays inside one deployable that can be tested and versioned on its own.
The pattern generalises well beyond leasing. Any time a Power Platform solution needs to talk to a third party that has its own identity model and its own opinions about how it reports state, a thin gateway is worth the extra component: it is the difference between one place to change and every flow you own.
Building agents on the Power Platform, or trying to get one past a pilot? I am happy to talk it through.
Get in Touch →