Business Central Expense Management Reaches GA in October. The License-Free Path Isn’t Actually Free.

Finance director reviewing an expense report approval dashboard in a modern office

If your Concur or Expensify renewal is sitting in front of your CFO this quarter, the timing is inconvenient. Microsoft is about to ship native Business Central expense management, a module inside Dynamics 365 Business Central that had been dismissed by practitioners as a minor, checkbox-only feature when it first appeared on the 2026 release wave 1 plan back in April. It no longer looks minor. Between the original release plan entry and the general availability date now set for October 2026, Microsoft quietly attached an AI-driven Expense Agent to the module that covers most of the ground people assumed only a dedicated T&E platform could handle: receipt scanning, mobile capture, email submission, mileage calculation, and policy compliance checks that flag violations before an expense report ever reaches a manager. For an IT Director or finance leader weighing whether to sign another year of a third-party contract, that changes the question from “does Business Central do expenses now” to “is it ready enough to consolidate onto, and what will it actually cost.”

Finance director reviewing an expense report approval dashboard in a modern office

What changed since Business Central expense management was first announced

When Business Central’s expense reports feature first showed up on the release plan, at least one well-known practitioner in the ecosystem publicly predicted it would fall flat. His reasoning was straightforward: without receipt capture, mobile submission, or corporate card integration, a native module was never going to pull organizations away from Concur or Expensify, tools built around exactly those capabilities. That skepticism was reasonable at the time, because the initial description of the feature read like a manual, form-based expense report tool bolted onto the general ledger.

What shipped alongside it in preview is a different story. The Expense Agent, which Microsoft documents as a production-ready preview feature, performs the parts of the workflow that used to require a third-party app: it reads a receipt image or PDF, extracts merchant, amount, date, and category, calculates mileage reimbursement against a configured company rate, and groups related expenses into a report automatically. Submission works through a dedicated web app, a mobile app with camera capture and offline support, direct email to an organization’s expense mailbox, or a Copilot chat interface inside Microsoft Teams. None of that requires opening Business Central at all. What Microsoft’s current documentation does not describe, at least not yet, is automatic reconciliation against corporate card statement feeds, a feature dedicated expense platforms have offered for a decade and that larger organizations in particular tend to depend on. That gap is worth watching, not dismissing; it may simply not have been documented yet ahead of GA.

The workflow, and who actually needs a Business Central license

The module organizes expenses through a status flow that will look familiar to anyone who has used a modern expense tool: Open, Pending Approval, Released, Approved, Rejected, Processed for Payment, and Completed. An employee can enter mileage, add participants to a shared expense, itemize a single receipt into multiple categories, or split a hotel bill into refundable and non-refundable lines when part of it (the minibar, say) falls outside policy. A manager reviews and approves or rejects from within that same flow, and an accountant posts approved reports to generate Expense Ledger Entries and drive reimbursement, with posting accounts controlled through Expense Categories and Expense Posting Groups an administrator sets up in advance.

Employee capturing a paper receipt with a smartphone for expense report submission

The detail that deserves the most attention from a finance leader is licensing, because it does not follow the pattern most Business Central features do. An employee who only submits expenses, whether through the web app, email, or the Copilot chat interface, does not need a Business Central license at all. That sounds like a straightforward cost win until you read the next line: that access method draws on Copilot Credits instead. Anyone who needs to open Business Central itself to manage or approve reports needs at minimum a Team Member license, and posting the reports and processing payment requires Essentials or Premium. So the module has effectively three separate cost levers rather than one: a consumption-based charge for expense-only submitters routed through Copilot Credits, a per-user subscription cost for anyone touching the module inside Business Central proper, and the underlying Essentials or Premium tier required to post anything at all. None of that is disclosed as a flat number in Microsoft’s documentation, which does not publish a specific Copilot Credit consumption rate for expense processing the way it has for some AI Builder scenarios.

Why that licensing structure matters more than the feature list

A CFO comparing this against a Concur or Expensify renewal is not just comparing feature checklists. They are comparing a predictable per-seat SaaS cost against a hybrid model where the cost of casual expense submitters scales with Copilot Credit consumption, a metric most finance teams have no historical baseline for. An organization with 40 people who occasionally submit an expense report and five people in finance who approve and post them will have a very different cost profile than one with 400 field employees submitting receipts weekly through the mobile app, even though both fit inside the same license categories. Before treating this as a straight replacement decision, it is worth actually modeling that consumption, not estimating it, because Copilot Credits behave differently from a fixed per-user fee and can move with usage in ways a traditional T&E contract does not.

There is also a timing consideration that is easy to overlook. As of this writing, the module and its Expense Agent are still labeled a production-ready preview, meaning Microsoft considers it stable enough to run in production but reserves the right to change it, and it operates under supplemental preview terms of use rather than Business Central’s standard product terms. October 2026 is the stated general availability date, but Microsoft’s own release plan documentation carries the standard disclaimer that projected functionality and delivery timelines may change. Organizations with a Concur or Expensify contract expiring in the next renewal cycle should treat October as a target to validate against, not a date to build a migration plan around before it actually happens.

What to do before the next contract renewal

The practical path for a finance or IT leader facing this decision now is a short, deliberate evaluation rather than an early commitment in either direction. Set up the module in a sandbox environment, route a real slice of a month’s expense volume through the Expense Agent’s mobile and email submission paths, and track how many receipts require manual correction after the AI extraction step, since the documentation itself notes that users should expect to review and correct results rather than trust them blindly. In parallel, ask your Business Central partner or internal admin to estimate Copilot Credit consumption against your actual expense submission volume, not a generic average, since that number is the one piece of this decision Microsoft has left for each organization to work out on its own. If your current Concur or Expensify agreement has a shorter renewal term available, or a month-to-month bridge option, that flexibility is worth paying for this cycle specifically so the decision isn’t forced before GA lands and the Copilot Credit math has a real quarter of data behind it.

None of this means the module isn’t a legitimate option. For organizations with straightforward expense policies, modest transaction volume, and no dependency on corporate card feed reconciliation, native Expense Management removes a genuine integration cost and keeps expense data inside the same ledger as everything else. Routeget Technologies has walked several Business Central clients through exactly this kind of licensing and consumption modeling ahead of a platform consolidation decision, and the pattern holds: the module’s capability gap has closed faster than the ecosystem expected, but the cost model needs its own diligence before it replaces a contract that already works.


#BusinessCentral #ExpenseManagement #ERPLicensing #CopilotCredits #FinanceTransformation #SMBERP #DynamicsBusinessCentral

Business Central Withholding Tax Just Went Standard. The Setup Still Isn’t a Checkbox.

Finance director reviewing an international vendor payment and tax compliance dashboard in a modern office

For years, a Business Central partner fielding a withholding tax requirement from a customer expanding into Brazil, Nigeria, the Philippines, or a dozen other markets had exactly two honest answers: buy a third-party ISV solution built for that specific jurisdiction, or write custom code against the purchasing posting routines and hope the next major version upgrade didn’t break it. Neither answer was cheap, and neither scaled if the same customer later opened operations in a second country with a different withholding regime. That gap is what Microsoft’s new Business Central withholding tax engine is built to close. With the public preview that opened April 1, 2026 and general availability targeted for October 2026, Microsoft has built the calculation logic directly into the standard, non-localized version of the product, available for any country or region where a business needs it.

This matters more than it might sound like on first read. Country-specific withholding tax logic has existed in Business Central for a long time, but only inside the local functionality packs for markets like Italy, India, Australia, and New Zealand, each maintained as its own separate implementation with its own tables and its own quirks. A partner supporting a customer with entities in Italy and Colombia couldn’t reuse the Italian withholding tax setup for the Colombian entity, because the two were never built on shared logic. The new engine changes that by putting a single, configurable withholding tax framework into the base application, meaning any tenant, in any country, can turn it on without waiting for Microsoft (or an ISV) to ship a localization for that specific jurisdiction.

How the Business Central Withholding Tax Engine Works

The mechanics are straightforward at the conceptual level. When you post a purchase invoice or purchase order for a vendor flagged as withholding tax liable, Business Central calculates the applicable withholding tax based on your configuration, withholds that amount from what you’d otherwise pay the vendor, and creates a withholding tax entry for tracking and later settlement. A separate action, Calculate and Post Withholding Tax Settlements, lets you process and remit those withheld amounts to the tax authority for a given period. None of that is conceptually new to anyone who has worked with Italian or Indian withholding tax before. What’s new is that it’s no longer bolted onto a country pack; it lives in General Ledger Setup as a feature you enable directly.

Enabling it is only the first step, and this is where the “just flip a switch” narrative some blog posts have used falls apart under any real implementation pressure. After turning on Enable Withholding Tax in General Ledger Setup, you still need to build out four interconnected setup layers before a single invoice will calculate correctly. First, Withholding Tax Revenue Types, which define the categories of taxable transactions (each with its own code, description, and display sequence) and which later drive statutory reporting and certificate generation. Second, Withholding Tax Business Posting Groups, assigned to the vendors subject to withholding, and Withholding Tax Product Posting Groups, assigned to the items or G/L accounts the tax applies against. Third, a Withholding Tax Posting Setup record that links a specific business posting group to a specific product posting group and defines the actual calculation behavior: the calculation rule (less than, equal to, or another comparison against a threshold), a minimum invoice amount below which no tax is withheld, the withholding percentage itself, and a Realized Withholding Type that determines whether the tax is recognized at invoice posting, at payment posting, or at whichever comes first. Fourth, the G/L account setup for the prepaid and payable withholding tax accounts, plus the balancing account types and numbers Business Central needs to post the offsetting entries correctly.

That Realized Withholding Type field deserves particular attention from anyone implementing this for a jurisdiction they haven’t worked with before, because it isn’t a cosmetic timing preference. Statutory withholding regimes frequently specify exactly when the withholding obligation legally arises, and that moment doesn’t always match Business Central’s default assumptions. A configuration that recognizes withholding tax at invoice posting when the local rule requires recognition at payment will produce entries that reconcile cleanly inside Business Central while being wrong for the actual filing. This is not a gap in the software so much as a reminder that a generalized engine can’t encode every country’s statutory timing rules for you; that judgment call sits with whoever configures the posting setup, and it needs to be validated against actual local tax guidance, not against what feels intuitive from a US or UK accounting background.

Abstract illustration of a digital invoice with a portion of its value being withheld into a separate ledger

The Parts the Documentation Leaves for You to Test

Microsoft’s own documentation for this feature is candid about what it covers and noticeably quiet about several scenarios that any multinational deployment will eventually hit. There’s no published guidance yet on how withholding tax interacts with early payment discounts, where the discount changes the payment amount after the withholding calculation might already have run. There’s nothing specific on multi-currency purchase documents, where the withholding percentage presumably applies to a converted amount, but the conversion timing (invoice date rate versus payment date rate) isn’t spelled out. Prepayment scenarios, where part of the vendor payment happens before the final invoice, aren’t addressed either, and neither is whether a single vendor can carry more than one withholding tax code simultaneously for different transaction types.

None of this means the feature is unfinished in a way that should block evaluation. It means that any partner scoping an implementation should treat those four scenarios (discounts, multi-currency, prepayments, multiple codes per vendor) as required test cases before go-live, not edge cases to handle reactively after a customer complaint. Build a small set of test vendors and test posting groups in a sandbox, run each scenario through to a posted settlement, and compare the resulting entries against what the local tax authority actually expects. That’s a half-day of structured testing that will surface problems far more cheaply than discovering them during a live settlement run in month three.

There’s a second practical wrinkle worth planning around: coexistence with the existing localized versions. A customer running Italian local functionality for their Milan entity and the new standard engine for a newly opened Kenyan entity now has two withholding tax implementations active in the same tenant, built on different tables, with different setup pages, and (presumably, though Microsoft hasn’t published a migration path) no automatic bridge between them. For partners supporting genuinely multinational customers, this is worth raising proactively rather than waiting for someone to ask why the Italy withholding tax report doesn’t include Kenyan vendors.

Why the Timing Matters Right Now

Because the feature is still in public preview as of this writing, with general availability set for October 2026, this is the window where testing and feedback actually shape the shipped product rather than reacting to it after the fact. A conflicting timeline circulated by at least one independent Business Central blog puts general availability as early as June 2026, but Microsoft’s own release plan documentation lists October 2026 as the GA date, which is the figure worth planning around until Microsoft says otherwise. Partners with customers who have been paying for third-party withholding tax add-ons or running custom code against the purchasing module have a real opportunity here: a standard, Microsoft-supported alternative is arriving, and the preview period is the right time to validate it against the specific statutory requirements those customers already comply with, rather than assuming general availability means production-ready for every jurisdiction on day one.

At Routeget, this is the kind of feature we tend to see underestimated at the scoping stage, precisely because “Microsoft now supports withholding tax natively” sounds like it closes a requirement rather than opening a configuration project. The posting groups, the realized timing decision, and the untested edge cases are where the actual implementation effort lives, and getting them wrong doesn’t surface until a settlement run doesn’t match what the tax authority expected.


#DynamicsBusinessCentral #WithholdingTax #FinanceAutomation #TaxCompliance #ERPGovernance #GlobalFinance

Why Business Central Webhook Notifications Go Missing, and How to Architect Around It

Solutions architect reviewing a network integration dashboard representing Business Central webhook notifications

A Business Central integration that sailed through testing starts dropping records three weeks into production, and nobody can explain why until someone finally opens the subscription logs and finds a long trail of silent deletions. This is one of the more common failure patterns solution architects run into once Business Central webhook notifications move from a sandbox demo into a live integration carrying order confirmations, inventory adjustments, or approval status changes. The webhook model itself is well documented, but a handful of its operational rules are easy to miss during initial build-out, and missing them is exactly what causes integrations to degrade quietly instead of failing loudly where someone would notice.

The Handshake Most Implementations Get Half Right

Every Business Central webhook subscription begins with a validation handshake, and it is stricter than most developers expect on first pass. When a subscription is created against the v2.0 API, Business Central sends a request to the registered notification URL with a validationToken appended as a query parameter. The receiving endpoint has to echo that exact token back in the response body with an HTTP 200 status, and this is not a one-time formality. The same handshake fires again every time the subscription is renewed, which matters because Business Central webhook subscriptions expire after three days by design. There is no way to extend that window through configuration; the only supported pattern is issuing a PATCH request to the subscription resource before expiration, which triggers a fresh validation round trip.

Teams that build their receiver as a lightweight Azure Function often hit trouble here because of cold starts. If the function has scaled to zero and the handshake response takes more than a few seconds to come back, Business Central treats it as a failed validation and the subscription is never established or renewed. Keeping the receiver warm, or at minimum handling the validation response as the very first branch in the function before any other logic runs, removes most of the flakiness teams report during initial rollout.

Why Business Central Webhook Notifications Stop Coming, With No Error in Sight

The part of the design that catches experienced integration teams off guard is what happens after a notification actually fails to deliver. Business Central will retry a failed notification for up to 36 hours, but only if the subscriber’s endpoint responds with HTTP 408, 429, or something in the 5xx range. Any other response code, including a 400 or a 404 that might result from a temporary bug in the receiver’s routing logic, causes the subscription to be deleted immediately with no further retry and no separate alert. From the Business Central side, everything looks fine because the delivery attempt technically completed. From the integration’s side, notifications simply stop arriving for that entity, and unless someone is actively polling the subscriptions endpoint to check for unexpected deletions, the gap can persist for days before anyone notices missing sales order lines or unsynced customer records downstream.

This is the mechanism behind the scenario at the top of this article. A receiver that returns a 500 during a genuine outage is actually in a safer position than one that returns a 400 because of a malformed payload edge case, since the 500 at least buys 36 hours of retry attempts while the underlying issue gets fixed. Teams that want resilience here should treat any unhandled exception in the receiver as a 5xx rather than letting it bubble up as a generic error page, and should build a scheduled check that compares active subscriptions against the expected list so a silent deletion gets flagged rather than discovered by a downstream data gap weeks later.

Developer workstation showing an abstract data synchronization diagram representing a Business Central API integration

The Records Webhooks Quietly Refuse to Support

Before troubleshooting delivery issues, it is worth confirming the subscribed entity was ever eligible for webhooks in the first place, since Business Central will let a subscription be created against certain API pages that then never fire a single notification. Webhooks are not supported for API pages built on temporary tables, for pages where the OData key consists of more than one field or is otherwise composite, for system tables above table number 2000000000, for anything exposed as an API type query rather than an API type page, or for the Job Queue Entry table specifically. An API page built for a custom extension needs ODataKeyFields set to a single field, typically SystemId, or the subscription will appear to register successfully while silently never delivering anything.

Document-style entities carry their own nuance worth designing around. A change to a sales invoice line does not generate its own notification; instead, Business Central notifies against the parent sales invoice header when any of its lines change. Integrations that subscribe only at the header level and assume line-level granularity will miss the specific detail of what changed and need to follow up with a GET request against the full document to reconstruct it, which is standard practice anyway since webhook payloads never carry the actual record data, only a pointer to it and the type of change that occurred.

Batching, Delay, and the Events That Let You Tune Both

Business Central does not fire a notification the instant a record changes. There is a default 30 second delay built in after the first change to a watched entity, which exists to let a burst of related changes settle before anything is sent. If more than 1,000 records change within that delay window, Business Central collapses the individual notifications into a single collection notification rather than sending a thousand separate payloads, which is a sensible default for bulk imports but can surprise a downstream system expecting one notification per record during something like a large data migration or batch order release.

Both behaviors are adjustable for AL developers who need finer control. The delay interval can be modified through the OnGetDelayTime integration event in the API Webhook Notification Mgt. codeunit, and the threshold that triggers collection-style batching can be adjusted through OnGetMaxNumberOfNotifications in API Webhook Notification Send. Extensions that need near-real-time delivery for smaller entities, such as a status flag that a warehouse floor system needs to react to within a couple of seconds, are reasonable candidates for tightening the delay through these events; extensions dealing with high-volume header tables like sales lines are usually better served leaving the defaults alone and designing the receiver to handle collection notifications gracefully.

Designing for the Gaps: A Hybrid Pattern That Actually Holds Up

Given all of the above, the honest engineering position is that Business Central webhooks were never meant to be the sole source of truth for keeping two systems in sync, and Microsoft’s own documentation is candid that delivery is not guaranteed. Subscriptions can lapse from a missed renewal, a receiver bug can trigger an unannounced deletion, and network conditions on either side can drop a notification outright. The pattern that holds up in production combines the two mechanisms rather than choosing one: webhooks handle the fast path, giving near-real-time propagation for the vast majority of changes, while a scheduled reconciliation job, often running hourly or nightly depending on data volume, polls the same API endpoints using a last-modified timestamp filter to catch anything the webhook layer missed.

This is a small amount of extra engineering for a meaningful reliability gain, and it also solves the operational blind spot described earlier: the reconciliation job can double as the subscription health check, verifying that expected subscriptions still exist and re-registering anything that was unexpectedly deleted. Teams that skip this step tend to discover the gap only when a customer or finance team member notices a record that should have synced and did not, which is a far more expensive way to find the same bug.

What This Means for Your Next Integration Build

None of these behaviors are hidden or undocumented, but they are scattered across API reference pages that most teams read once during initial scoping and rarely revisit once the integration is live. The practical takeaway is to treat the three-day renewal window, the narrow retry code list, the unsupported table types, and the batching thresholds as design inputs from day one rather than issues to debug after the fact. At Routeget Technologies, the integrations that hold up longest in production are the ones where the reconciliation safety net was scoped alongside the webhook subscriptions from the start, not bolted on after the first silent data gap got noticed. Getting that sequencing right the first time is usually the difference between an integration the business trusts and one that quietly needs babysitting.


#BusinessCentralAPI #WebhookReliability #ERPIntegration #DynamicsBusinessCentral #ALDevelopment #EnterpriseIntegration