Dynamics 365 Business Central¶
Applies to: e-Invoice · e-Way Bill · Which modules do I have?
Purpose¶
Connect Business Central to Complifly using an extension that authenticates with a Microsoft Entra ID token, sends posted documents to the mapped ingest endpoint, and consumes compliance outcomes.
Audience¶
Business Central developers and implementation partners.
Prerequisites¶
- The Integration Pattern — read first
- Machine-to-Machine Authentication
- An Entra ID tenant with rights to register an application
- Business Central developer effort allocated
- Sandbox credentials
Steps¶
1. Register the application in Entra ID¶
Business Central is the integration where identity-provider authentication is the natural choice, because the identity platform is already present.
| Step | Detail |
|---|---|
| Register an application | One per ERP. Do not share a registration across integrations |
| Create a client secret or certificate | Store it in the tenant's secret store |
| Expose the required application role | The role Complifly expects on the token |
| Grant admin consent | This is the step most often missed. Without it, tokens authenticate and are then refused as forbidden |
| Record the identifiers | Tenant and application identifiers, for the Complifly-side mapping |
Complifly must map the application to the customer's company before tokens are accepted. Do this before the first test call, or the first test looks like an authentication defect.
2. Build the outbound call¶
| Decision | Guidance |
|---|---|
| Trigger | On posting the sales invoice or credit memo |
| Execution | Through a job queue entry rather than inline — never block posting on an external call |
| Endpoint | The mapped ingest endpoint, with the template identifier |
| Credential | The Entra ID token, cached until shortly before expiry |
| Payload | Business Central's own field names, translated by the mapping template |
Posting must not depend on an external service being available. Queue the call and let it retry.
3. Source the required fields¶
| Complifly needs | Typically from |
|---|---|
| Document number and date | Posted sales invoice header |
| Document type | Invoice or credit memo, translated by a lookup |
| Supplier registration | Company information, or the responsibility centre in multi-registration setups |
| Buyer registration and address | Customer card and its address fields |
| Place of supply | Determined in Business Central; a tax position |
| Values | Posted document totals |
| Line details | Posted document lines |
| Classification codes | Item card |
Once you know where each value lives, build the translation in the product rather than in ERP code: Build a Mapping Template walks through creating the template, loading these fields from a sample, and dragging them onto their NIC counterparts with the right direct, date or lookup rule.
4. Handle the Business Central traps¶
| Trap | Symptom | Fix |
|---|---|---|
| Admin consent not granted | Token accepted, call refused as forbidden | Grant consent. This is the most common failure |
| Multiple registrations | Wrong supplier registration | Establish which object carries the registration — company information or responsibility centre — before mapping |
| Posted versus unposted | Sending a document that can still change | Trigger on the posted document only |
| Number series per company | Duplicate rejections | Confirm uniqueness per registration per financial year |
| Rounding lines | Total mismatch | Include rounding in the mapped total |
| Token requested per call | Rate limited while authenticating | Cache the token |
| Sandbox pointing at production | A test document registered for real | Separate environments structurally, not by care |
5. Consume the write-back feed¶
Add a scheduled job queue entry that pulls events, stores outcomes against the posted document, and acknowledges.
| Store | Where |
|---|---|
| Reference number and acknowledgement | Fields on the posted sales invoice |
| Signed QR data | Where the report layout needs it |
| e-Way Bill number and validity | Against the shipment or the invoice |
| Failure reason | A field a person will look at |
Acknowledge only after the outcome is committed. Acknowledging first loses the event if the job then fails.
6. Handle rejections visibly¶
Use a queue or a list page a person reviews daily, with a notification. A rejection stored in a field nobody opens is a document that never becomes compliant.
Validation¶
| Check | Method | Pass condition |
|---|---|---|
| Token acquisition works | Call a low-risk endpoint | Accepted |
| Admin consent granted | Call an ingest endpoint | Not refused as forbidden |
| Token cached | Inspect call behaviour | One token serves many calls |
| Correct registration | Post from each registration | Correct supplier registration each time |
| Posting is not blocked | Stop the network and post | Posting succeeds; the call queues |
| Retry works | Restore the network | The queued call succeeds |
| Totals match | Compare the mapped payload against the posted document | Exact, including rounding |
| Credit memos map correctly | Post one | Routes as a credit note |
| Outcome reaches Business Central | Complete one document end to end | Reference number on the posted invoice |
| Report layout works | Print, if printing in Business Central | Signed QR scans from paper |
| Idempotent consumer | Deliver an event twice | Processed once |
| Rejections visible | Force a rejection | A person sees it the same day |
Troubleshooting¶
| Symptom | Cause | Action |
|---|---|---|
| Token accepted, call refused as forbidden | Admin consent not granted, or the client not mapped to a company | Grant consent; confirm the mapping |
| Unauthorised with a fresh token | Wrong audience or issuer, or clock drift | Compare the token's claims against the configuration |
| Rate limited while authenticating | Token requested per call | Cache it |
| Posting hangs | The call runs inline | Move it to the job queue |
| Wrong supplier registration | Mapped from the wrong object | Confirm which object carries it |
| Duplicate rejections | Number series overlap, or the document sent twice | Check the series and the trigger's idempotency |
| Total mismatch | Rounding line excluded | Include it |
| Reference number never arrives | Write-back not consumed, or the job queue entry is not running | Check the flag, subscription, then the job |
| Events lost after a failure | Acknowledged before committing | Acknowledge after |
| A test document registered for real | Sandbox configured with production credentials | Treat as an incident. The number is permanently consumed |
Related Articles¶
- Build a Mapping Template — the field mapping, screen by screen
- The Integration Pattern — everything common
- Machine-to-Machine Authentication — the token flow
- Mapping Templates API
- Write-back API