Folio3, a Salesforce Consulting, MSP, ISV and Agentforce partner, cut billing errors 88% for a Midwest U.S. industrial distributor by integrating Salesforce with Microsoft Dynamics 365. Monthly billing and order entry errors fell from 42 to 5.
The work was a 12-month Sales Cloud and Service Cloud implementation, including a NetSuite data migration and custom AWS middleware connecting Salesforce to Dynamics 365 Finance and Dynamics 365 Supply Chain Management (D365 F&SCM). It was planned for 12 months and delivered on schedule. In the first 30 days after the Service Cloud go-live, support met a 1-hour first-response target on 94.2% of high-priority (P1 and P2) cases. Quotes take a median of 22 minutes.
Key takeaways
Keep pricing and stock in the ERP
Salesforce queries Dynamics 365 live, so quotes never use stale copies.
Audit the ERP before the SOW
More than 5 years of D365 customizations and messy legacy data set this project’s 12-month timeline.
Skip CPQ when pricing lives in the ERP
Standard Salesforce Quotes plus Apex covered quoting without a second pricing engine.
Key results and what drove them
The biggest gain came from removing manual order entry: an accepted quote now creates the D365 sales order on its own.
| Metric | Before → After | What drove the change |
|---|---|---|
| Billing and order entry errors | 42 → 5 a month (88% fewer) | Accepted quotes create the D365 sales order automatically, so no one retypes order lines |
| First-response SLA, P1 and P2 cases (1-hour target) | Not tracked → 94.2% met | Omni-Channel routing plus Entitlement Management and Milestones in Service Cloud |
| Quote turnaround | Not tracked as a quote cycle → 22-minute median | Live D365 stock and pricing inside the Salesforce quote |
Billing errors: 6-month average before the Sales Cloud go-live vs. the 30-day hypercare window after full cutover (month 12). SLA: P1 and P2 cases, first 30 days after Service Cloud go-live. Quote turnaround: from the rep’s quote request to the customer PDF, in Sales Cloud.
Project at a glance
| Item | Detail |
|---|---|
| Client | Midwest U.S. industrial fluid power and mechanical components distributor ($100M+ revenue) |
| Scale | About 180 Salesforce seats, 4 sales territories, 4 warehouses |
| Salesforce products | Sales Cloud and Service Cloud |
| ERP | Microsoft Dynamics 365 Finance and Supply Chain Management |
| Integration layer | Custom Node.js microservices on AWS Lambda and Amazon API Gateway, with Amazon SQS, Amazon DynamoDB and AWS Secrets Manager |
| Legacy system retired | NetSuite |
| Scope and timeline | 12 months for Sales Cloud, Service Cloud, the D365 integration and the NetSuite migration, delivered on plan |
| Services budget | $150,000–$220,000, excluding software licenses |
| Implementation partner | Folio3 |
An 8-person Folio3 team delivered it: a project delivery lead, a functional consultant, an integration architect, two Salesforce developers, a data migration specialist, a QA lead and a project manager.
Why can’t Salesforce users see Dynamics 365 inventory?
Salesforce users can’t see Dynamics 365 inventory until the two systems are integrated. At this distributor, stock lived only in D365, so reps phoned the warehouse back office to check fluid power components across 4 warehouses, built quotes in spreadsheets, and emailed them to order entry clerks.
The clerks then keyed every line into D365 by hand. SKU typos and wrong tier-pricing choices produced an average of 42 billing errors a month. Support inquiries sat in shared Outlook inboxes with no SLA tracking or escalation.
Folio3 connects Salesforce to Dynamics 365, NetSuite and other ERPs so reps see live stock and pricing inside every quote.
How does Salesforce talk to Dynamics 365 without a licensed middleware platform?
Folio3 connected Salesforce to Dynamics 365 through custom Node.js microservices running on AWS Lambda behind Amazon API Gateway, with no middleware license. Folio3’s Salesforce–Dynamics 365 integration guide recommends a custom build when existing systems are heavily customized. This client’s D365 had more than 5 years of customizations from previous vendors, and a custom layer also avoided recurring middleware subscription fees.
- Quote accepted → sales order in D365
- Rep builds quote → live stock and pricing
- Agent opens case → order and shipment status
- Account or contact changes → real-time sync both ways
- Change Data Capture and D365 data events · no polling
- OAuth 2.0 on both sides · TLS 1.3
- Failed orders retried 5 times, then a dead-letter queue
- Field mappings change without a redeploy
- 1.2 million raw records audited
- About 600,000 clean customer records migrated
- Retired after migration
Figure 1. Architecture: Salesforce connects to Dynamics 365 through custom AWS middleware; NetSuite fed a one-time migration and was retired.
| Data flow | Direction | Trigger | Result |
|---|---|---|---|
| Order creation | Sales Cloud → D365 | Quote status changes to Accepted | D365 creates the sales order and returns the ERP order ID |
| Stock and pricing lookup | Sales Cloud → D365 | Rep builds a quote | Live SKU stock across 4 warehouses, plus tier pricing |
| Order status lookup | Service Cloud → D365 | Agent opens a case | Order status, shipment tracking and invoice details in the Service Console |
| Accounts and contacts | Sales Cloud ↔ D365 | Record created or changed | Real-time, event-driven sync through the AWS microservice layer |
The account and contact sync works without polling. Salesforce Change Data Capture events and D365 data events post to Amazon API Gateway, which triggers a Lambda function that updates the other system right away.
How quote-to-order works after the integration
Figure 2. Quote-to-order before and after the integration: four manual steps replaced by one Salesforce flow.
The manual handoffs are gone. Reps see live stock and pricing inside the quote, and an accepted quote creates the Dynamics 365 sales order on its own, so no one retypes order lines.
What drives the timeline of a Salesforce–Dynamics 365 integration?
The timeline of a Salesforce–Dynamics 365 integration depends on three things: how customized the ERP is, how clean the legacy data is, and the client’s business calendar. Folio3 typically scopes 6 to 8 months for a full-scale single-ERP integration when the ERP’s APIs are standard and the data is clean. On this project, all three shaped the 12-month plan, and they’re the ones most worth checking before you plan your own.
Inside D365, more than 5 years of customizations meant 8 custom OData endpoints had to be refactored for batching, inventory pagination and high-volume payloads before sync could run reliably.
On the data side, NetSuite held 1.2 million raw records, including transaction history and duplicate account ledgers. Auditing and deduplicating them took about 8 weeks. About 600,000 clean customer records then moved to Salesforce through Folio3’s Salesforce migration services, and NetSuite was retired.
Then there was the calendar: the client’s peak sales season fell during the territory rollout, and the regional sales teams couldn’t all join user acceptance testing at once. So the 4 territories went live one at a time across months 8 to 11, within the 12-month plan.
Lesson learned: the API health check on ERP customizations belongs before the SOW is signed, so the timeline reflects them from the start.
How the 12 months ran
- M1–2Discovery and data mappingAudited D365 custom endpoints and mapped NetSuite customer tables to Salesforce objects.
- M3–6Sales Cloud and middleware buildStandard Quotes, Apex triggers, and the Node.js microservices on AWS.
- M4–5Data cleanup (in parallel)NetSuite extraction, duplicate audit, and cleanup of about 600,000 customer records.
- M6–10Service Cloud buildService Console, Omni-Channel routing, and live D365 order status.
- M7Pilot UATSales Cloud staging and user acceptance testing.
- M8–11Go-live 1Sales Cloud, one territory at a time.
- M11Go-live 2Service Cloud routing and order status lookups.
- M12Hypercare and handover30 days of monitoring and tuning, then handover to the client’s IT team.
The phases overlapped on purpose: the NetSuite cleanup ran alongside the middleware build, and Service Cloud work started while Sales Cloud was still in testing.
What did go-live and hypercare look like?
Fayez Shamim, who led functional delivery through the Service Cloud go-live and hypercare, describes it:
In the first week after the Sales Cloud go-live, the team’s main job was tuning Amazon API Gateway throttling limits and AWS Lambda concurrency. Peak-hour stock lookups across all 4 warehouses were arriving in bursts, and the limits were adjusted until no requests dropped. By the time I was leading hypercare, the work had shifted to Service Cloud: customers replying to old email threads were creating duplicate cases, so we reworked the routing rules to stop them. When the 30-day hypercare period closed, production logs showed zero unhandled API exceptions across the Node.js middleware.
Fayez Shamim, Business Analyst & Functional Consultant, Folio3
Prebuilt connector, middleware or custom build: which fits?
The right way to connect Salesforce to an ERP depends mostly on how customized the ERP is. Folio3 runs separate Salesforce, NetSuite and Microsoft Dynamics practices, so it works with all three routes:
| Your situation | Route | What Folio3 typically uses |
|---|---|---|
| Salesforce + NetSuite, standard lead-to-cash flows | Prebuilt connector | Folio3’s Built for NetSuite certified Salesforce connector, recognized by Oracle as NetSuite Next Ready |
| Salesforce + Dynamics 365 Business Central, standard flows | Prebuilt connector | Folio3’s BURQ iPaaS connector on Microsoft AppSource |
| Several systems, high data volume, heavy transformation | iPaaS | MuleSoft, Boomi or Jitterbit |
| One ERP with years of customizations | Custom build | A custom API layer, like the AWS microservices in this project |
Prebuilt connectors are fastest when the ERP is close to standard. Custom builds pay off when the ERP is heavily customized, as this distributor’s was. For a deeper comparison, read Folio3’s guide to ERP integration with Salesforce.
Folio3’s integration architects will review your ERP’s APIs and customizations and recommend connector, iPaaS or custom build.
Frequently asked questions
How long does a Salesforce–Dynamics 365 integration take?
Folio3 typically scopes 6 to 8 months for a full-scale single-ERP Salesforce–Dynamics 365 integration when the ERP’s APIs are standard and the data is clean. This project, a full Sales Cloud and Service Cloud implementation with the integration and a NetSuite migration, was planned for 12 months and delivered on schedule. Refactoring 8 legacy D365 endpoints, cleaning 1.2 million NetSuite records and working around the client’s peak season shaped that plan.
How much does a Salesforce–Dynamics 365 integration cost?
On this Folio3 project, professional services fell in the $150,000–$220,000 range. That covered architecture, the custom AWS microservices, NetSuite data migration and hypercare, and excluded Salesforce, Microsoft and AWS license costs. The biggest cost drivers were refactoring the legacy D365 OData endpoints and cleaning 1.2 million NetSuite records, because both took the most engineering hours.
Can Salesforce show real-time Dynamics 365 inventory?
Yes. Folio3’s AWS microservices query D365 the moment a rep builds a quote and return live stock across all 4 warehouses. Folio3 didn’t store inventory snapshots in Salesforce, because a copy of fast-moving stock goes stale quickly.
How do you quote from Salesforce without licensing CPQ?
Folio3 used standard Salesforce Quotes plus Apex instead of CPQ. SKU catalogs, price books and tier-pricing rules stay in D365, and the microservices fetch live stock and pricing while the rep builds the quote. There’s no second pricing engine to maintain. CPQ makes sense when pricing and bundling logic should live in Salesforce rather than the ERP.
Who maintains custom middleware after handover?
The client’s IT team maintains the custom middleware after Folio3’s handover. During hypercare, Folio3 handed over technical documentation, OpenAPI specifications, AWS deployment runbooks and monitoring dashboards.
How is the AWS integration between Salesforce and Dynamics 365 secured?
Folio3 secured the integration with OAuth 2.0 on both sides and no hardcoded credentials. The Lambda microservices authenticate to D365 F&SCM through the OAuth 2.0 client credentials flow in Microsoft Entra ID, and to Salesforce through a Connected App using the OAuth 2.0 JWT bearer flow. Secrets and tokens are stored in AWS Secrets Manager, and all traffic is encrypted in transit with TLS 1.3.
How do Dynamics 365 field changes reach the integration without a redeploy?
Folio3 stores the field mappings in Amazon DynamoDB, so a Dynamics 365 field change needs a configuration update, not a redeploy. Custom D365 fields are exposed through data entities and OData endpoints, and the Node.js microservices read their mappings from DynamoDB. When a field name or data type changes in D365, an administrator updates the mapping through an admin API.
What happens when the same account is edited in both systems at once?
Folio3 gave most fields a single owner system. D365 F&SCM owns financial and credit fields such as payment terms, tax status and credit limits. Salesforce owns sales fields such as lead status and communication preferences. For the few shared fields, such as primary address and phone number, the Lambda event router compares last-modified timestamps, checks which system has authority over the field, and applies the most recent valid change.
What happens if Dynamics 365 is down or rate-limiting when an order is created?
In Folio3’s design, the order waits in a queue instead of failing. Orders from Salesforce pass through Amazon SQS. If D365 returns a 429 (rate limited) or 503 (unavailable) response, the Lambda function throws an error and SQS returns the message to the queue for another attempt. After 5 failed attempts, SQS moves the message to a dead-letter queue and the system administrator gets an alert.
Why use serverless AWS Lambda instead of servers or a licensed iPaaS?
Folio3 chose AWS Lambda because quote and inventory traffic is uneven. Lookups spike during business hours and peak season, and Lambda scales with them without paying for idle servers. It also leaves the client’s IT team with no servers to patch after handover, and no recurring middleware subscription.
Sources
- Salesforce: Change Data Capture Developer Guide
- Microsoft Learn: Data events in finance and operations apps
- AWS: Amazon SQS dead-letter queues
- Folio3: How to Integrate Salesforce with Microsoft Dynamics 365
About the author
Fayez specializes in Salesforce CRM implementations. On this engagement, he led functional delivery through the Service Cloud go-live and hypercare, acting as the bridge between the distributor’s sales, service and IT teams and Folio3’s technical team. He holds four Salesforce certifications (Administrator, Business Analyst, Data 360 Consultant and Marketing Cloud Engagement Administrator) and an MBA in Marketing from the Institute of Business Management (IoBM).
About Folio3
Folio3 is a Salesforce Consulting, MSP, ISV and Agentforce partner, with separate Salesforce, NetSuite and Microsoft Dynamics practices. Read Folio3’s Salesforce success stories or explore its Salesforce consulting services.
Folio3’s Salesforce team will map your quote-to-order flow and review your ERP’s APIs during discovery.









