Kingdee Payment Application → DingTalk Supplier Monthly Settlement: A Single-Strategy Sync Tutorial
What This Strategy Solves
At one of our retail clients, the finance team handles supplier monthly settlement payments in Kingdee Cloud Cosmos. Internal review is done in Kingdee, but the boss and business leads must sign off in DingTalk OA. Every month, finance staff manually retyped document numbers, supplier names, and amounts into DingTalk — slow and error-prone.
We use the Qeasy Data Integration Platform to bridge this gap: approved payment applications in Kingdee are pulled incrementally by approval date, and DingTalk "Supplier Monthly Settlement Payment" approval instances are created automatically.
Data Flow and Field Mapping
Data flow: Kingdee Cloud Cosmos (CN_PAYAPPLY payment application) → Qeasy middleware (transform + code mapping) → DingTalk OA (topapi/processinstance/create process instance).
Key field mapping:
| Layer | Target field (DingTalk) | Source field (Kingdee) | Mapping type | Notes |
|---|---|---|---|---|
| Top | process_code | Constant PROC-22EDF4E6-5CC9-4712-B9A3-34AEAF37B8AC | CONSTANT | Unique process code for supplier monthly settlement |
| Top | originator_user_id | _findCollection on F_VAOJ_FQR | COLLECTION | name → DingTalk user_id |
| Top | dept_id | _findCollection, leader_in_dept[0].dept_id | COLLECTION | name → primary dept_id |
| Form | Document No. | FBillNo | DIRECT | Kingdee bill number |
| Form | Supplier | FCONTACTUNIT.fname | DIRECT | base data, take name |
| Form | Applied amount | FAPPLYAMOUNTFOR_H | DIRECT | header amount (local currency) |
| Form | Payable amount | FPAYAMOUNTFOR_H | DIRECT | header payable amount |
| Form | Application date | FDATE | DIRECT | business date |
| Form | Expected pay date | FEXPECTPAYDATE | DIRECT | expected payment date |
| Form | Settlement org | FSETTLEORGID.fname | DIRECT | base data, take name |
| Form | Pay org | FPAYORGID.fnumber | DIRECT | code |
| Form | Settlement currency | FSETTLECUR.Fnumber | DIRECT | code |
| Form | Bill type | FBILLTYPEID.fnumber | DIRECT | code |
| Form | Payee account name | FEACHCCOUNTNAME | DIRECT | receiver account name |
| Form | Payee bank | FEACHBANKNAME | DIRECT | receiver bank |
| Form | Payee account no. | FEACHBANKACCOUNT | DIRECT | receiver account number |
| Form | Remarks | FDescription / F_VAOJ_Remarks | DIRECT | entry or extended remarks |
Kingdee base data fields are object structures. Use .fname for names and .fnumber for codes — this is a Kingdee Cloud Cosmos convention newcomers often miss.
Configuring in Qeasy
In Qeasy, configure this strategy as a two-step source → target:
- Source (QUERY): Pick Kingdee Cloud Cosmos, use
executeBillQuery, FormId =CN_PAYAPPLY, FilterString =FApproveDate>='{{LAST_SYNC_TIME|dateTime}}'for incremental pull. - Target (EXECUTE): Pick DingTalk OA, use
topapi/processinstance/create, map the four top-level parameters per table, and buildform_component_valuesas a[{name, value}, ...]array via UI mapping or script.
Centralized code mapping is a common pattern among Qeasy customers: keep "name → user_id" and "name → dept_id" lookups in the hub (the "DingTalk Directory → Kingdee Employee" strategy), and this strategy only references them. When someone leaves or rotates, only the hub strategy needs refreshing.
Implementation Steps
Phase 1: Full trigger (first go-live)
- Manually trigger a full pull in Qeasy, temporarily setting FilterString to
FApproveDate>='2024-01-01'. Verify Kingdee returns complete fields and DingTalk approval instances are created normally. - After the full run, reset
LAST_SYNC_TIMEto the current time.
Phase 2: Incremental start
- Source crontab:
*/7 9-22 * * *(every 7 minutes from 9:00–22:00), covering the audit peak; idle at night to save resources. - Target crontab:
*/5 9-22 * * *(every 5 minutes). Slightly slower source keeps the target from piling up.
Phase 3: Steady-state
- After one week, verify DingTalk approval instances map 1:1 to Kingdee bills, with no duplicates or misses.
- Ship header first, then add line items (entry rows) in a later phase. This staged approach — one variable at a time — is how Qeasy customers usually de-risk rollouts.
Lessons Learned
- dept_id returns nothing, request fails: A typical mistake is forgetting that the originator may belong to the root department. DingTalk requires a department; root must be
-1. The safe pattern is fallback in the transform layer: whenleader_in_deptis empty, setdept_id = -1. - _findCollection matches multiple rows: DingTalk sometimes has duplicate names. Querying by
namereturns multiple rows, andoriginator_user_idbecomes an array — which fails. This trips people up. The safe pattern is to add a second condition (e.g., employee ID or last 4 digits of mobile) for an exact match. - Forgot
.fnameon Kingdee base data: WritingFSETTLEORGIDdirectly returns an object, not a string. In DingTalk forms it shows up as[object Object]. Remember:.fnamefor names,.fnumberfor codes. - Wrong incremental field: Some teams mistakenly use
FDATE(business date) as the incremental field, so January backfills get missed. Incremental must useFApproveDate(approval date) — business dates can be backdated; only approval date represents "just happened". - form_component_values control name typo: When DingTalk form controls are renamed but the integration side isn't updated, DingTalk returns "control does not exist". The safe pattern is to parameterize control names so only one place needs editing.
When This Applies — and When It Doesn't
Applies: Kingdee Cloud Cosmos as ERP, DingTalk as OA; approved bills need to flow into DingTalk for executive sign-off; monthly supplier settlement payments, travel reimbursement, payment applications.
Doesn't apply: Bi-directional sync (DingTalk approval result written back to Kingdee) — this strategy is one-way initiation only; for write-back, a separate strategy is needed. Also, unapproved Kingdee bills are skipped because the incremental filter uses FApproveDate.