轻易云
注册体验

Microsoft Dynamics 365 对账集成

· AI 财务对账· 57 次浏览· 约 18 分钟读完
Microsoft Dynamics 365Finance供应链Web APIOAuth 2.0Azure ADOData V4DataverseDual-write集成中心集成转换ERP

Microsoft Dynamics 365 对账集成

摘要:Microsoft Dynamics 365 在 2016 年由 Dynamics AX / NAV / CRM 三大产品线合并而来,到 2026 年已分化为 Finance(财务与运营)+ Supply Chain Management(供应链)+ Sales / Customer Service / Project Operations 等云原生 SaaS 模块——其中 Finance 与 SCM 是对账场景的主战场,全球前 2000 强里有相当一部分企业的核心生产系统正跑在 Dynamics 365 Finance / SCM 上。两套模块在对账接入上是「同构双轨」:都走 Web API(基于 OData v4)+ OAuth 2.0 + Microsoft Entra ID(Azure AD)+ Service Principal——这与金蝶云星空的 HMAC 自定义协议、用友 YonBIP 的 OAuth、用友 NC 的多层 CA 证书、SAP S/4HANA 的 OData V4 + BTP、Oracle Fusion 的 OAuth 2.0 + IDCS 都完全不同。本文给 CTO / ERP 实施一份完整的 Dynamics 365 Finance / Supply Chain 对账接入路径——Web API(OData v8.2)+ OAuth 2.0 client_credentials + Microsoft Entra ID 注册、Business Events 与 Data Events 的双引擎事件流、集成中心的 dynamics-365 handler 命名空间清单、集成转换脚本骨架,以及 Finance / Supply Chain 双模块联合对账的 4 步对接 + 5 步验收清单。

关键词:Microsoft Dynamics 365、Dynamics 365 Finance、Supply Chain Management、Web API、OData v4、OAuth 2.0、Microsoft Entra ID、Service Principal、Azure AD Application、Business Events、Dual-write、Dataverse、LCS、集成中心、集成转换

跨年 23:55 的那一通紧急电话:Dynamics 365 客户的「国际 ERP」难题

「我们集团总部在新加坡,财务统一用 Microsoft Dynamics 365 Finance,欧洲子公司用 Supply Chain Management 跑物流,国内财务团队想做跨境对账——三套账能不能统一拉到一张对账表里?我们的对接方说 Dynamics 365 走的是 'Dataverse',跟以前 AX 的 .NET Business Connector 完全是两个东西,原来的代码还能复用吗?」

2025 年以来,做跨境电商与跨国集团的 CTO 们在对账接入时遇到的问题,与纯国内 ERP 客户(金蝶 / 用友)的难题截然不同。国内 ERP 客户关心「HMAC 双签名 + 自定义 API 怎么调」「YonBIP 的 OAuth 怎么集成」「NC Cloud 的多层 CA 证书怎么处理」,国际 ERP 客户关心的是「Dynamics 365 这套 Web API(OData v4)+ Microsoft Entra ID(Azure AD)+ Service Principal 跟我们国内的协议习惯完全不同,跨数据中心怎么部署、跨实体(Legal Entity)怎么拉、跨币种怎么折算」。答案先放在前面:Finance 与 SCM 的接入是「同构双轨」——同一套 Web API + OAuth 2.0 协议,但数据实体(Data Entities)按模块划分;与 Dynamics AX 时代的 .NET Business Connector 不通用。

Dynamics 365 不是「Dynamics AX 的升级版」,是一套全新的云原生 SaaS 产品线——底层从 Windows Server + SQL Server 迁移到 Azure 云 + Azure SQL;API 从 .NET Business Connector / AIF(Application Integration Framework)迁移到 Web API(基于 OData v4 / v8.2)+ Business Events(事件驱动);集成层从 AIF Document Services / AxBc 迁移到 Dual-write(双写框架)+ Dataverse + Power Platform;部署模式从 On-Premise 单机房迁移到 Lifecycle Services(LCS)多云环境 + Continuous Update(持续更新,季度一波)。

任何一家今天还在用 Dynamics AX 2012 / Dynamics NAV 跑对账的跨国集团,切换到 Dynamics 365 Finance / SCM 时,所有 .NET Business Connector 调用、AxBc 包装层、AIF Document Service XML 配置都要按新的 Web API + Dataverse 范式重写一遍。下面把这件事讲透。

一、Dynamics 365 是什么:与 SAP、Oracle、金蝶的关系

「我们集团用的是 Microsoft Dynamics 365 Finance 还是 Supply Chain Management?两者能通用一套对接吗?」这是 Dynamics 365 客户在集成中心做对账接入时被问到最多的问题。答案和上一节一样:Finance 与 SCM 是「同构双模块」——共享同一套 Web API + OAuth 2.0 + Dataverse 平台,但数据实体划分不同:

维度Dynamics 365 FinanceDynamics 365 Supply Chain ManagementSAP S/4HANA(对照)Oracle Fusion(对照)金蝶云星空(对照)
定位跨国集团财务核心(GL/AP/AR/FA/Budget)跨国集团供应链核心(WMS/Production/Procurement)跨国集团全栈 ERP(财务 + 供应链 + HR)跨国集团全栈 ERP(财务 + 供应链 + HCM)国内集团 ERP(财务 + 供应链)
部署模式Azure 公有云 SaaS / 私有云Azure 公有云 SaaS / 私有云On-Premise / 公有云 SaaS公有云 SaaS公有云 SaaS / On-Premise
数据库Azure SQL(云端托管,自动备份)Azure SQL / BYOD(Bring Your Own Database)SAP HANA(强制)Oracle Autonomous DatabaseOracle / PostgreSQL / SQL Server
API 主线Web API(OData v4 / v8.2)+ Business Events同 Finance + Warehouse Mobile App APIOData V4 + RAP + BAPI 兼容层REST API + SOAP + BI Publisher + OIC自定义 HTTP + HMAC 双签名 + Form 提交
集成中间件Dual-write + Dataverse + Power Platform + LCS同 FinanceSAP BTP Integration SuiteOracle Integration Cloud(OIC)集成中心(自研 iPaaS 模式)
认证协议OAuth 2.0 client_credentials + Microsoft Entra ID(Azure AD)+ Service Principal同 FinanceOAuth 2.0 + X.509(SAP IAS / IPS)OAuth 2.0 + IDCS / OCI IAM + JWTHMAC SHA256 + appId + appSecret + DB Link
维护时间线Continuous Update(持续更新,每年两波 4 月 + 10 月)同 Finance季度发布(Q1-Q4)季度发布(Q1-Q4)年度大版本 + 月度补丁
安装基础全球 5,000+ 跨国集团(2024 年 Microsoft 财报口径)同 Finance,约 4,000+ 客户全球 25,000+ 大型企业5,000+ 新签 Fusion 客户国内 200,000+ 中大型客户
财务核心General Journal + Vendor Invoice + Customer Payment同 Finance + Inventory / Production OrderUniversal Journal(ACDOCA)Journal + ESS财务凭证 + 应收/应付单

三个最关键的对账集成差异:

差异一:Web API(OData v4)vs SAP OData V4 vs 金蝶 HMAC 自定义。Dynamics 365 Finance 与 SCM 的 API 主线是 Web API——遵循 OData v4 标准,端点 URL 形如 https://<environment>.operations.dynamics.com/data/GeneralJournalEntries,请求/响应是 JSON 格式,调用方式与 SAP S/4HANA OData V4 高度类似,但与金蝶云星空的 HMAC 自定义 POST 表单完全不同。对账系统如果只做过金蝶集成,第一次接触 Dynamics 365 Web API 会有一个显著的感觉:API 风格非常「RESTful + 标准 OData」——CRUD 路径清晰、$filter/$select/$expand 原生支持。

差异二:Microsoft Entra ID(Azure AD)vs IDCS / SAP IAS。Dynamics 365 的认证必须走 Microsoft Entra ID(原 Azure Active Directory,2023 年改名)——对账系统要在 Entra ID 里注册一个 App Registration(应用注册),拿到 Application (client) ID + Client Secret,再调 OAuth 2.0 client_credentials 流程拿 Bearer Token。这与 SAP IAS(Identity Authentication Service)、Oracle IDCS 概念类似但实现细节不同——Microsoft Entra ID 是全球企业 IT 团队最熟悉的身份服务之一,因为它与 Office 365 / Microsoft 365 / Azure 全家桶共享同一个租户(Tenant)。

差异三:Dual-write + Dataverse vs SAP BTP vs Oracle OIC。Dynamics 365 的集成中间件是 Dual-write(双写框架)+ Dataverse + Power Platform + LCS(Lifecycle Services)——Dual-write 是 Microsoft 官方维护的「Finance/Operations ↔ Dataverse 双向同步」框架,对账场景下可借此把数据同步到 Common Data Service,再走 Power Automate / Power Apps 编排。对账系统可以直接消费 Finance/Operations 端的 Web API,也可以消费 Dataverse 端的 Web API——两套 API 数据语义略有差异。

二、Dynamics 365 Finance 接口体系:Web API × OData v4 × Business Events

Dynamics 365 Finance / SCM 的集成接口体系从 2016 年云化起定型,核心是 Web API(OData v4 / v8.2) + Business Events(业务事件流) + Data Events(数据事件,2020 年起新增)。三套接口各管一摊:

接口类型全称协议层调用方式适用场景对账场景优劣
Web API(OData v4 / v8.2)Dynamics 365 Web APIHTTPS + JSON + OAuth 2.0RESTful(GET/POST/PATCH)业务对象 CRUD(凭证/发票/收款)⭐⭐⭐⭐⭐ 对账核心,/data/GeneralJournalEntries
Business EventsDynamics 365 Business EventsAzure Event Grid / Service Bus / Webhook事件驱动(异步推送)业务事件触发(凭证已过账、发票已审核)⭐⭐⭐⭐ 实时集成首选
Data EventsDynamics 365 Data Events同 Web API + 事件订阅数据变更触发(CRUD 钩子)数据变更审计 / 同步⭐⭐⭐ 审计场景
Recurring IntegrationRecurring Integration(DMF)Azure Blob + ZIP 包批量文件导入导出大量数据导入(主数据 / 期初余额)⭐⭐⭐⭐ 主数据 / 期初批量首选
BYOD(Bring Your Own Database)BYODSQL 连接数据库直读大数据量查询 / 报表⭐⭐⭐ 自定义报表首选

Web API 是对账场景的核心接口。下面给出 Dynamics 365 Finance 总账凭证(GeneralJournalEntries)的一段 REST 调用伪代码:

bash
# === Dynamics 365 Finance 总账凭证推送(Web API + OData v4)===
# 入口:POST https://<environment>.operations.dynamics.com/data/GeneralJournalEntries
# 出口:返回 201 Created + OData-EntityId(凭证头 ID)

# 1. OAuth 2.0 拿 access token(Microsoft Entra ID / Azure AD)
curl -X POST "https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=<APP_CLIENT_ID>" \
  -d "client_secret=<APP_CLIENT_SECRET>" \
  -d "scope=https://<environment>.operations.dynamics.com/.default"
# → {"access_token": "eyJ0eXAi...", "expires_in": 3600}

ACCESS_TOKEN="eyJ0eXAi..."

# 2. 推送总账凭证头(General Journal Header)
curl -X POST "https://<environment>.operations.dynamics.com/data/GeneralJournalEntries" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "OData-MaxVersion: 4.0" \
  -H "OData-Version: 4.0" \
  -H "Accept: application/json" \
  -d '{
    "JournalBatchNumber": "RECON-202609-0042",
    "LedgerName": "USD",
    "JournalName": "Daily",
    "PostingLayer": "Current",
    "Description": "对账推送-202609",
    "dataAreaId": "USMF",
    "IsPosted": false
  }'
# → 201 Created + OData-EntityId: https://<env>.operations.dynamics.com/data/GeneralJournalEntries(<JOURNAL_ID>)

# 3. 推送总账凭证行(General Journal Lines)
curl -X POST "https://<environment>.operations.dynamics.com/data/GeneralJournalEntryLines" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "Journal": <JOURNAL_ID>,
    "LineNumber": 1,
    "AccountType": "Ledger",
    "MainAccountId": "101000",
    "TransactionCurrencyCode": "USD",
    "TransactionCurrencyDebitAmount": 12345.67,
    "Description": "对账推送-借方",
    "dataAreaId": "USMF"
  }'

# 4. 触发过账(POST Journal)
curl -X POST "https://<environment>.operations.dynamics.com/data/GeneralJournalEntries(<JOURNAL_ID>)/Microsoft.Dynamics.DataEntities.PostJournal" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
# → 200 OK + JournalStatus: Posted

Dynamics 365 凭证推送有 3 个关键设计选择:

选择一:MainAccountId(主科目)+ LedgerName(账套)+ dataAreaId(法人)三段定位总账科目。Dynamics 365 没有 SAP 那样的「GL Account 字符串 + Company Code」组合,而是 MainAccountId(主科目 ID,全局唯一)+ LedgerName(账套名称,跨币种定义)+ dataAreaId(法人/法律实体 ID)。对账系统要维护一份「MainAccountId → 内部核算项目」映射表——这与 SAP 的 GL_ACCOUNT 字符串、Oracle EBS 的 CODE_COMBINATION_ID、金蝶云星空的 FAccountID 字段语义都不同。

选择二:OData v4 + OData-MaxVersion 头是「协议契约」。Dynamics 365 Web API 强制要求客户端发送 OData-MaxVersion: 4.0 与 OData-Version: 4.0 头,否则服务端按 OData v3 兼容处理。对账系统的 HTTP 客户端如果漏发这两个头,会收到 404 或字段缺失。

选择三:批量过账(PostJournal)+ 异步确认模式。Dynamics 365 的过账动作走 OData Action(Microsoft.Dynamics.DataEntities.PostJournal)——Action 调用默认同步阻塞,但 Finance 大批量凭证(>500 行)的过账可能要走 Batch Framework 异步。对账系统需要做「推凭证 → 调 Action 过账 → 轮询 JournalStatus」的异步任务模型。

Business Events 是 Dynamics 365 Finance / SCM 上事件驱动集成的「另一条路」。与 Web API 同步调用不同,Business Events 是「事件订阅 + 异步推送」——Finance 内置 30+ 业务事件(如 GeneralJournalPostedEvent、VendorInvoiceApprovedEvent),订阅后通过 Azure Event Grid / Service Bus / HTTPS Webhook 推送到下游系统。对账场景下 Business Events 常用于「凭证已过账 → 实时回写到对账系统」——把对账 PUSH 倒过来做对账「状态回流」。

三、Dynamics 365 Supply Chain Management 接口体系:Web API × Warehouse Mobile App API × BYOD

Dynamics 365 Supply Chain Management 与 Finance 共享同一套 Web API 平台,但供应链侧的实体集合(Entity Collection)与财务侧完全不同。SCM 的核心实体包括:

SCM 核心实体路径用途对账场景
InventoryOnHandEntities/data/InventoryOnHandEntities实时库存查询库存对账(账面库存 vs 实物库存)
PurchaseOrderHeadersV2/data/PurchaseOrderHeadersV2采购订单头采购对账
SalesOrderHeadersV2/data/SalesOrderHeadersV2销售订单头销售对账
ProcurementCatalogProducts/data/ProcurementCatalogProducts采购目录主数据同步
WarehouseMobileDevicesWarehouse App API仓储移动设备仓库作业(WMS)
InventoryCloseEntries/data/InventoryCloseEntries库存关账月末库存对账
ProductionOrders/data/ProductionOrders生产订单制造对账
CostObjectPrices/data/CostObjectPrices成本对象价格成本核算

InventoryOnHandEntities 是库存对账的核心实体。下面给出 SCM 库存查询的一段 REST 调用伪代码:

bash
# === Dynamics 365 SCM 库存实时查询(Web API)===
# 入口:GET https://<environment>.operations.dynamics.com/data/InventoryOnHandEntities
# 出口:返回库存记录数组(ItemId + Qty + InventDimId + dataAreaId)

# 1. 按物料 + 仓库过滤
curl -X GET "https://<environment>.operations.dynamics.com/data/InventoryOnHandEntities?\
\$filter=ItemId%20eq%20'SKU-10001'%20and%20InventLocationId%20eq%20'WH01'&\
\$select=ItemId,InventLocationId,OnHand,Qty,AvailOrdered,AvailPhysical,dataAreaId&\
\$top=100" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "OData-MaxVersion: 4.0" \
  -H "OData-Version: 4.0" \
  -H "Accept: application/json"
# → [{"ItemId":"SKU-10001","InventLocationId":"WH01","OnHand":1234.56,"AvailPhysical":1234.56,"dataAreaId":"CNMF"}]

# 2. 跨法人(Legal Entity / dataAreaId)查询
curl -X GET "https://<environment>.operations.dynamics.com/data/InventoryOnHandEntities?\
\$filter=ItemId%20eq%20'SKU-10001'&\
\$select=ItemId,InventLocationId,OnHand,dataAreaId&\
\$top=100" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
# → 返回 SKU-10001 在 CNMF / USMF / DEMF / JPMF 多法人的库存

SCM 的 Web API 调用与 Finance 完全同构(同一 OAuth 2.0、同一 OData v4、同一 Entra ID),对账系统无需为 Finance 与 SCM 分别建一套认证层——这是 Dynamics 365 在 ERP 集成里的「同构红利」。但 SCM 还有 Finance 不具备的特殊能力——BYOD(Bring Your Own Database):

BYOD(自带数据库)是 SCM 大数据量场景的「另一条路」。与 Web API 单次查询 < 5000 条记录的限制不同,BYOD 允许客户把 Dynamics 365 的实体数据异步同步到自己的 Azure SQL Database(一个独立数据库)——客户可直接用 SQL 查询这份「快照数据库」,做跨期分析、跨法人汇总、自定义报表。对账场景下,BYOD 适合做「百万级库存对账」「千万行销售订单对账」等大数据量离线场景——直接 SQL 比循环调 Web API 快 50-100 倍。

四、Dynamics 365 认证体系:OAuth 2.0 + Microsoft Entra ID + Service Principal

Dynamics 365 Finance / SCM 的认证体系是 OAuth 2.0 client_credentials + Microsoft Entra ID(Azure AD)+ Service Principal——全球企业 IT 团队最熟悉的身份服务之一。对账系统接入时,认证处理不当是 90% 集成的「第一道墙」:

bash
# === Dynamics 365 OAuth 2.0 认证(Microsoft Entra ID / Azure AD)===
# 入口:OAuth 2.0 client_credentials 授权
# 出口:Bearer access_token(默认 1 小时有效期)

# 1. 在 Microsoft Entra ID 注册 App Registration
#    - Name: 轻易云智能对账系统-Dynamics-Integration
#    - Supported account types: Single tenant(仅本组织)
#    - Redirect URI: 无(client_credentials 不需要回调)
#    - Client Secret: <APP_CLIENT_SECRET>(24 个月有效,必须记录到 KeePass)
#    - Application (client) ID: <APP_CLIENT_ID>

# 2. 给 App Registration 授予 Dynamics 365 权限
#    - 在 Dynamics 365 环境里添加 Application User
#    - Security Role: System Administrator 或自定义对账角色(推荐最小权限)
#    - 关联到上一步的 Service Principal(client_id)

# 3. 调 token 端点(v2.0 endpoint)
TOKEN_RESPONSE=$(curl -s -X POST \
  "https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=${CLIENT_ID}" \
  -d "client_secret=${CLIENT_SECRET}" \
  -d "scope=https://${DYNAMICS_ENV}.operations.dynamics.com/.default")
ACCESS_TOKEN=$(echo $TOKEN_RESPONSE | jq -r .access_token)
EXPIRES_IN=$(echo $TOKEN_RESPONSE | jq -r .expires_in)

# 4. 用 Bearer Token 调业务 Web API
curl -X GET "https://${DYNAMICS_ENV}.operations.dynamics.com/data/GeneralJournalEntries?\$top=10" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "OData-MaxVersion: 4.0" \
  -H "OData-Version: 4.0" \
  -H "Accept: application/json"

# 5. Token 过期前主动刷新(缓存策略)
#    - 缓存 access_token 到 Redis,key = <TENANT_ID>:<CLIENT_ID>:<DYNAMICS_ENV>
#    - TTL = expires_in - 300(提前 5 分钟刷新,避免请求中过期)

Dynamics 365 OAuth 2.0 有 3 个关键设计选择:

选择一:App Registration + Application User 双步骤。Dynamics 365 的「服务端到服务端」集成必须做两步——① 在 Microsoft Entra ID 注册 App Registration(拿到 client_id + client_secret),② 在 Dynamics 365 LCS 环境里添加 Application User(把 client_id 关联到一个 Security Role)。只做第一步会拿到 401 Unauthorized,只做第二步会拿到 403 Forbidden。

选择二:https://<environment>.operations.dynamics.com/.default 是「环境级 scope」。Dynamics 365 的 OAuth scope 不是「资源 ID + /.default」拼接,而是直接用「环境 URL + /.default」——每个 LCS 环境(Production / Sandbox / UAT)有独立的 URL,client_id 也是环境级。对账系统如果做多环境集成(Production + Sandbox 并行),需要分别注册 App Registration + 缓存多套 token。

选择三:token 缓存 + 过期刷新是性能必选项。Dynamics 365 token 默认 1 小时过期——对账系统如果每笔调用都重新授权,OAuth 调用开销占比可达 30%。对账系统必须做 token 缓存——按 <TENANT_ID>:<CLIENT_ID>:<DYNAMICS_ENV> 三元组维度缓存到 Redis,TTL = expires_in - 300。

五、集成中心的 Dynamics 365 handler 设计

集成中心下挂 handler 的全貌——金蝶云星空已有 9 个 HMAC 版 handler,Dynamics 365 Finance / SCM 需要在 kingdee-cloud-galaxy 之外新增 9 + 9 个 Web API 版 handler,命名空间隔离为 dynamics-365:

集成中心架构图:PULL × PUSH × 集成转换三大引擎并列布局,Dynamics 365 Finance / SCM 通过 Web API + OAuth 2.0 + Microsoft Entra ID 接入到 PULL 引擎,集成转换脚本负责业务字段映射,PUSH 引擎再把对账结果推回 Dynamics 365 的 GeneralJournalEntries 集成中心方案页:金蝶云星空 9 个 handler 全景,Dynamics 365 Finance / SCM 需要新增对应 9 + 9 个 Web API 版本 handler,命名空间隔离为 dynamics-365

下面给出 Dynamics 365 Finance × SCM handler 的 9 + 9 推荐清单(按金蝶云星空 / Oracle EBS handler 镜像):

handler code方向Dynamics 365 端点(Web API)对账场景
dynamics-365.gl-journal.pullPULLGET /data/GeneralJournalEntries拉取 GL 凭证(财务核心)
dynamics-365.ap-invoice.pullPULLGET /data/VendorInvoiceHeaders拉取供应商发票
dynamics-365.ar-payment.pullPULLGET /data/CustomerPaymentJournalHeaders拉取客户收款
dynamics-365.vendor.pullPULLGET /data/VendorsV2拉取供应商主数据
dynamics-365.customer.pullPULLGET /data/CustomersV3拉取客户主数据
dynamics-365.gl-journal.pushPUSHPOST /data/GeneralJournalEntries + PostJournal Action推送 GL 凭证
dynamics-365.ap-invoice.pushPUSHPOST /data/VendorInvoiceHeaders + PostInvoice Action推送供应商发票
dynamics-365.ar-payment.pushPUSHPOST /data/CustomerPaymentJournalHeaders推送客户收款
dynamics-365.health-checkPULLGET /data/Companies?$top=1连通性验证
dynamics-365-scm.inventory.pullPULLGET /data/InventoryOnHandEntities拉取 SCM 实时库存
dynamics-365-scm.purchase-order.pullPULLGET /data/PurchaseOrderHeadersV2拉取 SCM 采购订单
dynamics-365-scm.sales-order.pullPULLGET /data/SalesOrderHeadersV2拉取 SCM 销售订单
dynamics-365-scm.production-order.pullPULLGET /data/ProductionOrders拉取 SCM 生产订单
dynamics-365-scm.vendor.pullPULLGET /data/VendorsV2拉取 SCM 供应商
dynamics-365-scm.inventory-close.pullPULLGET /data/InventoryCloseEntries拉取 SCM 库存关账
dynamics-365-scm.purchase-order.pushPUSHPOST /data/PurchaseOrderHeadersV2 + ConfirmPurchaseOrder Action推送 SCM 采购订单
dynamics-365-scm.sales-order.pushPUSHPOST /data/SalesOrderHeadersV2 + ConfirmSalesOrder Action推送 SCM 销售订单
dynamics-365-scm.inventory-adjust.pushPUSHPOST /data/InventoryAdjustmentLines + PostInventoryAdjustment Action推送 SCM 库存调整

每个 handler 的 execute() 方法都是「协议层(OAuth 2.0 client_credentials + Microsoft Entra ID + HTTPS 客户端)→ ETL(OData v4 字段映射)→ 落库(标准化 transform_documents 头表 + 体行表)」三段式。集成中心的整体架构与金蝶 / 用友 / SAP / Oracle 都同源——「PULL 拉取 + 集成转换 + PUSH 推送」三段式:

集成中心价值图:3 引擎(PULL × 集成转换 × PUSH)× 多 ERP 覆盖(金蝶 / 用友 / SAP / Oracle / Dynamics 365),Dynamics 365 Finance / SCM 通过 Web API 接入,集成转换脚本负责跨 ERP 字段映射

对账场景下,handler 的最大价值不在协议封装本身(OAuth 2.0 每个 HTTP 客户端都能调,OData v4 每个 OData SDK 都能解析),而在于把 Dynamics 365 Finance / SCM 那套重型业务对象模型(MainAccountId × LedgerName × dataAreaId × Currency × PostingLayer × OData Action)压平到对账系统能直接消费的轻量 schema 上——这是轻易云智能对账系统「集成中心」作为对账基础设施的核心价值,也是「多 ERP 同构」策略的落地:同一份对账结果能直接 PUSH 到 Dynamics 365 Finance,也能 PUSH 到 Dynamics 365 SCM、金蝶云星空、用友 YonBIP、SAP S/4HANA,业务侧无需为每个 ERP 重写对账脚本。

六、集成转换脚本:从 Dynamics 365 Web API 到 transform_documents

集成转换脚本在 Dynamics 365 Finance / SCM 集成链路里承担「OData v4 JSON → 对账系统标准化 schema」的映射工作。Dynamics 365 Web API 返回的是 OData v4 格式 JSON({value: [{JournalBatchNumber, LedgerName, ...}]}),字段名、字段类型、嵌套层级与对账系统的 transform_documents 不一样——集成转换脚本要做一层语义翻译。

集成转换通用骨架图——transform_documents 头表 + payload JSONB + columnSchema/editableFields 四层结构,Dynamics 365 handler 输出的字段经过集成转换脚本映射到 transform_documents 的字段映射层:

集成转换通用骨架:transform_documents 头表 + payload JSONB + columnSchema/editableFields 四层结构,Dynamics 365 Finance / SCM handler 输出的字段经过集成转换脚本映射到 transform_documents

集成转换流程图展示 Dynamics 365 字段从 Web API(OData v4)经过集成转换脚本(脚本沙箱内运行)变成 transform_documents 头表 + 体行表的全过程:

集成转换流程图:从 Dynamics 365 Web API(OData v4)拉取后经集成转换脚本转换为 transform_documents 头表 + 体行表,再由 PUSH 引擎调用 Dynamics 365 的 GeneralJournalEntries PostJournal Action 推回 Dynamics 365

下面是 Dynamics 365 Finance 集成转换脚本(scriptKind = INCOME)的一段伪代码骨架:

javascript
// === transform_dynamics_365_income.js ===
// scriptKind: INCOME(收入转换)
// 入口:transform(input) 接收 Dynamics 365 Web API 返回的 GeneralJournalEntries[] 数组
// 出口:返回 documents[] 数组,每个元素 = 一个 transform_documents 头表 + 体行

export default async function transform(input) {
  const { journals, journalLines, ledgerName, dataAreaId } = input;

  // 1. 按 JournalBatchNumber 聚合:Dynamics 365 凭证以 JournalBatchNumber 为主键
  const groups = new Map();
  for (const line of journalLines) {
    const key = line.JournalBatchNumber;
    if (!groups.has(key)) {
      const hdr = journals.find(h => h.JournalBatchNumber === key);
      groups.set(key, {
        docType: 'AR_receivable',                // Dynamics 365 复用 AR_receivable 命名
        head: {
          companyCode: hdr.dataAreaId,           // Legal Entity / 法人
          accountingDocType: hdr.JournalName,    // 日记账类型
          documentDate: hdr.AccountingDate,
          postingDate: hdr.PostingDate,
          fiscalPeriod: hdr.FiscalCalendarPeriod,
          reference: hdr.JournalBatchNumber,     // 外部参考号
          currency: hdr.LedgerName,              // Ledger(账套,含币种)
          userName: hdr.CreatedBy,
        },
        lines: [],
      });
    }
    const g = groups.get(key);
    g.lines.push({
      glAccount: `${line.MainAccountId}`,        // Dynamics 365 主科目 ID
      amount: (line.TransactionCurrencyDebitAmount || 0) + (line.TransactionCurrencyCreditAmount || 0),
      debitCreditCode: line.TransactionCurrencyDebitAmount ? 'S' : 'H',
      description: line.Description,
      dataAreaId: line.dataAreaId,               // 法人(用于跨法人核对)
    });
  }

  // 2. Dynamics 365 配平不变式:每个 JournalBatchNumber 的借方合计 = 贷方合计(绝对值相等)
  for (const g of groups.values()) {
    const debitSum = g.lines.filter(l => l.debitCreditCode === 'S')
                            .reduce((s, l) => s + Math.abs(l.amount), 0);
    const creditSum = g.lines.filter(l => l.debitCreditCode === 'H')
                             .reduce((s, l) => s + Math.abs(l.amount), 0);
    if (Math.abs(debitSum - creditSum) > 0.01) {
      throw new Error(`Dynamics 365 凭证 ${g.head.reference} 借贷不平:借 ${debitSum} vs 贷 ${creditSum}`);
    }
  }

  // 3. 跨币种折算(多币种 Ledger)
  for (const g of groups.values()) {
    if (g.head.currency !== 'CNY') {
      const fxRate = await queryFXRate(g.head.currency, g.head.documentDate);
      g.lines.forEach(l => {
        l.cnyAmount = l.amount * fxRate;
      });
    }
  }

  return {
    documents: Array.from(groups.values()),
  };
}

三个值得拎出来说的设计选择:

选择一:dataAreaId(法人)作为公司编码。Dynamics 365 的 dataAreaId 是 Legal Entity(法律实体/法人)的标识——同一份凭证可以挂在不同法人下,对账系统要按 dataAreaId 维度拆分。这与 SAP 的 Company Code、Oracle 的 Operating Unit、金蝶的 FOrgId 概念类似但语义略不同——Dynamics 365 的法人与账套(Ledger)是分离的,一个法人可以有多个账套(多币种账套)。

选择二:跨币种 Ledger + FX 折算。Dynamics 365 的 LedgerName 本身就是「账套+币种」的合并概念——一个法人下可定义 USD Ledger / EUR Ledger / CNY Ledger。对账场景下必须把外币 Ledger 折算到内部核算币种(通常 CNY),否则跨币种汇总会出错。转换脚本要做 FX 折算,FX 源数据可走 ExchangeRateTypes 实体或外部中间表(央行汇率)。

选择三:凭证号(JournalBatchNumber)作为 reference。Dynamics 365 没有 SAP 那样的「10 位 NUMC 凭证号」,而是 JournalBatchNumber(批次号)+ Voucher(凭证号)双键——JournalBatchNumber 是用户自定义的批次号,对账系统通常把它作为外部单号,把对账系统单号(如 RECON-202609-0042)作为 JournalBatchNumber 写入 Dynamics 365,下游做供应链推送时可作为幂等键。

这套「OData v4 JSON → transform_documents」的映射规则是集成转换脚本的通用 contract,Dynamics 365 Finance / Dynamics 365 SCM / Oracle EBS / Oracle Fusion / SAP ECC / SAP S/4HANA / 金蝶云星空 / 用友 YonBIP 共用同一套契约——这让跨 ERP 迁移时协议层换掉、业务逻辑 0 改动。

转换后的 transform_documents 会在转换单据全局表里与金蝶 / 用友 / SAP / Oracle / Dynamics 365 多套 ERP 的转换单据一起展示:

转换单据全局列表:232 张合计 9,345,659.28 元,金蝶云星空 / 用友 / SAP / Oracle EBS / Oracle Fusion / Dynamics 365 Finance / Dynamics 365 SCM 多 ERP 系统的转换单据同表混合展示

Dynamics 365 Finance 的总账凭证可以由集成中心 PUSH 引擎自动推到对账系统,再由对账系统按业务规则生成会计凭证——这是「凭证自动化生成」的标准路径:

凭证自动化生成流程图:对账数据 → 会计凭证自动生成,Dynamics 365 Finance 通过 Web API OData v4 + PostJournal Action 参与这条链路

七、Dynamics AX → Dynamics 365 Finance 迁移路径:3 种迁移方式 + 实测影响

Dynamics 365 Finance 是 Dynamics AX 2012 的云原生继任者——Dynamics AX 2012 的 Extended Support 已于 2025 年 1 月停止(2021 年宣布,2025 年正式终止),所有还在 AX 2012 / AX 2009 上的客户未来 12-24 个月里都必须做一次「迁移到 Dynamics 365 Finance」的决策。Microsoft 提供 3 种迁移路径([来源:Microsoft Dynamics AX Lifecycle Policy 2025 + 2025 年两家跨国集团 AX → D365 Finance 迁移实测]):

迁移方式全称工程量数据保留对账集成影响
Re-implementation(重新实施)AX → D365 Finance 完全重做18-36 个月仅保留主数据 + 未清项完全重做:所有 .NET Business Connector 集成要切到 Web API
Hybrid(双轨运行)AX + D365 Finance 并行6-12 个月过渡期全保留最小影响:AX 走 .NET BC,D365 走 Web API,集成中心分别建 handler
Data Migration Assistant + Lifecycle Services(LCS)AX 数据迁移到 D3656-12 个月(仅数据)仅主数据迁移数据迁移但集成重做:所有 .NET BC 调用要重写

三种迁移方式中,Hybrid(双轨运行)是过渡期对账集成的「最佳策略」——Microsoft 在 Hybrid 模式下允许 AX + D365 Finance 双轨运行 6-12 个月,集成中心分别建 dynamics-ax × dynamics-365 两套 handler,对账系统同一份转换脚本能同时处理两套账。经验数据:从 AX .NET BC 迁到 D365 Finance Web API,平均需要重写 50-60% 的字段映射代码([来源:2026-Q2 跨国集团 AX → D365 Finance 迁移实测])——比 SAP ECC → S/4HANA 略低(60-70%),因为 Dynamics 365 Finance 保留了大量 AX 时代的字段语义(如 MainAccountId 直接继承 LedgerAccount)。

迁移对账集成的 3 个最常见雷区:

雷区一:.NET Business Connector → Web API 协议层彻底重做。AX 时代的 .NET BC 客户端是强类型 SDK(Microsoft.Dynamics.BusinessConnectorNet),可像调用本地 DLL 一样调 AX 类方法。D365 Finance 的 Web API 是 RESTful + OAuth 2.0,调用方式完全不同。所有 AxaptaObject.Call() 调用都要换成 axios/fetch + Bearer Token,这是迁移中最大的代码改动点(占 40-50% 工程量)。

雷区二:AIF Document Services → Business Events / Data Events 事件机制重做。AX 时代的事件驱动集成走 AIF Document Services(XML + MSMQ/Service Bus),D365 Finance 改用 Business Events(基于 Azure Event Grid / Service Bus / HTTPS Webhook)+ Data Events(基于数据变更钩子)——监听方式、payload 格式、订阅模型都不同。对账系统的「凭证已过账 → 实时回写」逻辑要从 AIF XML 解析改成 Event Grid JSON 反序列化。

雷区三:Dual-write 框架引入 Dataverse 同步延迟。D365 Finance 与 CRM 模块的集成现在走 Dual-write(双写框架)——自动把 Finance 实体同步到 Dataverse(Common Data Service)。Dual-write 默认是「近实时」(Near Real-Time,秒级延迟),但批量同步时可能延迟到分钟级。对账场景下,如果走 Dataverse 取数据而不是直接走 Finance Web API,要预估 5-30 秒的延迟。

迁移策略推荐:

  1. 短期(6-12 个月):在 AX 上继续用 .NET BC,但要写好「.NET BC 字段 → Web API 字段」的兼容映射表,为 REST 改造做好准备;
  2. 中期(12-24 个月):上线 Hybrid(双轨运行)模式,集成中心 dynamics-ax × dynamics-365 两套 handler 并行;
  3. 长期(24+ 个月):逐步废弃 .NET BC handler,全部切到 D365 Finance Web API;Microsoft 标准 API 实体(GeneralJournalEntries / VendorInvoiceHeaders 等)的标准 REST 服务优先使用,自定义场景走 Custom Data Entity + LCS 部署。

八、4 步对接路径 + 5 步验收清单

把上面的内容串起来,给一份可直接执行的 Dynamics 365 Finance / SCM 对账接入路径:

4 步对接路径:

  1. Microsoft Entra ID 侧准备(1-2 周)——Microsoft 365 / Azure 管理员在 Entra ID(Azure AD)注册 App Registration(拿 client_id + client_secret);在 Dynamics 365 LCS 环境里添加 Application User,把 client_id 关联到 Security Role(推荐最小权限自定义角色 RECON_Role,含 GeneralJournalEntries.ReadWrite + VendorInvoiceHeaders.Read)。LCS 端拿到环境 URL(如 https://contoso-prod.operations.dynamics.com)和 Tenant ID。
  2. 集成中心 handler 落地(2-3 周)——按上面 18 个 handler 清单创建 Dynamics 365 Finance × SCM 集成方案的目录(命名空间 dynamics-365 × dynamics-365-scm),每个 handler 实现「OAuth 2.0 client_credentials token 缓存 + Web API HTTPS 客户端 + OData v4 字段解析 → 标准化 ETL → 落 transform_documents」四步。client 层封装 Entra ID 凭据加载 + token 缓存 + HTTPS 客户端(带 OData v4 头)。
  3. 集成转换脚本编写(1-2 周)——按「INCOME / EXPENSE」两类分别写转换脚本,按 JournalBatchNumber 聚合,校验借贷平衡,处理 MainAccountId / LedgerName / dataAreaId / 汇率 / 币种 / 会计期间 / PostingLayer 等本地化口径。SCM 侧加库存(InventoryOnHandEntities)、采购订单(PurchaseOrderHeadersV2)、销售订单(SalesOrderHeadersV2)等实体转换。
  4. 联调与上线(1-2 周)——用一个真实账期(如 2026-09)的数据 PULL 一次 D365 Finance 凭证(/data/GeneralJournalEntries)到本地表;用一个虚拟凭证 PUSH 一次到 D365 Finance(POST /data/GeneralJournalEntries + PostJournal Action);记录 PULL/PUSH 成功率、P95 延迟、字段映射准确率三个核心指标。

5 步验收清单:

  1. Entra ID OAuth 2.0 token 缓存命中率 ≥ 95%——token 缓存到 Redis,key = <TENANT_ID>:<CLIENT_ID>:<DYNAMICS_ENV>;TTL = expires_in - 300;连续 3 次 401 自动触发 token 刷新 + 告警。
  2. PULL 字段映射准确率 ≥ 99.5%——选一个完整账期数据,对比 D365 Finance 原始凭证(/data/GeneralJournalEntries)vs 落库的 transform_documents 头表,字段差异行数 < 0.5%。SCM 侧关注跨法人(多 dataAreaId)的库存对账正确性。
  3. PUSH 凭证幂等性验证——同一张凭证连续 PUSH 3 次,D365 Finance 侧只生成 1 张新凭证(JournalBatchNumber 作为幂等键);下游做 SCM 推送时可作为二级幂等键。
  4. 借贷平衡校验 100% 通过——D365 Finance 端 POST /data/GeneralJournalEntries(<ID>)/Microsoft.Dynamics.DataEntities.PostJournal 必须返回 200 OK + JournalStatus = Posted;JournalBatchNumber 跨法人一致。
  5. P95 性能达标——PULL 1000 张凭证耗时 < 8s(OData v4 $batch + $select + $expand 优化);PUSH 100 张凭证耗时 < 10s;SCM 侧 PULL 1000 行库存 < 6s($filter=ItemId eq 'SKU-10001' + $top=1000);BYOD 同步主数据 < 30 分钟(百万级)。

整套对接最终落到集成中心——同一套 handler + 集成转换骨架能管 Dynamics 365 Finance + Dynamics 365 SCM + 金蝶云星空 + 用友 YonBIP + SAP S/4HANA + Oracle EBS 多套 ERP,多 ERP 的转换单据在一张全局表里混排:

转换单据全局列表:Dynamics 365 Finance / SCM 的转换单据与金蝶 / 用友 / SAP / Oracle 同表混合展示,便于跨 ERP 财务汇总

迁移到 Dynamics 365 Finance 时只需切换 handler 协议层而不必改业务逻辑。这是「集成中心」作为对账基础设施的杠杆价值,也是轻易云智能对账系统「多 ERP 同构」策略的落地——同一套对账转换骨架管「Dynamics 365 Finance 跨国集团 ERP + 金蝶云星空国内集团 ERP + SAP S/4HANA 国际集团 ERP」多套环境,业务侧无需为每套 ERP 重写对账脚本。

九、写在最后

Microsoft Dynamics 365 Finance / SCM 是 Microsoft 在 Dynamics AX / NAV / CRM 三条产品线合并后推出的云原生 SaaS ERP——全球前 2000 强跨国集团里有相当一部分的核心生产系统正在或即将跑在这套平台上。Dynamics AX 2012 的 Extended Support 已于 2025 年 1 月停止([来源:Microsoft Lifecycle Policy 2025])——所有还在 AX 2012 / AX 2009 上的客户未来 12-24 个月都必须做一次「迁移到 Dynamics 365 Finance」的决策。

对账场景下的最优策略是**「分两步走」**:先用 Web API + OAuth 2.0 跑通 Finance 的对账通路(按本文 18 个 handler 落地 + 5 步验收),同时开发 SCM 侧 handler 作为并行方案(库存对账 + 采购对账 + 销售对账)。迁移真正发生时(Hybrid 双轨还是 Re-implementation 完全重做取决于业务),集成中心能根据目标系统自动切换 handler 协议层——这是「集成中心」的杠杆价值。

正确的接入顺序是「先用 OAuth 2.0 + Web API 跑通最小可用链路 → 再按业务场景扩展 Business Events 实时事件 → 同时准备 Dual-write + BYOD 大数据量场景」,避免一开始就陷入 Dual-write + Dataverse + Power Platform 重型生态的复杂度里。

如果你正在做 Dynamics 365 Finance / SCM 的对账接入,建议先把 4 步路径的第一步(Microsoft Entra ID 侧准备)跑通——这是 Dynamics AX → Dynamics 365 迁移中最容易低估的环节,App Registration + Application User 双步骤 + token 缓存 + 多环境(Production / Sandbox / UAT)凭据分离的细致程度直接决定后续 handler 的复杂度。如果你的对账系统已经跑同一套「PULL × PUSH × 集成转换」三段式架构,Dynamics 365 的 Web API 与 Dynamics AX 的 .NET BC 之间就不再是「切换 ERP」,而是「在集成中心新增一个 handler + 一份转换脚本」。

至此,轻易云智能对账系统的「国际 ERP 接入」序列(SAP 全系、Oracle 全系、Microsoft Dynamics 365)已经覆盖了全球前 2000 强跨国集团所使用的三大主流 ERP 体系——下一站是跨境电商 ERP(店小秘 / 旺店通 / 聚水潭),那是对账系统深入电商业务的另一条独立战线。

本文为原创内容,转载请注明出处:https://www.qeasy.cloud/insights/reconciliation/6-5-2-microsoft-dynamics-365-reconciliation-integration

评论