Syncing DingTalk Payment Vouchers to Kingdee Cloud: A Single-Strategy Field Guide
What This Strategy Solves
A manufacturing company was running its expense approvals inside DingTalk, while the general ledger and accounts payable had to live in Kingdee Cloud. Finance staff ended up retyping voucher numbers, dates, counterparties, and amounts between the two systems every month — a recipe for month-end reconciliation chaos.
We used the Qeasy integration platform to build a single strategy, 'DingTalk Payment Voucher (Other Business Payments) V4.0', that pulls approved DingTalk instances and lands them in Kingdee's payment voucher list on a scheduled cadence. It is not a brute-force full sync, nor a one-off script — it is an observable, replayable, phased sync pipeline.
Data Flow and Field Mapping
The flow is DingTalk (source) → Qeasy middle layer → Kingdee Cloud (target), one-way B_TO_A.
On the source side, DingTalk's v1.0/yida/processes/instances query endpoint retrieves completed approval instances using processInstanceId as the key and title as the voucher-number anchor. On the target side, Kingdee's batchSave execution endpoint is used with id as the idempotency key.
Key field mapping:
| Business meaning | DingTalk field | Kingdee field | Handling |
|---|---|---|---|
| Voucher number | title | FBillNo | Direct mapping |
| Business date | Completion timestamp (ms) | FDATE | Function FROM_UNIXTIME(ts/1000,'%Y-%m-%d') |
| Voucher type | Form identifier | FBillTypeID | Constant FKDLX02_SYS (other business payments) |
| Currency | Form control | FCURRENCYID | Constant PRE001 (CNY) |
| Counterparty type | Form control | FCONTACTUNITTYPE | Option-set id mapping selectField_*.id |
| Counterparty code | Form value | FCONTACTUNIT | Lookup via code mapping table |
In practice, we centralize code mapping, option-set id parsing, and date functions inside Qeasy's data transformation layer so that changes are made once, not scattered across strategies.
How to Configure It on Qeasy
In Qeasy, create a new integration strategy. Pick DingTalk as the source platform and Kingdee Cloud as the target. Tag the business module as 'Finance Sync'.
- Source configuration: Pick a YiDa form-instance query action. Set pagination with
pageSize=50andpageNumberstarting at 1. Use DingTalk app-level credentials:appType,systemToken, anduserId. ThesystemTokenmust be stored in Qeasy's credential vault — never inline it in the strategy. - Target configuration: Pick Kingdee's
batchSaveaction. Fill organization, currency, and voucher type as constants. Map header fields directly, and expand subforms for payment detail lines. - Transformation layer: Convert the timestamp with the time function. Resolve counterparty codes through the mapping table (Qeasy's 'Code Mapping' node is the right place to manage them centrally). Enable
idCheck=truefor idempotency so reruns do not duplicate postings. - Credentials and runtime: All tokens and app secrets are injected through Qeasy's credential management. Once connectivity passes testing, attach a schedule.
Implementation Steps
- Incremental anchor: Use the strategy go-live timestamp as the starting point. Pull only DingTalk instances whose completion time is ≥ that timestamp. Do not backfill historical data in the live pipeline.
- Full backfill (optional): If the client wants the last three months of historical vouchers in Kingdee as well, run a separate one-shot backfill task and shut it down afterward. Keep it isolated from the incremental schedule.
- Scheduling cadence: The DingTalk side polls every 20 minutes (
*/20 * * * *), and the Kingdee side batches writes every 10 minutes (*/10 * * * *). Source is slow, target is fast — this decouples real-time approval from write pressure on Kingdee. It is a common pattern among Qeasy customers: phased header-and-body processing, dual-track incremental and full sync. - Observation window: For the first three days, review runtime logs and failure records daily. Manually repair or rerun failed instances. Then drop to weekly health checks.
- Exception handling: Qeasy ships with built-in retry and alerting. Occasional 429 throttling on DingTalk is handled by automatic backoff. Kingdee validation failures land in an error queue for manual triage.
Lessons Learned from the Field
- Forgetting to divide by 1000 on the timestamp. YiDa returns completion time in milliseconds. If you feed it directly into
FROM_UNIXTIME, you will land in some date in 1970 and Kingdee will reject the document. Always hardcode/ 1000inside the conversion function. - Mixing option-set ids with display values. DingTalk components give you option-set ids; Kingdee expects codes. Mapping the display value silently looks fine on day one but causes reconciliation drift by day three. The safe approach is to extract
selectField_xxx_idand resolve it via the code mapping table. - Hardcoding
systemTokeninside the strategy. The token shown in the source material is illustrative — but if any secret is pasted into the strategy JSON, it is at risk. Our hard rule: all secrets go into Qeasy's credential vault; the strategy only references variable names. - Inverting source and target cadences. If you poll Kingdee every 10 minutes and DingTalk every 20 minutes, Kingdee can write a batch before the DingTalk data has even arrived, leading to overwrites on rerun. The poll cadence on the source must be ≥ the source system's update granularity.
- Syncing in-flight approval instances. The DingTalk YiDa
instancesendpoint returns in-progress records by default. Without astatus='COMPLETED'filter, you will end up with a pile of draft-state vouchers in Kingdee after a week. Restrict the source query to completed instances only.
When to Use and When Not to
Use it when: deployments are private, approvals live in DingTalk YiDa, the ledger lives in Kingdee Cloud, daily voucher volume is 10–200, and the business expects posting immediately after approval without overnight manual entry.
Do not use it when: daily voucher volume is very small (< 5 per day) — an Excel exchange is cheaper — or when complex voucher templates and tax splits across multiple orgs are required. In that case, lean on Qeasy's voucher template engine with custom-function extensions instead of a single sync strategy.